still revamping...

This commit is contained in:
Ludwig Lehnert 2024-12-22 01:07:58 +01:00
parent f8c17803c3
commit e35ceeacf9
26 changed files with 284 additions and 33 deletions

View File

@ -79,6 +79,7 @@
"variant": "cpp",
"*.inc": "cpp",
"source_location": "cpp",
"text_encoding": "cpp"
"text_encoding": "cpp",
"stack": "cpp"
}
}

View File

@ -149,6 +149,23 @@ public:
};
};
class Type : public Jsonable {
public:
Type() : Jsonable() {}
virtual ~Type() = default;
static Type *fromJson(boost::json::value json);
};
class Symbol {
const std::string name;
std::shared_ptr<Type> type;
public:
Symbol(const std::string &name) : name(name) {}
Symbol(const std::string &name, Type *type) : name(name), type(type) {}
};
class ASTNode : public Jsonable {
public:
ASTNode(LOC_ARG) : Jsonable(), sourceRange(sourceRange) {}
@ -170,6 +187,8 @@ public:
};
class Expr : public ASTNode {
std::shared_ptr<Type> type;
public:
Expr(LOC_ARG) : ASTNode(sourceRange) {}
virtual ~Expr() = default;
@ -199,13 +218,5 @@ public:
virtual bool isTypeName() override { return true; }
};
class Type : public Jsonable {
public:
Type() : Jsonable() {}
virtual ~Type() = default;
static Type *fromJson(boost::json::value json);
};
} // namespace ast
} // namespace plsm

View File

@ -0,0 +1,148 @@
#pragma once
#include "AST/AST.h"
namespace plsm {
namespace ast {
class BaseASTVisitor : public ASTVisitor {
public:
BaseASTVisitor() : ASTVisitor() {};
virtual std::any visit(BinExpr &binExpr, std::any param) override {
binExpr.lhs->accept(this, param);
binExpr.rhs->accept(this, param);
return std::any();
}
virtual std::any visit(CallExpr &callExpr, std::any param) override {
callExpr.callee->accept(this, param);
for (auto &arg : callExpr.args) {
arg->accept(this, param);
}
return std::any();
}
virtual std::any visit(CastExpr &castExpr, std::any param) override {
castExpr.value->accept(this, param);
castExpr.typeName->accept(this, param);
return std::any();
}
virtual std::any visit(Identifier &identifier, std::any param) override {
return std::any();
}
virtual std::any visit(LambdaExpr &lambdaExpr, std::any param) override {
for (auto &param : lambdaExpr.params) {
param->accept(this, param);
}
for (auto &body : lambdaExpr.body) {
body->accept(this, param);
}
return std::any();
}
virtual std::any visit(UnExpr &unExpr, std::any param) override {
unExpr.expr->accept(this, param);
return std::any();
}
virtual std::any visit(IntValue &intValue, std::any param) override {
return std::any();
}
virtual std::any visit(FloatValue &floatValue, std::any param) override {
return std::any();
}
virtual std::any visit(Import &import, std::any param) override {
return std::any();
}
virtual std::any visit(Module &module, std::any param) override {
for (auto &import : module.imports) {
import->accept(this, param);
}
for (auto &stmt : module.stmts) {
stmt->accept(this, param);
}
return std::any();
}
virtual std::any visit(AssignStmt &assignStmt, std::any param) override {
assignStmt.lval->accept(this, param);
assignStmt.rval->accept(this, param);
return std::any();
}
virtual std::any visit(ExprStmt &exprStmt, std::any param) override {
exprStmt.expr->accept(this, param);
return std::any();
}
virtual std::any visit(FnParam &fnParam, std::any param) override {
fnParam.typeName->accept(this, param);
return std::any();
}
virtual std::any visit(FnDecl &fnDecl, std::any param) override {
for (auto &param : fnDecl.params) {
param->accept(this, param);
}
for (auto &body : fnDecl.body) {
body->accept(this, param);
}
return std::any();
}
virtual std::any visit(IfStmt &ifStmt, std::any param) override {
ifStmt.condition->accept(this, param);
for (auto &ifBody : ifStmt.ifBody) {
ifBody->accept(this, param);
}
for (auto &elseBody : ifStmt.elseBody) {
elseBody->accept(this, param);
}
return std::any();
}
virtual std::any visit(RetStmt &retStmt, std::any param) override {
retStmt.value->accept(this, param);
return std::any();
}
virtual std::any visit(VarDecl &varDecl, std::any param) override {
varDecl.typeName->accept(this, param);
return std::any();
}
virtual std::any visit(WhileStmt &whileStmt, std::any param) override {
whileStmt.condition->accept(this, param);
for (auto &body : whileStmt.body) {
body->accept(this, param);
}
return std::any();
}
virtual std::any visit(PrimitiveTypeName &primitiveTypeName,
std::any param) override {
return std::any();
}
};
} // namespace ast
} // namespace plsm

