diff --git a/ast.h b/ast.h index 6cf22e89b..da9bee095 100644 --- a/ast.h +++ b/ast.h @@ -3,12 +3,60 @@ #include #include -typedef yytokentype token_type; - namespace ast{ +// Enumerations +enum ASSIGN_OP_T{ + ASSIGN, + INPLACE_MUL, INPLACE_DIV, INPLACE_MOD, + INPLACE_ADD, INPLACE_SUB, + INPLACE_LSHIFT, INPLACE_RSHIFT, + INPLACE_AND, INPLACE_XOR, + INPLACE_OR +}; + +enum BIN_OP_T{ + MUL, DIV, MOD, + ADD, SUB, + LEFT_SHIFT, RIGHT_SHIFT, + LT, GT, + LE, GE, + EQ, NE, + AND, XOR, OR, + LAND, LOR +}; + +enum UNARY_OP_T{ + INC, DEC, + PLUS, MINUS, + ADDR, DEREF, + COMPL, NOT +}; + +enum TYPE_T{ + VOID_T, + UINT8_T, UINT16_T, UINT32_T, UINT64_T, + INT8_T, INT16_T, INT32_T, INT64_T, + FLOAT32_T, FLOAT64_T +}; + +// AST class node { }; +struct token: public node{ + token(ASSIGN_OP_T value): assign_op(value){ } + token(BIN_OP_T value): bin_op(value){ } + token(UNARY_OP_T value): unary_op(value){ } + token(TYPE_T value): type(value){ } + + union { + ASSIGN_OP_T assign_op; + BIN_OP_T bin_op; + UNARY_OP_T unary_op; + TYPE_T type; + }; +}; + template class list: public node { public: @@ -26,55 +74,13 @@ node* append_ptr_list(node *result, node *in){ class binary_operator: public node{ public: - enum OP_T{ - MUL, DIV, REM, - ADD, SUB, - LEFT_SHIFT, RIGHT_SHIFT, - LT, GT, - LE, GE, - EQ, NE, - AND, XOR, OR, - LAND, LOR - }; - - static OP_T get_op(token_type token){ - switch(token){ - case LEFT_OP: return LEFT_SHIFT; - case RIGHT_OP: return RIGHT_SHIFT; - case LE_OP: return LE; - case GE_OP: return GE; - case EQ_OP: return EQ; - case NE_OP: return NE; - case AND_OP: return LAND; - case OR_OP: return LOR; - default: assert(false && "unreachable"); throw; - } - } - - static OP_T get_op(char token){ - switch(token){ - case '*': return MUL; - case '/': return DIV; - case '%': return REM; - case '+': return ADD; - case '-': return SUB; - case '<': return LT; - case '>': return GT; - case '&': return AND; - case '^': return XOR; - case '|': return OR; - default: assert(false && "unreachable"); throw; - } - } - -public: - binary_operator(token_type op, node *lhs, node *rhs) - : op_(get_op(op)), lhs_(lhs), rhs_(rhs) { } - binary_operator(char op, node *lhs, node *rhs) - : op_(get_op(op)), lhs_(lhs), rhs_(rhs){ } + binary_operator(node *op, node *lhs, node *rhs) + : op_(((token*)op)->bin_op), lhs_(lhs), rhs_(rhs) { } + binary_operator(BIN_OP_T op, node *lhs, node *rhs) + : op_(op), lhs_(lhs), rhs_(rhs) { } private: - const OP_T op_; + const BIN_OP_T op_; const node *lhs_; const node *rhs_; }; @@ -106,19 +112,22 @@ public: class unary_operator: public node{ public: - unary_operator(token_type token, node *arg): token_(token), arg_(arg) { } + unary_operator(node *op, node *arg) + : op_(((token*)op)->unary_op), arg_(arg) { } + unary_operator(UNARY_OP_T op, node *arg) + : op_(op), arg_(arg) { } private: - const token_type token_; + const UNARY_OP_T op_; const node *arg_; }; class cast_operator: public node{ public: - cast_operator(token_type type, node *arg): type_(type), arg_(arg) { } + cast_operator(node *type, node *arg): type_(type), arg_(arg) { } public: - const token_type type_; + const node *type_; const node *arg_; }; @@ -134,29 +143,45 @@ public: }; class assignment_expression: public node{ - typedef binary_operator::OP_T op_t; +public: + assignment_expression(node *lvalue, node *op, node *rvalue) + : lvalue_(lvalue), op_(((token*)op)->assign_op), rvalue_(rvalue) { } public: - assignment_expression(node *lvalue, token_type op, node *rvalue) - : lvalue_(lvalue), op_(binary_operator::get_op(op)), rvalue_(rvalue) { } - -public: - op_t op_; + ASSIGN_OP_T op_; const node *lvalue_; const node *rvalue_; }; -class compound_statement: public node{ -public: - compound_statement() : statements_() {} - compound_statement(node *stmt): statements_{stmt} {} - compound_statement* append(node *stmt) { statements_.push_back(stmt); return this; } +class statement: public node{ -private: - std::list statements_; }; -class selection_statement: public node{ +class declaration: public node{ +public: + declaration(node *spec, node *init) + : spec_(spec), init_(init) { } + +public: + const node *spec_; + const node *init_; +}; + + +class compound_statement: public statement{ + typedef list* declarations_t; + typedef list* statements_t; + +public: + compound_statement(node* decls, node* statements) + : decls_((declarations_t)decls), statements_((statements_t)statements) {} + +private: + declarations_t decls_; + statements_t statements_; +}; + +class selection_statement: public statement{ public: selection_statement(node *cond, node *if_value, node *else_value = nullptr) : cond_(cond), if_value_(if_value), else_value_(else_value) { } @@ -167,7 +192,7 @@ public: const node *else_value_; }; -class iteration_statement: public node{ +class iteration_statement: public statement{ public: iteration_statement(node *init, node *stop, node *exec, node *statements) : init_(init), stop_(stop), exec_(exec), statements_(statements) { } @@ -179,7 +204,7 @@ private: const node *statements_; }; -class no_op: public node { }; +class no_op: public statement { }; // Types class declarator: public node{ @@ -211,11 +236,11 @@ public: class parameter: public declarator { public: - parameter(token_type type, node *decl) - : type_(type), decl_(decl) { } + parameter(node *spec, node *decl) + : spec_(((token*)spec)->type), decl_(decl) { } public: - const token_type type_; + const TYPE_T spec_; const node *decl_; }; @@ -248,23 +273,14 @@ public: const node *initializer_; }; -class declaration: public node{ -public: - declaration(node *spec, node *init) - : spec_(spec), init_(init) { } - -public: - const node *spec_; - const node *init_; -}; class type: public node{ public: - type(token_type spec, node * decl) - : spec_(spec), decl_(decl) { } + type(node *spec, node * decl) + : spec_(((token*)spec)->type), decl_(decl) { } public: - const token_type spec_; + const TYPE_T spec_; const node *decl_; }; diff --git a/main.cpp b/main.cpp index 5a01e7c68..f4a67ddb4 100644 --- a/main.cpp +++ b/main.cpp @@ -6,9 +6,18 @@ extern int yyparse(); extern YY_BUFFER_STATE yy_scan_string(const char * str); extern void yy_delete_buffer(YY_BUFFER_STATE buffer); +const char src[] = +"\ +void test(int32 id){\ + fp32 c[16, 16] = {0};\ + int32 i = 0;\ + i += 1;\ +}\ +"; + int main() { - char string[] = "void test(int);"; - YY_BUFFER_STATE buffer = yy_scan_string(string); + YY_BUFFER_STATE buffer = yy_scan_string(src); + yyparse(); yy_delete_buffer(buffer); return 0; } diff --git a/parser.y b/parser.y index 3501fba0f..3fbed1113 100644 --- a/parser.y +++ b/parser.y @@ -33,10 +33,17 @@ translation_unit *ast_root; /* -------------------------- */ type_specifier - : VOID - | UINT8 | UINT16 | UINT32 | UINT64 - | INT8 | INT16 | INT32 | INT64 - | FP32 | FP64 + : VOID { $$ = new token(VOID_T); } + | UINT8 { $$ = new token(UINT8_T); } + | UINT16 { $$ = new token(UINT16_T); } + | UINT32 { $$ = new token(UINT32_T); } + | UINT64 { $$ = new token(UINT64_T); } + | INT8 { $$ = new token(INT8_T); } + | INT16 { $$ = new token(INT16_T); } + | INT32 { $$ = new token(INT32_T); } + | INT64 { $$ = new token(INT64_T); } + | FP32 { $$ = new token(FLOAT32_T); } + | FP64 { $$ = new token(FLOAT64_T); } ; pointer @@ -62,8 +69,8 @@ constant_list ; type_name - : type_specifier { $$ = new type((yytokentype)(size_t)$1, nullptr); } - | type_specifier abstract_declarator { $$ = new type((yytokentype)(size_t)$1, $2); } + : type_specifier { $$ = new type($1, nullptr); } + | type_specifier abstract_declarator { $$ = new type($1, $2); } ; /* -------------------------- */ @@ -83,108 +90,113 @@ primary_expression unary_expression : primary_expression { $$ = $1; } - | INC_OP unary_expression { $$ = new unary_operator(INC_OP, $2); } - | DEC_OP unary_expression { $$ = new unary_operator(DEC_OP, $2); } - | unary_operator cast_expression { $$ = new unary_operator((yytokentype)(size_t)$1, $2); } + | INC_OP unary_expression { $$ = new unary_operator(INC, $2); } + | DEC_OP unary_expression { $$ = new unary_operator(DEC, $2); } + | unary_operator cast_expression { $$ = new unary_operator($1, $2); } ; unary_operator - : '&' - | '*' - | '+' - | '-' - | '~' - | '!' + : '&' { $$ = new token(ADDR); } + | '*' { $$ = new token(DEREF); } + | '+' { $$ = new token(PLUS); } + | '-' { $$ = new token(MINUS); } + | '~' { $$ = new token(COMPL); } + | '!' { $$ = new token(NOT); } ; cast_expression : unary_expression { $$ = $1; } - | '(' type_name ')' cast_expression { $$ = new cast_operator((yytokentype)(size_t)$1, $2); } + | '(' type_name ')' cast_expression { $$ = new cast_operator($1, $2); } ; multiplicative_expression : cast_expression { $$ = $1; } - | multiplicative_expression '*' cast_expression { $$ = new binary_operator('*', $1, $3); } - | multiplicative_expression '/' cast_expression { $$ = new binary_operator('/', $1, $3); } - | multiplicative_expression '%' cast_expression { $$ = new binary_operator('%', $1, $3); } + | multiplicative_expression '*' cast_expression { $$ = new binary_operator(MUL, $1, $3); } + | multiplicative_expression '/' cast_expression { $$ = new binary_operator(DIV, $1, $3); } + | multiplicative_expression '%' cast_expression { $$ = new binary_operator(MOD, $1, $3); } ; additive_expression : multiplicative_expression { $$ = $1; } - | additive_expression '+' multiplicative_expression { $$ = new binary_operator('+', $1, $3); } - | additive_expression '-' multiplicative_expression { $$ = new binary_operator('-', $1, $3); } + | additive_expression '+' multiplicative_expression { $$ = new binary_operator(ADD, $1, $3); } + | additive_expression '-' multiplicative_expression { $$ = new binary_operator(SUB, $1, $3); } ; shift_expression : additive_expression { $$ = $1; } - | shift_expression LEFT_OP additive_expression { $$ = new binary_operator(LEFT_OP, $1, $3); } - | shift_expression RIGHT_OP additive_expression { $$ = new binary_operator(RIGHT_OP, $1, $3); } + | shift_expression LEFT_OP additive_expression { $$ = new binary_operator(LEFT_SHIFT, $1, $3); } + | shift_expression RIGHT_OP additive_expression { $$ = new binary_operator(RIGHT_SHIFT, $1, $3); } ; +/* Comparison */ relational_expression : shift_expression { $$ = $1; } - | relational_expression '<' shift_expression { $$ = new binary_operator('<', $1, $3); } - | relational_expression '>' shift_expression { $$ = new binary_operator('>', $1, $3); } - | relational_expression LE_OP shift_expression { $$ = new binary_operator(LE_OP, $1, $3); } - | relational_expression GE_OP shift_expression { $$ = new binary_operator(GE_OP, $1, $3); } + | relational_expression '<' shift_expression { $$ = new binary_operator(LT, $1, $3); } + | relational_expression '>' shift_expression { $$ = new binary_operator(GT, $1, $3); } + | relational_expression LE_OP shift_expression { $$ = new binary_operator(LE, $1, $3); } + | relational_expression GE_OP shift_expression { $$ = new binary_operator(GE, $1, $3); } ; equality_expression : relational_expression { $$ = $1; } - | equality_expression EQ_OP relational_expression { $$ = new binary_operator(EQ_OP, $1, $3); } - | equality_expression NE_OP relational_expression { $$ = new binary_operator(NE_OP, $1, $3); } + | equality_expression EQ_OP relational_expression { $$ = new binary_operator(EQ, $1, $3); } + | equality_expression NE_OP relational_expression { $$ = new binary_operator(NE, $1, $3); } ; +/* Binary */ and_expression : equality_expression { $$ = $1; } - | and_expression '&' equality_expression { $$ = new binary_operator('&', $1, $3); } + | and_expression '&' equality_expression { $$ = new binary_operator(AND, $1, $3); } ; exclusive_or_expression : and_expression { $$ = $1; } - | exclusive_or_expression '^' and_expression { $$ = new binary_operator('^', $1, $3); } + | exclusive_or_expression '^' and_expression { $$ = new binary_operator(XOR, $1, $3); } ; inclusive_or_expression : exclusive_or_expression { $$ = $1; } - | inclusive_or_expression '|' exclusive_or_expression { $$ = new binary_operator('|', $1, $3); } + | inclusive_or_expression '|' exclusive_or_expression { $$ = new binary_operator(OR, $1, $3); } ; +/* Logical */ logical_and_expression : inclusive_or_expression { $$ = $1; } - | logical_and_expression AND_OP inclusive_or_expression { $$ = new binary_operator(AND_OP, $1, $3); } + | logical_and_expression AND_OP inclusive_or_expression { $$ = new binary_operator(LAND, $1, $3); } ; logical_or_expression : logical_and_expression { $$ = $1; } - | logical_or_expression OR_OP logical_and_expression { $$ = new binary_operator(OR_OP, $1, $3); } + | logical_or_expression OR_OP logical_and_expression { $$ = new binary_operator(LOR, $1, $3); } ; +/* Conditional */ conditional_expression : logical_or_expression { $$ = $1; } | logical_or_expression '?' conditional_expression ':' conditional_expression { $$ = new conditional_expression($1, $2, $3); } ; +/* Assignment */ assignment_operator - : '=' - | MUL_ASSIGN - | DIV_ASSIGN - | MOD_ASSIGN - | ADD_ASSIGN - | SUB_ASSIGN - | LEFT_ASSIGN - | RIGHT_ASSIGN - | AND_ASSIGN - | XOR_ASSIGN - | OR_ASSIGN + : '=' { $$ = new token(ASSIGN); } + | MUL_ASSIGN { $$ = new token(INPLACE_MUL); } + | DIV_ASSIGN { $$ = new token(INPLACE_DIV); } + | MOD_ASSIGN { $$ = new token(INPLACE_MOD); } + | ADD_ASSIGN { $$ = new token(INPLACE_ADD); } + | SUB_ASSIGN { $$ = new token(INPLACE_SUB); } + | LEFT_ASSIGN { $$ = new token(INPLACE_LSHIFT); } + | RIGHT_ASSIGN { $$ = new token(INPLACE_RSHIFT); } + | AND_ASSIGN { $$ = new token(INPLACE_AND); } + | XOR_ASSIGN { $$ = new token(INPLACE_XOR); } + | OR_ASSIGN { $$ = new token(INPLACE_OR); } ; - assignment_expression : conditional_expression { $$ = $1; } - | unary_expression assignment_operator assignment_expression { $$ = new assignment_expression($1, (yytokentype)(size_t)$2, $3); } + | unary_expression assignment_operator assignment_expression { $$ = new assignment_expression($1, $2, $3); } ; +/* Expression */ expression : assignment_expression { $$ = $1; } ; @@ -201,13 +213,20 @@ statement ; compound_statement - : '{' '}' { $$ = new compound_statement(); } - | '{' statement_list '}' { $$ = $1; } + : '{' '}' { $$ = new compound_statement(nullptr, nullptr); } + | '{' statement_list '}' { $$ = new compound_statement(nullptr, $1); } + | '{' declaration_list '}' { $$ = new compound_statement($1, nullptr); } + | '{' declaration_list statement_list '}' { $$ = new compound_statement($1, $2);} ; + +declaration_list + : declaration { $$ = new list((declaration*)$1); } + | declaration_list declaration { $$ = append_ptr_list($1, $2); } + statement_list - : statement { $$ = new compound_statement($1); } - | statement_list statement { $$ = append_ptr_list($1, $2); } + : statement { $$ = new list((statement*)$1); } + | statement_list statement { $$ = append_ptr_list($1, $2); } ; expression_statement @@ -232,11 +251,11 @@ iteration_statement direct_declarator - : identifier { $$ = $1; } - | direct_declarator '[' constant_list ']' { $$ = new tile_declarator($2); } - | direct_declarator '(' parameter_list ')' { $$ = new function_declarator($2); } - | direct_declarator '(' identifier_list ')' { $$ = new function_declarator($2); } - | direct_declarator '(' ')' { $$ = new function_declarator(nullptr); } + : identifier { $$ = $1; } + | direct_declarator '[' constant_list ']' { $$ = new tile_declarator($2); } + | direct_declarator '(' parameter_list ')' { $$ = new function_declarator($2); } + | direct_declarator '(' identifier_list ')' { $$ = new function_declarator($2); } + | direct_declarator '(' ')' { $$ = new function_declarator(nullptr); } ; identifier_list @@ -250,9 +269,9 @@ parameter_list ; parameter_declaration - : declaration_specifiers declarator { $$ = new parameter((yytokentype)(size_t)$1, $2); } - | declaration_specifiers abstract_declarator { $$ = new parameter((yytokentype)(size_t)$1, $2); } - | declaration_specifiers { $$ = new parameter((yytokentype)(size_t)$1, nullptr); } + : declaration_specifiers declarator { $$ = new parameter($1, $2); } + | declaration_specifiers abstract_declarator { $$ = new parameter($1, $2); } + | declaration_specifiers { $$ = new parameter($1, nullptr); } ; @@ -295,11 +314,12 @@ translation_unit ; external_declaration - : function_definition { $$ = $1; } - | declaration { $$ = $1; } - ; + : function_definition { $$ = $1; } + | declaration { $$ = $1; } + ; function_definition - : declarator compound_statement { $$ = new function_definition($1, $2); } + : declaration_specifiers declarator compound_statement + | declarator compound_statement { $$ = new function_definition($1, $2); } ;