From 266273963c1cffbdef1a50f23af70ae26670d0d2 Mon Sep 17 00:00:00 2001 From: Eatswap Date: Tue, 13 Dec 2022 15:21:09 +0800 Subject: [PATCH] add: complete AST generation --- AST.h | 27 ++++++++++ DragonLisp.y | 126 ++++++++++++++++++++++++++----------------- DragonLispDriver.cpp | 101 ++++++++++++++++++++++++++++++++++ DragonLispDriver.h | 57 ++++++++++++++++++-- 4 files changed, 257 insertions(+), 54 deletions(-) diff --git a/AST.h b/AST.h index 7ff0354..2bc1528 100644 --- a/AST.h +++ b/AST.h @@ -23,6 +23,7 @@ enum ASTType { T_VarOpAST, T_LValOpAST, T_ReturnAST, + T_LiteralAST, }; /// BaseAST - Base class for all AST nodes. @@ -90,6 +91,10 @@ public: inline ASTType getType() const override final { return T_FuncDefAST; } + + inline const std::string& getName() const { + return this->name; + } }; class FuncCallAST : public ExprAST { @@ -236,6 +241,28 @@ public: } }; +class LiteralAST : public ExprAST { +private: + std::shared_ptr val; + +public: + explicit LiteralAST(bool val) : val(std::make_shared(val)) {} + + explicit LiteralAST(std::int64_t val) : val(std::make_shared(val)) {} + + explicit LiteralAST(double val) : val(std::make_shared(val)) {} + + explicit LiteralAST(std::string val) : val(std::make_shared(std::move(val))) {} + + inline ASTType getType() const override final { + return T_LiteralAST; + } + + std::shared_ptr eval(Context* parent) override final { + return val->copy(); + } +}; + } #endif // __DRAGON_LISP_AST_H__ diff --git a/DragonLisp.y b/DragonLisp.y index 92fc121..b6d2f79 100644 --- a/DragonLisp.y +++ b/DragonLisp.y @@ -104,7 +104,33 @@ namespace DragonLisp { %type binary-tokens %type list-tokens -%type > R-Value +%type > L-Value +%type > array-ref +%type > func-def + +%type > R-Value +%type > S-Expr +%type > S-Expr-helper + +%type >> R-Value-list + +%type > identifier-list +%type > func-arg-list +%type >> func-body +%type > func-body-expr + +%type > return-expr +%type > S-Expr-binary +%type > S-Expr-unary +%type > S-Expr-list +%type > S-Expr-if +%type > S-Expr-var-op +%type > S-Expr-Lval-op +%type > S-Expr-loop +%type > S-Expr-func-call + + +%type , std::shared_ptr>> statement %define parse.error verbose @@ -118,72 +144,72 @@ S ; statements - : statement { std::printf("Parsed statements -> statement\n"); } - | statements statement { std::printf("Parsed statements -> statements statement\n"); } + : statement { std::printf("Parsed statements -> statement\n"); drv.execute($1); } + | statements statement { std::printf("Parsed statements -> statements statement\n"); drv.execute($2); } ; statement - : S-Expr { std::printf("Parsed statement -> S-Expr\n"); } - | func-def { std::printf("Parsed statement -> func-def\n"); } + : R-Value { std::printf("Parsed statement -> R-Value\n"); $$ = $1; } + | func-def { std::printf("Parsed statement -> func-def\n"); $$ = $1; } ; array-ref - : LPAREN AREF IDENTIFIER R-Value RPAREN { std::printf("Parsed array-ref -> ( AREF IDENTIFIER R-Value )\n"); } + : LPAREN AREF IDENTIFIER R-Value RPAREN { std::printf("Parsed array-ref -> ( AREF IDENTIFIER R-Value )\n"); $$ = drv.constructLValueAST($3, $4); } ; return-expr - : LPAREN RETURN R-Value RPAREN { std::printf("Parsed return-expr -> ( RETURN R-Value )\n"); } + : LPAREN RETURN R-Value RPAREN { std::printf("Parsed return-expr -> ( RETURN R-Value )\n"); $$ = drv.constructReturnAST($3); } ; func-body-expr - : return-expr { std::printf("Parsed func-body -> return-expr\n"); } - | R-Value { std::printf("Parsed func-body -> R-Value\n"); } + : return-expr { std::printf("Parsed func-body -> return-expr\n"); $$ = $1; } + | R-Value { std::printf("Parsed func-body -> R-Value\n"); $$ = $1; } ; func-body - : func-body-expr { std::printf("Parsed func-body -> func-body-expr\n"); } - | func-body func-body-expr { std::printf("Parsed func-body -> func-body func-body-expr\n"); } + : func-body-expr { std::printf("Parsed func-body -> func-body-expr\n"); $$ = { $1 }; } + | func-body func-body-expr { std::printf("Parsed func-body -> func-body func-body-expr\n"); $1.push_back($2); $$ = $1; } ; L-Value - : IDENTIFIER { std::printf("Parsed L-Value -> IDENTIFIER\n"); } - | array-ref { std::printf("Parsed L-Value -> array-ref\n"); } + : IDENTIFIER { std::printf("Parsed L-Value -> IDENTIFIER\n"); $$ = drv.constructLValueAST($1); } + | array-ref { std::printf("Parsed L-Value -> array-ref\n"); $$ = $1; } ; R-Value - : IDENTIFIER { std::printf("Parsed R-Value -> IDENTIFIER\n"); } - | S-Expr { std::printf("Parsed R-Value -> S-Expr\n"); } - | INTEGER { std::printf("Parsed R-Value -> INTEGER\n"); } - | FLOAT { std::printf("Parsed R-Value -> FLOAT\n"); } - | STRING { std::printf("Parsed R-Value -> STRING\n"); } - | array-ref { std::printf("Parsed R-Value -> array-ref\n"); } - | NIL { std::printf("Parsed R-Value -> NIL\n"); } - | T { std::printf("Parsed R-Value -> T\n"); } + : IDENTIFIER { std::printf("Parsed R-Value -> IDENTIFIER\n"); $$ = drv.constructLValueAST($1); } + | S-Expr { std::printf("Parsed R-Value -> S-Expr\n"); $$ = $1; } + | INTEGER { std::printf("Parsed R-Value -> INTEGER\n"); $$ = drv.constructLiteralAST($1); } + | FLOAT { std::printf("Parsed R-Value -> FLOAT\n"); $$ = drv.constructLiteralAST($1); } + | STRING { std::printf("Parsed R-Value -> STRING\n"); $$ = drv.constructLiteralAST($1); } + | array-ref { std::printf("Parsed R-Value -> array-ref\n"); $$ = $1; } + | NIL { std::printf("Parsed R-Value -> NIL\n"); $$ = drv.constructLiteralAST(false); } + | T { std::printf("Parsed R-Value -> T\n"); $$ = drv.constructLiteralAST(true); } ; R-Value-list - : R-Value { std::printf("Parsed R-Value-list -> R-Value\n"); } - | R-Value-list R-Value { std::printf("Parsed R-Value-list -> R-Value-list R-Value\n"); } + : R-Value { std::printf("Parsed R-Value-list -> R-Value\n"); $$ = { $1 }; } + | R-Value-list R-Value { std::printf("Parsed R-Value-list -> R-Value-list R-Value\n"); $1.push_back($2); $$ = $1; } ; S-Expr - : LPAREN S-Expr-helper RPAREN { std::printf("Parsed S-Expr -> ( S-Expr-helper )\n"); } - | LPAREN RPAREN { std::printf("Parsed S-Expr -> ()\n"); } + : LPAREN S-Expr-helper RPAREN { std::printf("Parsed S-Expr -> ( S-Expr-helper )\n"); $$ = $2; } + | LPAREN RPAREN { std::printf("Parsed S-Expr -> ()\n"); $$ = drv.constructLiteralAST(false); } ; S-Expr-helper - : S-Expr-var-op { std::printf("Parsed S-Expr-helper -> S-Expr-var-op\n"); } - | S-Expr-Lval-op { std::printf("Parsed S-Expr-helper -> S-Expr-Lval-op\n"); } - | S-Expr-unary { std::printf("Parsed S-Expr-helper -> S-Expr-unary\n"); } - | S-Expr-binary { std::printf("Parsed S-Expr-helper -> S-Expr-binary\n"); } - | S-Expr-list { std::printf("Parsed S-Expr-helper -> S-Expr-list\n"); } - | S-Expr-if { std::printf("Parsed S-Expr-helper -> S-Expr-if\n"); } - | S-Expr-loop { std::printf("Parsed S-Expr-helper -> S-Expr-loop\n"); } - | S-Expr-func-call { std::printf("Parsed S-Expr-helper -> S-Expr-func-call\n"); } + : S-Expr-var-op { std::printf("Parsed S-Expr-helper -> S-Expr-var-op\n"); $$ = $1; } + | S-Expr-Lval-op { std::printf("Parsed S-Expr-helper -> S-Expr-Lval-op\n"); $$ = $1; } + | S-Expr-unary { std::printf("Parsed S-Expr-helper -> S-Expr-unary\n"); $$ = $1; } + | S-Expr-binary { std::printf("Parsed S-Expr-helper -> S-Expr-binary\n"); $$ = $1; } + | S-Expr-list { std::printf("Parsed S-Expr-helper -> S-Expr-list\n"); $$ = $1; } + | S-Expr-if { std::printf("Parsed S-Expr-helper -> S-Expr-if\n"); $$ = $1; } + | S-Expr-loop { std::printf("Parsed S-Expr-helper -> S-Expr-loop\n"); $$ = $1; } + | S-Expr-func-call { std::printf("Parsed S-Expr-helper -> S-Expr-func-call\n"); $$ = $1; } ; S-Expr-var-op - : var-op-tokens IDENTIFIER R-Value { std::printf("Parsed S-Expr-var-op -> var-op-tokens IDENTIFIER R-Value\n"); } + : var-op-tokens IDENTIFIER R-Value { std::printf("Parsed S-Expr-var-op -> var-op-tokens IDENTIFIER R-Value\n"); $$ = drv.constructVarOpAST($2, $3, $1); } ; var-op-tokens @@ -192,7 +218,7 @@ var-op-tokens ; S-Expr-Lval-op - : lval-op-tokens L-Value R-Value { std::printf("Parsed S-Expr-Lval-op -> lval-op-tokens L-Value R-Value\n"); } + : lval-op-tokens L-Value R-Value { std::printf("Parsed S-Expr-Lval-op -> lval-op-tokens L-Value R-Value\n"); $$ = drv.constructLValOpAST($2, $3, $1); } ; lval-op-tokens @@ -202,7 +228,7 @@ lval-op-tokens ; S-Expr-unary - : unary-tokens R-Value { std::printf("Parsed S-Expr-unary -> unary-tokens R-Value\n"); } + : unary-tokens R-Value { std::printf("Parsed S-Expr-unary -> unary-tokens R-Value\n"); $$ = drv.constructUnaryExprAST($2, $1); } ; unary-tokens @@ -212,7 +238,7 @@ unary-tokens ; S-Expr-binary - : binary-tokens R-Value R-Value { std::printf("Parsed S-Expr-binary -> binary-tokens R-Value R-Value\n"); } + : binary-tokens R-Value R-Value { std::printf("Parsed S-Expr-binary -> binary-tokens R-Value R-Value\n"); $$ = drv.constructBinaryExprAST($2, $3, $1); } ; binary-tokens @@ -226,7 +252,7 @@ binary-tokens ; S-Expr-list - : list-tokens R-Value-list { std::printf("Parsed S-Expr-list -> list-tokens R-Value-list\n"); } + : list-tokens R-Value-list { std::printf("Parsed S-Expr-list -> list-tokens R-Value-list\n"); $$ = drv.constructListExprAST($2, $1); } ; list-tokens @@ -247,32 +273,32 @@ list-tokens ; S-Expr-if - : IF R-Value func-body-expr func-body-expr { std::printf("Parsed S-Expr-if -> IF R-Value func-body-expr func-body-expr\n"); } - | IF R-Value func-body-expr { std::printf("Parsed S-Expr-if -> IF R-Value func-body-expr\n"); } + : IF R-Value func-body-expr func-body-expr { std::printf("Parsed S-Expr-if -> IF R-Value func-body-expr func-body-expr\n"); $$ = drv.constructIfAST($2, $3, $4); } + | IF R-Value func-body-expr { std::printf("Parsed S-Expr-if -> IF R-Value func-body-expr\n"); $$ = drv.constructIfAST($2, $3, nullptr); } ; S-Expr-loop - : LOOP func-body { std::printf("Parsed S-Expr-loop -> LOOP func-body\n"); } - | LOOP FOR IDENTIFIER FROM R-Value TO R-Value DO func-body { std::printf("Parsed S-Expr-loop -> LOOP FOR IDENTIFIER FROM R-Value TO R-Value DO func-body\n"); } - | DOTIMES LPAREN IDENTIFIER R-Value RPAREN func-body { std::printf("Parsed S-Expr-loop -> DOTIMES LPAREN IDENTIFIER R-Value RPAREN func-body\n"); } + : LOOP func-body { std::printf("Parsed S-Expr-loop -> LOOP func-body\n"); $$ = drv.constructLoopAST($2); } + | LOOP FOR IDENTIFIER FROM R-Value TO R-Value DO func-body { std::printf("Parsed S-Expr-loop -> LOOP FOR IDENTIFIER FROM R-Value TO R-Value DO func-body\n"); $$ = drv.constructLoopAST($3, $5, $7, $9); } + | DOTIMES LPAREN IDENTIFIER R-Value RPAREN func-body { std::printf("Parsed S-Expr-loop -> DOTIMES LPAREN IDENTIFIER R-Value RPAREN func-body\n"); $$ = drv.constructLoopAST($3, $4, $6); } ; func-def - : LPAREN DEFUN IDENTIFIER func-arg-list func-body RPAREN { std::printf("Parsed func-def -> ( DEFUN IDENTIFIER func-arg-list func-body )\n"); } + : LPAREN DEFUN IDENTIFIER func-arg-list func-body RPAREN { std::printf("Parsed func-def -> ( DEFUN IDENTIFIER func-arg-list func-body )\n"); $$ = drv.constructFuncDefAST($3, $4, $5); } ; func-arg-list - : LPAREN RPAREN { std::printf("Parsed func-arg-list -> ( )\n"); } - | LPAREN identifier-list RPAREN { std::printf("Parsed func-arg-list -> ( identifier-list )\n"); } + : LPAREN RPAREN { std::printf("Parsed func-arg-list -> ( )\n"); $$ = {}; } + | LPAREN identifier-list RPAREN { std::printf("Parsed func-arg-list -> ( identifier-list )\n"); $$ = $2; } identifier-list - : identifier-list IDENTIFIER { std::printf("Parsed identifier-list -> identifier-list IDENTIFIER\n"); } - | IDENTIFIER { std::printf("Parsed identifier-list -> IDENTIFIER\n"); } + : identifier-list IDENTIFIER { std::printf("Parsed identifier-list -> identifier-list IDENTIFIER\n"); $1.push_back($2); $$ = $1; } + | IDENTIFIER { std::printf("Parsed identifier-list -> IDENTIFIER\n"); $$ = { $1 }; } ; S-Expr-func-call - : IDENTIFIER R-Value-list { std::printf("Parsed S-Expr-func-call -> IDENTIFIER R-Value-list\n"); } - | IDENTIFIER { std::printf("Parsed S-Expr-func-call -> IDENTIFIER\n"); } + : IDENTIFIER R-Value-list { std::printf("Parsed S-Expr-func-call -> IDENTIFIER R-Value-list\n"); $$ = drv.constructFuncCallAST($1, $2); } + | IDENTIFIER { std::printf("Parsed S-Expr-func-call -> IDENTIFIER\n"); $$ = drv.constructFuncCallAST($1, {}); } ; %% diff --git a/DragonLispDriver.cpp b/DragonLispDriver.cpp index 5b51fd4..6dc6d45 100644 --- a/DragonLispDriver.cpp +++ b/DragonLispDriver.cpp @@ -30,8 +30,109 @@ int DLDriver::parse(std::istream& in, const std::string& s) { delete this->parser; this->parser = new DLParser(*this->scanner, *this); + // Execution Context + delete this->context; + this->context = new Context(nullptr); + this->parser->set_debug_level(1); return this->parser->parse(); } +std::shared_ptr DLDriver::constructLValueAST(std::string name) { + return std::make_shared(std::move(name)); +} + +std::shared_ptr DLDriver::constructLValueAST(std::string name, std::shared_ptr index) { + return std::make_shared(std::move(name), std::move(index)); +} + +std::shared_ptr DLDriver::constructFuncDefAST(std::string name, std::vector args, std::vector> body) { + return std::make_shared(std::move(name), std::move(args), std::move(body)); +} + +std::shared_ptr DLDriver::constructLiteralAST(bool value) { + return std::make_shared(value); +} + +std::shared_ptr DLDriver::constructLiteralAST(std::int64_t value) { + return std::make_shared(value); +} + +std::shared_ptr DLDriver::constructLiteralAST(double value) { + return std::make_shared(value); +} + +std::shared_ptr DLDriver::constructLiteralAST(std::string value) { + return std::make_shared(std::move(value)); +} + +std::shared_ptr DLDriver::constructBinaryExprAST(std::shared_ptr lhs, std::shared_ptr rhs, Token op) { + return std::make_shared(std::move(lhs), std::move(rhs), op); +} + +std::shared_ptr DLDriver::constructUnaryExprAST(std::shared_ptr expr, Token op) { + return std::make_shared(std::move(expr), op); +} + +std::shared_ptr DLDriver::constructListExprAST(std::vector> exprs, Token op) { + return std::make_shared(std::move(exprs), op); +} + +std::shared_ptr DLDriver::constructIfAST(std::shared_ptr cond, std::shared_ptr then, std::shared_ptr els) { + return std::make_shared(std::move(cond), std::move(then), std::move(els)); +} + +std::shared_ptr DLDriver::constructFuncCallAST(std::string name, std::vector> args) { + return std::make_shared(std::move(name), std::move(args)); +} + +std::shared_ptr DLDriver::constructVarOpAST(std::string name, std::shared_ptr value, Token op) { + return std::make_shared(std::move(name), std::move(value), op); +} + +std::shared_ptr DLDriver::constructLValOpAST(std::shared_ptr lval, std::shared_ptr value, Token op) { + return std::make_shared(std::move(lval), std::move(value), op); +} + +std::shared_ptr DLDriver::constructReturnAST(std::shared_ptr value) { + return std::make_shared(std::move(value)); +} + +std::shared_ptr DLDriver::constructLoopAST(std::vector> body) { + return std::make_shared( + "", + std::make_shared(true), + std::make_shared(true), + std::move(body) + ); +} + +std::shared_ptr DLDriver::constructLoopAST(std::string id, std::shared_ptr to, std::vector> body) { + return std::make_shared( + std::move(id), + std::make_shared(std::int64_t(0)), + std::move(to), + std::move(body) + ); +} + +std::shared_ptr DLDriver::constructLoopAST(std::string id, std::shared_ptr from, std::shared_ptr to, std::vector> body) { + return std::make_shared( + std::move(id), + std::move(from), + std::move(to), + std::move(body) + ); +} + +void DLDriver::execute(std::variant , std::shared_ptr> ast) { + if (ast.index() == 0) { // ExprAST + auto expr = std::get<0>(ast); + expr->eval(this->context); + } else { // ast.index() == 1, FuncDefAST + auto func = std::get<1>(ast); + this->context->setFunc(func->getName(), func); + } +} + } // end namespace DragonLisp diff --git a/DragonLispDriver.h b/DragonLispDriver.h index 3332406..4d7e1f5 100644 --- a/DragonLispDriver.h +++ b/DragonLispDriver.h @@ -6,10 +6,18 @@ #include "DragonLispScanner.h" #include "DragonLisp.tab.hh" +#include "AST.h" namespace DragonLisp { class DLDriver { +private: + DLParser* parser = nullptr; + DLScanner* scanner = nullptr; + DragonLisp::location location; + + Context* context = nullptr; + public: DLDriver() = default; virtual ~DLDriver(); @@ -20,10 +28,51 @@ public: void error(const DLParser::location_type& l, const std::string& m); void error(const std::string& m); -private: - DLParser* parser = nullptr; - DLScanner* scanner = nullptr; - DragonLisp::location location; + void execute(std::variant, std::shared_ptr> ast); + + // Identifier AST + static std::shared_ptr constructLValueAST(std::string name); + + // ArrayRef AST + static std::shared_ptr constructLValueAST(std::string name, std::shared_ptr index); + + // FuncDef AST + static std::shared_ptr constructFuncDefAST(std::string name, std::vector args, std::vector> body); + + // Literal AST + static std::shared_ptr constructLiteralAST(bool value); + static std::shared_ptr constructLiteralAST(std::int64_t value); + static std::shared_ptr constructLiteralAST(double value); + static std::shared_ptr constructLiteralAST(std::string value); + + // BinaryExpr AST + static std::shared_ptr constructBinaryExprAST(std::shared_ptr lhs, std::shared_ptr rhs, Token op); + + // UnaryExpr AST + static std::shared_ptr constructUnaryExprAST(std::shared_ptr expr, Token op); + + // ListExpr AST + static std::shared_ptr constructListExprAST(std::vector> exprs, Token op); + + // If AST + static std::shared_ptr constructIfAST(std::shared_ptr cond, std::shared_ptr then, std::shared_ptr els); + + // Func Call AST + static std::shared_ptr constructFuncCallAST(std::string name, std::vector> args); + + // Var Op AST + static std::shared_ptr constructVarOpAST(std::string name, std::shared_ptr value, Token op); + + // LVal Op AST + static std::shared_ptr constructLValOpAST(std::shared_ptr lval, std::shared_ptr value, Token op); + + // Return AST + static std::shared_ptr constructReturnAST(std::shared_ptr value); + + // Loop AST + static std::shared_ptr constructLoopAST(std::vector> body); + static std::shared_ptr constructLoopAST(std::string id, std::shared_ptr from, std::shared_ptr to, std::vector> body); + static std::shared_ptr constructLoopAST(std::string id, std::shared_ptr to, std::vector> body); }; } // end namespace DragonLisp