View File

@ -26,10 +26,10 @@ enum BinOp {
};
class BinExpr : public Expr {
public:
const BinOp op;
const std::shared_ptr<Expr> lhs, rhs;
public:
BinExpr(LOC_ARG, const BinOp op, Expr *lhs, Expr *rhs)
: Expr(sourceRange), op(op), lhs(lhs), rhs(rhs) {}

View File

@ -8,10 +8,10 @@ namespace plsm {
namespace ast {
class CallExpr : public Expr {
public:
const std::shared_ptr<Expr> callee;
std::vector<std::shared_ptr<Expr>> args;
public:
CallExpr(LOC_ARG, Expr *callee, std::vector<Expr *> args)
: Expr(sourceRange), callee(callee), args() {
for (auto &arg : args) {

View File

@ -7,10 +7,10 @@ namespace plsm {
namespace ast {
class CastExpr : public Expr {
public:
const std::shared_ptr<Expr> value;
const std::shared_ptr<TypeName> typeName;
public:
CastExpr(LOC_ARG, Expr *value, TypeName *typeName)
: Expr(sourceRange), value(value), typeName(typeName) {}

View File

@ -6,9 +6,11 @@
namespace plsm {
namespace ast {
class Identifier : public Expr {
public:
const std::string name;
public:
std::shared_ptr<Symbol> symbol;
Identifier(LOC_ARG, const std::string &name)
: Expr(sourceRange), name(name) {}

View File

@ -10,10 +10,10 @@ namespace ast {
class FnParam;
class LambdaExpr : public Expr {
public:
std::vector<std::shared_ptr<FnParam>> params;
std::vector<std::shared_ptr<Expr>> body;
public:
LambdaExpr(LOC_ARG, std::vector<FnParam *> params, std::vector<Expr *> body)
: Expr(sourceRange), params(), body() {
for (auto &param : params) {

View File

@ -13,10 +13,10 @@ enum UnOp {
};
class UnExpr : public Expr {
public:
const UnOp op;
const std::shared_ptr<Expr> expr;
public:
UnExpr(LOC_ARG, const UnOp op, Expr *expr)
: Expr(sourceRange), op(op), expr(expr) {}

View File

@ -16,9 +16,9 @@ namespace ast {
// };
class IntValue : public Expr {
public:
const std::int64_t value;
public:
IntValue(LOC_ARG, int64_t value) : Expr(sourceRange), value(value) {}
virtual boost::json::value toJson() override;
@ -30,9 +30,9 @@ public:
};
class FloatValue : public Expr {
public:
const std::double_t value;
public:
FloatValue(LOC_ARG, double value) : Expr(sourceRange), value(value) {}
virtual boost::json::value toJson() override;

View File

@ -6,9 +6,9 @@
namespace plsm {
namespace ast {
class Import : public ASTNode {
public:
const std::string moduleName;
public:
Import(LOC_ARG, const std::string &moduleName)
: ASTNode(sourceRange), moduleName(moduleName) {}

View File

@ -9,11 +9,11 @@ namespace ast {
class Import;
class Module : public ASTNode {
public:
const std::string name;
std::vector<std::shared_ptr<Import>> imports;
std::vector<std::shared_ptr<Stmt>> stmts;
public:
Module(LOC_ARG, const std::string &name, const std::vector<Import *> &imports,
const std::vector<Stmt *> &stmts)
: ASTNode(sourceRange), name(name), imports(), stmts() {

View File

@ -8,10 +8,10 @@ namespace plsm {
namespace ast {
class AssignStmt : public Stmt {
public:
const std::shared_ptr<Expr> lval;
const std::shared_ptr<Expr> rval;
public:
AssignStmt(LOC_ARG, Expr *lval, Expr *rval)
: Stmt(sourceRange), lval(lval), rval(rval) {}

View File

@ -6,9 +6,9 @@
namespace plsm {
namespace ast {
class ExprStmt : public Stmt {
public:
const std::shared_ptr<Expr> expr;
public:
ExprStmt(LOC_ARG, Expr *expr) : Stmt(sourceRange), expr(expr) {}
virtual boost::json::value toJson() override;

View File

@ -9,10 +9,12 @@ namespace plsm {
namespace ast {
class FnParam : public ASTNode {
public:
const std::string name;
const std::shared_ptr<TypeName> typeName;
public:
std::shared_ptr<Symbol> symbol;
FnParam(LOC_ARG, const std::string &name, TypeName *typeName)
: ASTNode(sourceRange), name(name), typeName(typeName) {}
@ -25,12 +27,14 @@ public:
};
class FnDecl : public Stmt {
public:
const std::string name;
std::vector<std::shared_ptr<FnParam>> params;
const std::shared_ptr<TypeName> returnTypeName;
std::vector<std::shared_ptr<Stmt>> body;
public:
std::shared_ptr<Symbol> symbol;
FnDecl(LOC_ARG, const std::string &name, const std::vector<FnParam *> &params,
TypeName *returnTypeName, const std::vector<Stmt *> &body)
: Stmt(sourceRange), name(name), params(), returnTypeName(returnTypeName),

View File

@ -8,10 +8,10 @@ namespace plsm {
namespace ast {
class IfStmt : public Stmt {
public:
const std::shared_ptr<Expr> condition;
std::vector<std::shared_ptr<Stmt>> ifBody, elseBody;
public:
IfStmt(LOC_ARG, Expr *condition, const std::vector<Stmt *> &ifBody,
const std::vector<Stmt *> &elseBody)
: Stmt(sourceRange), condition(condition) {

View File

@ -6,9 +6,9 @@
namespace plsm {
namespace ast {
class RetStmt : public Stmt {
public:
const std::shared_ptr<Expr> value;
public:
RetStmt(LOC_ARG, Expr *value) : Stmt(sourceRange), value(value) {}
virtual boost::json::value toJson() override;

View File

@ -8,10 +8,12 @@ namespace plsm {
namespace ast {
class VarDecl : public Stmt {
public:
const std::string name;
const std::shared_ptr<TypeName> typeName;
public:
std::shared_ptr<Symbol> symbol;
VarDecl(LOC_ARG, const std::string &name, TypeName *typeName)
: Stmt(sourceRange), name(name), typeName(typeName) {}

View File

@ -7,10 +7,10 @@
namespace plsm {
namespace ast {
class WhileStmt : public Stmt {
public:
const std::shared_ptr<Expr> condition;
std::vector<std::shared_ptr<Stmt>> body;
public:
WhileStmt(LOC_ARG, Expr *condition, const std::vector<Stmt *> &body)
: Stmt(sourceRange), condition(condition) {
for (auto &stmt : body) {

View File

@ -7,14 +7,14 @@
namespace plsm {
namespace ast {
class FunctionType : public Type {
std::vector<std::unique_ptr<Type>> paramTypes;
const std::unique_ptr<Type> returnType;
public:
std::vector<std::shared_ptr<Type>> paramTypes;
const std::shared_ptr<Type> returnType;
FunctionType(const std::vector<Type *> &paramTypes, Type *returnType)
: Type(), returnType(returnType) {
for (auto &paramType : paramTypes) {
this->paramTypes.push_back(std::unique_ptr<Type>(paramType));
this->paramTypes.push_back(std::shared_ptr<Type>(paramType));
}
}

View File

@ -6,9 +6,9 @@ namespace plsm {
namespace ast {
class PrimitiveType : public Type {
public:
const std::string name;
public:
PrimitiveType(const std::string &name) : Type(), name(name) {}
bool operator==(const PrimitiveType &other) { return name == other.name; }

View File

@ -6,9 +6,9 @@ namespace plsm {
namespace ast {
class PrimitiveTypeName : public TypeName {
public:
const std::string name;
public:
PrimitiveTypeName(LOC_ARG, const std::string &name)
: TypeName(sourceRange), name(name) {}

View File

@ -0,0 +1,9 @@
#pragma once
#include "AST/AST.h"
namespace plsm {
void performNameAnalysis(std::shared_ptr<ast::Module> module);
}

View File

@ -0,0 +1,69 @@
#include "AST/BaseASTVisitor.h"
#include "Analysis.h"
#include <map>
#include <stack>
namespace plsm {
namespace {
class NameAnalysisVisitor1 : public ast::BaseASTVisitor {
std::stack<std::map<std::string, std::shared_ptr<ast::Symbol>>> *scopes;
public:
NameAnalysisVisitor1(
std::stack<std::map<std::string, std::shared_ptr<ast::Symbol>>> *scopes)
: scopes(scopes) {}
virtual std::any visit(ast::FnDecl &fnDecl, std::any param) override {
auto symbol = std::make_shared<ast::Symbol>(fnDecl.name);
fnDecl.symbol = symbol;
scopes->top()[fnDecl.name] = symbol;
return std::any();
}
virtual std::any visit(ast::VarDecl &varDecl, std::any param) override {
auto symbol = std::make_shared<ast::Symbol>(varDecl.name);
varDecl.symbol = symbol;
scopes->top()[varDecl.name] = symbol;
return std::any();
}
};
class NameAnalysisVisitor2 : public ast::BaseASTVisitor {
std::stack<std::map<std::string, std::shared_ptr<ast::Symbol>>> *scopes;
void push() {
scopes->push(std::map<std::string, std::shared_ptr<ast::Symbol>>());
}
void pop() { scopes->pop(); }
public:
NameAnalysisVisitor2(
std::stack<std::map<std::string, std::shared_ptr<ast::Symbol>>> *scopes)
: scopes(scopes) {}
};
} // namespace
void performNameAnalysis(std::shared_ptr<ast::Module> module) {
std::stack<std::map<std::string, std::shared_ptr<ast::Symbol>>> scopes;
scopes.push(std::map<std::string, std::shared_ptr<ast::Symbol>>());
NameAnalysisVisitor1 visitor1(&scopes);
NameAnalysisVisitor2 visitor2(&scopes);
for (auto &stmt : module->stmts) {
stmt->accept(&visitor1, nullptr);
}
for (auto &stmt : module->stmts) {
stmt->accept(&visitor2, nullptr);
}
}
} // namespace plsm

View File

@ -5,6 +5,7 @@
#include "plsmLexer.h"
#include "plsmParser.h"
namespace {
class MyAntlr4ErrorListener : public antlr4::BaseErrorListener {
std::string file;
std::string *error;
@ -22,6 +23,7 @@ public:
*error = ss.str();
}
};
} // namespace
namespace plsm {

View File

@ -3,6 +3,7 @@
#include <istream>
#include <sstream>
#include "Analysis.h"
#include "Parser.h"
static std::string readFile(const std::string &path) {
@ -28,6 +29,8 @@ int main(int argc, char *argv[]) {
auto module = plsm::parse(argv[1], input);
std::cout << module->toJsonString() << std::endl;
plsm::performNameAnalysis(module);
// std::cout << "\n\n";
// std::cout << plsm::ast::Module::fromJson(module->toJson())->toJson() <<