From 8ead608e507f2fabae577b94ca2f3c9bfb20f6ca Mon Sep 17 00:00:00 2001 From: shenao78 Date: Fri, 23 Jul 2021 17:41:27 +0800 Subject: [PATCH 1/5] func call expr --- Makefile | 7 +- {src => compiler}/codegen.c | 0 {src => compiler}/compiler.c | 7 +- {src => compiler}/create.c | 82 ++++++-- {src => compiler}/grammar.y | 37 +++- {src => compiler}/lex.l | 2 +- {src => compiler}/summoner.h | 43 ++-- interpreter/eval.cpp | 378 +++++++++++++++++++++++++++++++++++ interpreter/eval.h | 100 +++++++++ interpreter/main.cpp | 27 +++ main/main.c | 2 +- src/interpreter.c | 225 --------------------- src/interpreter.h | 9 - 13 files changed, 626 insertions(+), 293 deletions(-) rename {src => compiler}/codegen.c (100%) rename {src => compiler}/compiler.c (82%) rename {src => compiler}/create.c (71%) rename {src => compiler}/grammar.y (82%) rename {src => compiler}/lex.l (95%) rename {src => compiler}/summoner.h (91%) create mode 100644 interpreter/eval.cpp create mode 100644 interpreter/eval.h create mode 100644 interpreter/main.cpp delete mode 100644 src/interpreter.c delete mode 100644 src/interpreter.h diff --git a/Makefile b/Makefile index ab12081..3b45a0f 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ comp: - lex src/lex.l - yacc -d src/grammar.y - gcc -o bin/main y.tab.c lex.yy.c src/create.c src/interpreter.c src/compiler.c src/codegen.c main/main.c + lex compiler/lex.l + yacc -d compiler/grammar.y + gcc -o bin/main y.tab.c lex.yy.c compiler/create.c compiler/compiler.c compiler/codegen.c main/main.c + \ No newline at end of file diff --git a/src/codegen.c b/compiler/codegen.c similarity index 100% rename from src/codegen.c rename to compiler/codegen.c diff --git a/src/compiler.c b/compiler/compiler.c similarity index 82% rename from src/compiler.c rename to compiler/compiler.c index 502733f..6f3277c 100644 --- a/src/compiler.c +++ b/compiler/compiler.c @@ -5,8 +5,8 @@ static Compiler *st_current_compiler; Compiler *create_compiler() { - Compiler *compiler = malloc(sizeof(Compiler)); - compiler->func_definition_list = malloc(sizeof(FuncDefinition)); + Compiler *compiler = (Compiler *)malloc(sizeof(Compiler)); + compiler->func_definition_list = (FuncDefinition *)malloc(sizeof(FuncDefinition)); return compiler; } @@ -23,7 +23,8 @@ void set_current_compiler(Compiler *compiler) void add_definitions_to_compiler(DefinitionList *definitions) { Compiler *compiler = get_current_compiler(); - for (DefinitionList *pos = definitions; pos != NULL; pos = pos->next) { + for (DefinitionList *pos = definitions; pos != NULL; pos = pos->next) + { switch (pos->definition->kind) { case FUNC_DEFINITION: diff --git a/src/create.c b/compiler/create.c similarity index 71% rename from src/create.c rename to compiler/create.c index 425eb26..7f38abc 100644 --- a/src/create.c +++ b/compiler/create.c @@ -4,7 +4,7 @@ Expression *alloc_expression(ExpressionKind kind) { - Expression *expr = malloc(sizeof(Expression)); + Expression *expr = (Expression *)malloc(sizeof(Expression)); expr->kind = kind; return expr; } @@ -47,16 +47,41 @@ Expression *alloc_unary_expression(ExpressionKind kind, Expression *unaryExpr) Expression *alloc_binary_expression(ExpressionKind kind, Expression *left, Expression *right) { Expression *expr = alloc_expression(kind); - BinaryExpression *binary = malloc(sizeof(BinaryExpression)); + BinaryExpression *binary = (BinaryExpression *)malloc(sizeof(BinaryExpression)); binary->left = left; binary->right = right; expr->u.binary_expression = binary; return expr; } +Expression *alloc_func_call_expression(char *identifier, ArgumentList *argument_list) +{ + Expression *expr = alloc_expression(FUNC_CALL_EXPRESSION); + FuncCallExpression *func_call_e = (FuncCallExpression *)malloc(sizeof(FuncCallExpression)); + func_call_e->identifier = identifier; + func_call_e->argument_list = argument_list; + expr->u.func_call_expression = func_call_e; + return expr; +} + +ArgumentList *chain_argument_list(ArgumentList *list, Expression *expr) +{ + ArgumentList *next = (ArgumentList *)malloc(sizeof(ArgumentList)); + next->expr = expr; + next->next = NULL; + + if (list == NULL) + { + return next; + } + + list->next = next; + return list; +} + Statement *alloc_statement(StatementKind kind) { - Statement *stmt = malloc(sizeof(Statement)); + Statement *stmt = (Statement *)malloc(sizeof(Statement)); stmt->kind = kind; return stmt; } @@ -64,7 +89,7 @@ Statement *alloc_statement(StatementKind kind) Statement *alloc_assign_statement(char *variable, Expression *operand) { Statement *stmt = alloc_statement(ASSIGN_STATEMENT); - AssignStatement *assign_s = malloc(sizeof(AssignStatement)); + AssignStatement *assign_s = (AssignStatement *)malloc(sizeof(AssignStatement)); stmt->u.assign_s = assign_s; return stmt; } @@ -72,7 +97,7 @@ Statement *alloc_assign_statement(char *variable, Expression *operand) Statement *alloc_if_statement(Expression *condition, Block *then_block, Elseif *elseif_list, Block *else_block) { Statement *stmt = alloc_statement(IF_STATEMENT); - IfStatement *if_s = malloc(sizeof(IfStatement)); + IfStatement *if_s = (IfStatement *)malloc(sizeof(IfStatement)); if_s->condition = condition; if_s->then_block = then_block; if_s->elseif_list = elseif_list; @@ -84,11 +109,23 @@ Statement *alloc_if_statement(Expression *condition, Block *then_block, Elseif * Statement *alloc_declaration_stmt(char *name, TypeSpecifier *type, Expression *initializer) { Statement *stmt = alloc_statement(DECLARATION_STATEMENT); - Declaration *decl_s = malloc(sizeof(Declaration)); + Declaration *decl_s = (Declaration *)malloc(sizeof(Declaration)); + decl_s->name = name; + decl_s->type = type; + decl_s->initializer = initializer; stmt->u.decl_s = decl_s; return stmt; } +Statement *alloc_return_stmt(Expression *expr) +{ + Statement *stmt = alloc_statement(RETURN_STATEMENT); + ReturnStatement *return_s = (ReturnStatement *)malloc(sizeof(ReturnStatement)); + return_s->return_value = expr; + stmt->u.return_s = return_s; + return stmt; +} + Statement *alloc_block_statement(Block *block) { Statement *stmt = alloc_statement(BLOCK_STATEMENT); @@ -96,31 +133,28 @@ Statement *alloc_block_statement(Block *block) return stmt; } -StatementList *alloc_statement_list(Statement *statement) +StatementList *chain_statement_list(StatementList *list, Statement *statement) { - StatementList *stmt_list = malloc(sizeof(StatementList)); + StatementList *stmt_list = (StatementList *)malloc(sizeof(StatementList)); stmt_list->statement = statement; - return stmt_list; -} + stmt_list->next = NULL; -StatementList *chain_statement_list(StatementList *list, Statement *statement) -{ if (list == NULL) { - return alloc_statement_list(statement); + return stmt_list; } StatementList *pos; for (pos = list; pos->next; pos = pos->next) ; - pos->next = alloc_statement_list(statement); + pos->next = stmt_list; return list; } Elseif *alloc_else_if(Expression *condition, Block *block) { - Elseif *elseif = malloc(sizeof(Elseif)); + Elseif *elseif = (Elseif *)malloc(sizeof(Elseif)); elseif->condition = condition; elseif->block = block; return elseif; @@ -161,14 +195,14 @@ Block *close_block(Block *block, StatementList *stmt_list) Block *alloc_block(StatementList *list) { - Block *block = malloc(sizeof(Block)); + Block *block = (Block *)malloc(sizeof(Block)); block->statement_list = list; return block; } TypeSpecifier *alloc_type_specifier(BasicType type, char *identifier) { - TypeSpecifier *type_s = malloc(sizeof(TypeSpecifier)); + TypeSpecifier *type_s = (TypeSpecifier *)malloc(sizeof(TypeSpecifier)); type_s->basic_type = type; type_s->identifier = identifier; return type_s; @@ -176,7 +210,7 @@ TypeSpecifier *alloc_type_specifier(BasicType type, char *identifier) ParameterList *alloc_parameter(TypeSpecifier *type, char *identifier) { - ParameterList *p = malloc(sizeof(ParameterList)); + ParameterList *p = (ParameterList *)malloc(sizeof(ParameterList)); p->name = identifier; p->type = type; p->next = NULL; @@ -198,14 +232,14 @@ ParameterList *chain_parameter(ParameterList *list, ParameterList *parameter) Definition *alloc_definition(DefinitionKind kind) { - Definition *definition = malloc(sizeof(Definition)); + Definition *definition = (Definition *)malloc(sizeof(Definition)); definition->kind = kind; return definition; } Definition *alloc_func_definition(char *name, ParameterList *parameters, TypeSpecifier *return_type, Block *block) { - FuncDefinition *func_d = malloc(sizeof(FuncDefinition)); + FuncDefinition *func_d = (FuncDefinition *)malloc(sizeof(FuncDefinition)); func_d->name = name; func_d->parameters = parameters; func_d->return_type = return_type; @@ -224,7 +258,11 @@ FuncDefinition *chain_func_definition_list(FuncDefinition *list, FuncDefinition return next; } - list->next = next; + FuncDefinition *pos; + for (pos = list; pos->next; pos = pos->next) + ; + + pos->next = next; return list; } @@ -237,7 +275,7 @@ Definition *alloc_declaration_definition(Statement *declaration_stmt) DefinitionList *alloc_definition_list(Definition *definition) { - DefinitionList *list = malloc(sizeof(DefinitionList)); + DefinitionList *list = (DefinitionList *)malloc(sizeof(DefinitionList)); list->definition = definition; list->next = NULL; return list; diff --git a/src/grammar.y b/compiler/grammar.y similarity index 82% rename from src/grammar.y rename to compiler/grammar.y index 8d12453..55bca99 100644 --- a/src/grammar.y +++ b/compiler/grammar.y @@ -1,8 +1,7 @@ %{ #include #include -#include "src/summoner.h" -#include "src/interpreter.h" +#include "compiler/summoner.h" int yylex(); int yyerror(const char *s); @@ -21,6 +20,7 @@ int yyerror(const char *s); struct ParameterList *parameter_list; struct Definition *definition; struct DefinitionList *definition_list; + struct ArgumentList *argument_list; } %token BOOL_LITERAL @@ -30,8 +30,8 @@ int yyerror(const char *s); %token VAR FUNCTION IF ELSE FOR RETURN BREAK CONTINUE NIL %token BOOL_T INT_T DOUBLE_T STRING_T -%type expr bool_expr -%type stmt if_stmt declaration_stmt variable_declaration +%type expr bool_expr func_call_expr +%type stmt if_stmt declaration_stmt return_stmt variable_declaration %type stmt_list %type block %type elseif elseif_list @@ -39,6 +39,7 @@ int yyerror(const char *s); %type parameter_list paramter %type definition func_definition %type definition_list +%type argument_list %nonassoc '=' DECL_ASSIGN %left AND OR @@ -70,7 +71,10 @@ definition: func_definition: FUNCTION IDENTIFIER '(' parameter_list ')' type_specifier block { $$ = alloc_func_definition($2, $4, $6, $7); } - ; + | FUNCTION IDENTIFIER '(' ')' type_specifier block { $$ = alloc_func_definition($2, NULL, $5, $6); } + | FUNCTION IDENTIFIER '(' parameter_list ')' block { $$ = alloc_func_definition($2, $4, NULL, $6); } + | FUNCTION IDENTIFIER '(' ')' block { $$ = alloc_func_definition($2, NULL, NULL, $5); } + ; parameter_list: paramter @@ -82,16 +86,16 @@ paramter: ; stmt_list: - stmt {$$ = alloc_statement_list($1); } + stmt {$$ = chain_statement_list(NULL, $1); } | stmt_list new_line stmt {$$ = chain_statement_list($1, $3); } ; stmt: - expr { printExprValue(evalExpression($1)); } - | IDENTIFIER '=' expr { $$ = alloc_assign_statement($1, $3); } + IDENTIFIER '=' expr { $$ = alloc_assign_statement($1, $3); } | block { $$ = alloc_block_statement($1); } | if_stmt | declaration_stmt + | return_stmt ; declaration_stmt: @@ -109,9 +113,13 @@ type_specifier: BOOL_T { $$ = alloc_type_specifier(BOOLEAN_TYPE, NULL); } | INT_T { $$ = alloc_type_specifier(INT_TYPE, NULL); } | DOUBLE_T { $$ = alloc_type_specifier(DOUBLE_TYPE, NULL); } - | STRING_T { $$ = alloc_type_specifier(STRING_T, NULL); } + | STRING_T { $$ = alloc_type_specifier(STRING_TYPE, NULL); } ; +return_stmt: + RETURN expr { $$ = alloc_return_stmt($2); } + ; + if_stmt: IF bool_expr block { $$ = alloc_if_statement($2, $3, NULL, NULL); } | IF bool_expr block ELSE block { $$ = alloc_if_statement($2, $3, NULL, $5); } @@ -153,6 +161,7 @@ expr: | '-' expr %prec MINUS { $$ = alloc_unary_expression(MINUS_EXPRESSION, $2); } | '(' expr ')' { $$ = $2; } | bool_expr + | func_call_expr ; bool_expr: @@ -167,6 +176,16 @@ bool_expr: | '!' expr %prec NOT { $$ = alloc_unary_expression(NOT_EXPRESSION, $2); } ; +func_call_expr: + IDENTIFIER '(' ')' { $$ = alloc_func_call_expression($1, NULL); } + | IDENTIFIER '(' argument_list ')' { $$ = alloc_func_call_expression($1, $3); } + ; + +argument_list: + expr { $$ = chain_argument_list(NULL, $1); } + | argument_list ',' expr { $$ = chain_argument_list($1, $3); } + ; + new_line: '\n' | new_line '\n' diff --git a/src/lex.l b/compiler/lex.l similarity index 95% rename from src/lex.l rename to compiler/lex.l index c6b482a..3b1bde7 100644 --- a/src/lex.l +++ b/compiler/lex.l @@ -51,7 +51,7 @@ } [A-Za-z_][A-Za-z_0-9]* { - char *new_str = malloc(strlen(yytext) + 1); + char *new_str = (char *)malloc(strlen(yytext) + 1); strcpy(new_str, yytext); yylval.identifier = new_str; return IDENTIFIER; diff --git a/src/summoner.h b/compiler/summoner.h similarity index 91% rename from src/summoner.h rename to compiler/summoner.h index aa7c160..090204a 100644 --- a/src/summoner.h +++ b/compiler/summoner.h @@ -4,31 +4,13 @@ #include #include -typedef enum -{ - EXPR_BOOL_VALUE = 1, - EXPR_INT_VALUE, - EXPR_DOUBLE_VALUE, -} ExprValueType; - -typedef struct ExprValue -{ - ExprValueType type; - union - { - bool boolean_value; - int int_value; - double double_value; - } u; - -} ExprValue; - typedef enum { BOOL_EXPRESSION = 1, INT_EXPRESSION, DOUBLE_EXPRESSION, IDENTIFIER_EXPRESSION, + FUNC_CALL_EXPRESSION, ADD_EXPRESSION, SUB_EXPRESSION, MUL_EXPRESSION, @@ -74,6 +56,7 @@ typedef struct Expression char *identifier; struct BinaryExpression *binary_expression; struct Expression *unary_expression; + struct FuncCallExpression *func_call_expression; } u; } Expression; @@ -84,6 +67,18 @@ typedef struct BinaryExpression Expression *right; } BinaryExpression; +typedef struct ArgumentList +{ + Expression *expr; + struct ArgumentList *next; +} ArgumentList; + +typedef struct FuncCallExpression +{ + char *identifier; + ArgumentList *argument_list; +} FuncCallExpression; + Expression *alloc_expression(ExpressionKind kind); Expression *alloc_int_expression(int value); Expression *alloc_double_expression(double value); @@ -91,6 +86,8 @@ Expression *alloc_bool_expression(bool value); Expression *alloc_identifier_expression(char *identifier); Expression *alloc_unary_expression(ExpressionKind kind, Expression *unaryExpr); Expression *alloc_binary_expression(ExpressionKind kind, Expression *left, Expression *right); +Expression *alloc_func_call_expression(char *identifier, ArgumentList *argument_list); +ArgumentList *chain_argument_list(ArgumentList *list, Expression *expr); typedef enum { @@ -127,6 +124,7 @@ typedef struct Statement struct Declaration *decl_s; struct Block *block_s; struct IfStatement *if_s; + struct ReturnStatement *return_s; } u; } Statement; @@ -157,12 +155,17 @@ typedef struct IfStatement Block *else_block; } IfStatement; +typedef struct ReturnStatement +{ + Expression *return_value; +} ReturnStatement; + Statement *alloc_statement(StatementKind kind); Statement *alloc_assign_statement(char *variable, Expression *operand); Statement *alloc_block_statement(Block *block); Statement *alloc_if_statement(Expression *condition, Block *then_block, Elseif *elseif_list, Block *else_block); Statement *alloc_declaration_stmt(char *name, TypeSpecifier *type, Expression *initializer); -StatementList *alloc_statement_list(Statement *statement); +Statement *alloc_return_stmt(Expression *expr); StatementList *chain_statement_list(StatementList *list, Statement *statement); Elseif *alloc_else_if(Expression *condition, Block *block); Elseif *chain_else_if_list(Elseif *list, Elseif *elseif); diff --git a/interpreter/eval.cpp b/interpreter/eval.cpp new file mode 100644 index 0000000..deb6003 --- /dev/null +++ b/interpreter/eval.cpp @@ -0,0 +1,378 @@ + +#include +#include +#include "eval.h" +#include + +ExprValue eval_int_binary_expression(ExpressionKind type, int left, int right) +{ + ExprValue v; + v.type = EXPR_INT_VALUE; + switch (type) + { + case ADD_EXPRESSION: + v.u.int_value = left + right; + break; + case SUB_EXPRESSION: + v.u.int_value = left - right; + break; + case MUL_EXPRESSION: + v.u.int_value = left * right; + break; + case DIV_EXPRESSION: + v.u.int_value = left / right; + break; + case LT_EXPRESSION: + v.type = EXPR_BOOL_VALUE; + v.u.boolean_value = left < right; + break; + case LE_EXPRESSION: + v.type = EXPR_BOOL_VALUE; + v.u.boolean_value = left <= right; + break; + case GT_EXPRESSION: + v.type = EXPR_BOOL_VALUE; + v.u.boolean_value = left > right; + break; + case GE_EXPRESSION: + v.type = EXPR_BOOL_VALUE; + v.u.boolean_value = left >= right; + break; + case EQ_EXPRESSION: + v.type = EXPR_BOOL_VALUE; + v.u.boolean_value = left == right; + break; + case NE_EXPRESSION: + v.type = EXPR_BOOL_VALUE; + v.u.boolean_value = left != right; + break; + default: + printf("invalid expression type\n"); + exit(1); + } + return v; +} + +ExprValue eval_double_binary_expression(ExpressionKind kind, double left, double right) +{ + ExprValue v; + v.type = EXPR_DOUBLE_VALUE; + switch (kind) + { + case ADD_EXPRESSION: + v.u.double_value = left + right; + break; + case SUB_EXPRESSION: + v.u.double_value = left - right; + break; + case MUL_EXPRESSION: + v.u.double_value = left * right; + break; + case DIV_EXPRESSION: + v.u.double_value = left / right; + break; + case LT_EXPRESSION: + v.type = EXPR_BOOL_VALUE; + v.u.boolean_value = left < right; + break; + case LE_EXPRESSION: + v.type = EXPR_BOOL_VALUE; + v.u.boolean_value = left <= right; + break; + case GT_EXPRESSION: + v.type = EXPR_BOOL_VALUE; + v.u.boolean_value = left > right; + break; + case GE_EXPRESSION: + v.type = EXPR_BOOL_VALUE; + v.u.boolean_value = left >= right; + break; + case EQ_EXPRESSION: + v.type = EXPR_BOOL_VALUE; + v.u.boolean_value = left == right; + break; + case NE_EXPRESSION: + v.type = EXPR_BOOL_VALUE; + v.u.boolean_value = left != right; + break; + default: + printf("invalid expression type\n"); + exit(1); + } + return v; +} + +ExprValue eval_bool_binary_expression(ExpressionKind type, bool left, bool right) +{ + ExprValue v; + v.type = EXPR_BOOL_VALUE; + switch (type) + { + case AND_EXPRESSION: + v.u.boolean_value = left && right; + break; + case OR_EXPRESSION: + v.u.boolean_value = left || right; + break; + default: + printf("invalid expression type when eval bool value:%d\n", type); + exit(1); + } + return v; +} + +ExprValue Interpreter::eval_binary_expression(ExpressionKind kind, BinaryExpression *binaryExpression) +{ + ExprValue leftVal = this->eval_expression(binaryExpression->left); + ExprValue rightVal = this->eval_expression(binaryExpression->right); + + if (leftVal.type == EXPR_INT_VALUE && rightVal.type == EXPR_INT_VALUE) + { + return eval_int_binary_expression(kind, leftVal.u.int_value, rightVal.u.int_value); + } + + if (leftVal.type == EXPR_INT_VALUE && rightVal.type == EXPR_DOUBLE_VALUE) + { + return eval_double_binary_expression(kind, leftVal.u.int_value, rightVal.u.double_value); + } + + if (leftVal.type == EXPR_DOUBLE_VALUE && rightVal.type == EXPR_INT_VALUE) + { + return eval_double_binary_expression(kind, leftVal.u.double_value, rightVal.u.int_value); + } + + if (leftVal.type == EXPR_DOUBLE_VALUE && rightVal.type == EXPR_DOUBLE_VALUE) + { + return eval_double_binary_expression(kind, leftVal.u.double_value, rightVal.u.double_value); + } + + if (leftVal.type == EXPR_BOOL_VALUE && rightVal.type == EXPR_BOOL_VALUE) + { + return eval_bool_binary_expression(kind, leftVal.u.boolean_value, rightVal.u.boolean_value); + } + + printf("invalid expression type, left:%d, right:%d", leftVal.type, rightVal.type); + exit(1); +} + +ExprValue Interpreter::eval_expression(Expression *expr) +{ + ExprValue v; + switch (expr->kind) + { + case BOOL_EXPRESSION: + v.type = EXPR_BOOL_VALUE; + v.u.boolean_value = expr->u.boolean_value; + return v; + case INT_EXPRESSION: + v.type = EXPR_INT_VALUE; + v.u.int_value = expr->u.int_value; + return v; + case DOUBLE_EXPRESSION: + v.type = EXPR_DOUBLE_VALUE; + v.u.double_value = expr->u.double_value; + return v; + case MINUS_EXPRESSION: + v = this->eval_expression(expr->u.unary_expression); + if (v.type == EXPR_INT_VALUE) + { + v.u.int_value = -v.u.int_value; + } + else + { + v.u.double_value = -v.u.double_value; + } + return v; + case NOT_EXPRESSION: + v = this->eval_expression(expr->u.unary_expression); + v.u.boolean_value = !v.u.boolean_value; + return v; + case ADD_EXPRESSION: + case SUB_EXPRESSION: + case MUL_EXPRESSION: + case DIV_EXPRESSION: + case LT_EXPRESSION: + case LE_EXPRESSION: + case GT_EXPRESSION: + case GE_EXPRESSION: + case EQ_EXPRESSION: + case NE_EXPRESSION: + case AND_EXPRESSION: + case OR_EXPRESSION: + return this->eval_binary_expression(expr->kind, expr->u.binary_expression); + case FUNC_CALL_EXPRESSION: + { + FuncCallExpression *func_call_expr = expr->u.func_call_expression; + FuncDefinition *func_d = this->find_func_definition(func_call_expr->identifier); + if (func_d == nullptr) + { + cout << "func \"" << func_call_expr->identifier << "\" is undefined" << endl; + exit(1); + } + return *(this->eval_func(func_d, func_call_expr->argument_list)); + } + case IDENTIFIER_EXPRESSION: + return this->current_scope->find_identifier(expr->u.identifier)->get_value(); + default: + printf("invalid expression type when eval expression:%d\n", expr->kind); + exit(1); + } +} + +void Interpreter::exec() +{ + FuncDefinition *func_d = this->find_func_definition("main"); + if (func_d == nullptr) + { + cout << "fail to find main func" << endl; + exit(1); + } + this->eval_func(func_d, nullptr); +} + +FuncDefinition *Interpreter::find_func_definition(const char *name) +{ + FuncDefinition *list = this->func_definition_list; + for (; list != nullptr; list = list->next) + { + if (!strcmp(list->name, name)) + { + return list; + } + } + return nullptr; +} + +ExprValue *Interpreter::eval_func(FuncDefinition *fd, ArgumentList *arg_list) +{ + ParameterList *params = fd->parameters; + vector identifiers; + for (; params != nullptr && arg_list != nullptr; arg_list = arg_list->next, params = params->next) + { + ExprValue arg_val = this->eval_expression(arg_list->expr); + identifiers.push_back(new Identifier(params->name, arg_val)); + } + + StmtResult result = this->eval_block(fd->block, identifiers); + if (result.type == RETURN_STATEMENT_RESULT) + { + return new ExprValue(result.u.return_value); + } + return nullptr; +} + +StmtResult Interpreter::eval_block(Block *block, vector identifiers) +{ + Scope *parent = this->current_scope; + Scope *scope = new Scope(parent); + this->current_scope = scope; + + for (size_t i = 0; i < identifiers.size(); i++) + { + scope->put_identifier(identifiers[i]); + } + + StmtResult result; + for (StatementList *stmt = block->statement_list; stmt != nullptr; stmt = stmt->next) + { + result = this->eval_stmt(stmt->statement); + if (result.type != NORMAL_STATEMENT_RESULT) + { + break; + } + } + + delete scope; + this->current_scope = parent; + return result; +} + +StmtResult Interpreter::eval_stmt(Statement *stmt) +{ + StmtResult result = {NORMAL_STATEMENT_RESULT}; + switch (stmt->kind) + { + case BLOCK_STATEMENT: + return this->eval_block(stmt->u.block_s, vector()); + case ASSIGN_STATEMENT: + { + AssignStatement *assign_s = stmt->u.assign_s; + Identifier *identifier = this->current_scope->find_identifier(assign_s->variable); + if (identifier == nullptr) + { + cout << "\"" << assign_s->variable << "\" is undefined" << endl; + exit(1); + } + + identifier->set_value(this->eval_expression(assign_s->operand)); + return result; + } + case IF_STATEMENT: + { + IfStatement *if_s = stmt->u.if_s; + bool cond = this->eval_expression(if_s->condition).u.boolean_value; + if (cond) + { + return this->eval_block(if_s->then_block, vector()); + } + else + { + for (Elseif *elseif = if_s->elseif_list; elseif != nullptr; elseif = elseif->next) + { + bool cond = this->eval_expression(elseif->condition).u.boolean_value; + if (cond) + { + return this->eval_block(elseif->block, vector()); + } + } + if (if_s->else_block != nullptr) + { + return this->eval_block(if_s->else_block, vector()); + } + } + return result; + } + case RETURN_STATEMENT: + { + ReturnStatement *return_s = stmt->u.return_s; + result.type = RETURN_STATEMENT_RESULT; + result.u.return_value = this->eval_expression(return_s->return_value); + return result; + } + case DECLARATION_STATEMENT: + { + Declaration *declaration = stmt->u.decl_s; + ExprValue init_value; + if (declaration->type != nullptr) + { + switch (declaration->type->basic_type) + { + case BOOLEAN_TYPE: + init_value.type = EXPR_BOOL_VALUE; + init_value.u.boolean_value = false; + break; + case INT_TYPE: + init_value.type = EXPR_INT_VALUE; + init_value.u.int_value = 0; + break; + case DOUBLE_TYPE: + init_value.type = EXPR_DOUBLE_VALUE; + init_value.u.double_value = 0.0; + break; + default: + break; + } + } + + if (declaration->initializer != nullptr) + { + init_value = this->eval_expression(declaration->initializer); + } + this->current_scope->put_identifier(new Identifier(declaration->name, init_value)); + return result; + } + default: + cout << "invalid statement kind:" << stmt->kind << endl; + exit(1); + } +} diff --git a/interpreter/eval.h b/interpreter/eval.h new file mode 100644 index 0000000..9ef0eff --- /dev/null +++ b/interpreter/eval.h @@ -0,0 +1,100 @@ +#ifndef _EVAL_H_ +#define _EVAL_H_ + +#include +#include +#include +#include "../compiler/summoner.h" + +using namespace std; + +typedef enum +{ + EXPR_BOOL_VALUE = 1, + EXPR_INT_VALUE, + EXPR_DOUBLE_VALUE, +} ExprValueType; + +typedef struct ExprValue +{ + ExprValueType type; + union + { + bool boolean_value; + int int_value; + double double_value; + } u; + +} ExprValue; + +typedef enum +{ + NORMAL_STATEMENT_RESULT = 1, + RETURN_STATEMENT_RESULT, +} StmtResultType; + +typedef struct StmtResult +{ + StmtResultType type; + union + { + ExprValue return_value; + } u; +} StmtResult; + +class Identifier +{ +public: + Identifier(string name, ExprValue value) : name(name), value(value) {} + void set_value(ExprValue value) { this->value = value; } + string get_name() { return this->name; } + ExprValue get_value() { return this->value; } + +private: + string name; + ExprValue value; +}; + +class Scope +{ +public: + Scope(Scope *parent_scope) : parent_scope(parent_scope) {} + + Identifier *find_identifier(char *name) + { + if (this->identifier_dict.find(name) != this->identifier_dict.end()) + { + return this->identifier_dict[name]; + } + if (this->parent_scope == nullptr) + { + return nullptr; + } + return this->parent_scope->find_identifier(name); + }; + void put_identifier(Identifier *identifier) { identifier_dict[identifier->get_name()] = identifier; } + +private: + map identifier_dict; + Scope *parent_scope; +}; + +class Interpreter +{ +public: + Interpreter(FuncDefinition *func_list) : func_definition_list(func_list), current_scope(nullptr){}; + void exec(); + +private: + Scope *current_scope; + FuncDefinition *func_definition_list; + + ExprValue *eval_func(FuncDefinition *fd, ArgumentList *arg_list); + FuncDefinition *find_func_definition(const char *name); + StmtResult eval_block(Block *block, vector identifiers); + StmtResult eval_stmt(Statement *stmt); + ExprValue eval_expression(Expression *expr); + ExprValue eval_binary_expression(ExpressionKind kind, BinaryExpression *expr); +}; + +#endif diff --git a/interpreter/main.cpp b/interpreter/main.cpp new file mode 100644 index 0000000..80512b4 --- /dev/null +++ b/interpreter/main.cpp @@ -0,0 +1,27 @@ +#include +#include "eval.h" +#include "../compiler/summoner.h" + +using namespace std; + +int main(int argc, char *argv[]) +{ + Compiler *compiler = new Compiler(); + set_current_compiler(compiler); + + extern int yyparse(); + extern FILE *yyin; + yyin = fopen(argv[1], "r"); + if (yyin == NULL) + { + cout << "fail to open file:" << argv[1] << endl; + } + else + { + yyparse(); + } + + Interpreter *interpreter = new Interpreter(compiler->func_definition_list); + interpreter->exec(); + return 0; +} \ No newline at end of file diff --git a/main/main.c b/main/main.c index a15d32c..597368c 100644 --- a/main/main.c +++ b/main/main.c @@ -1,6 +1,6 @@ #include #include -#include "../src/summoner.h" +#include "../compiler/summoner.h" int main(int argc, char *argv[]) { diff --git a/src/interpreter.c b/src/interpreter.c deleted file mode 100644 index 9ac2a93..0000000 --- a/src/interpreter.c +++ /dev/null @@ -1,225 +0,0 @@ - -#include -#include -#include "interpreter.h" -#include "summoner.h" - -ExprValue evalIntBinaryExpression(ExpressionKind type, int left, int right) -{ - ExprValue v; - v.type = EXPR_INT_VALUE; - switch (type) - { - case ADD_EXPRESSION: - v.u.int_value = left + right; - break; - case SUB_EXPRESSION: - v.u.int_value = left - right; - break; - case MUL_EXPRESSION: - v.u.int_value = left * right; - break; - case DIV_EXPRESSION: - v.u.int_value = left / right; - break; - case LT_EXPRESSION: - v.type = EXPR_BOOL_VALUE; - v.u.boolean_value = left < right; - break; - case LE_EXPRESSION: - v.type = EXPR_BOOL_VALUE; - v.u.boolean_value = left <= right; - break; - case GT_EXPRESSION: - v.type = EXPR_BOOL_VALUE; - v.u.boolean_value = left > right; - break; - case GE_EXPRESSION: - v.type = EXPR_BOOL_VALUE; - v.u.boolean_value = left >= right; - break; - case EQ_EXPRESSION: - v.type = EXPR_BOOL_VALUE; - v.u.boolean_value = left == right; - break; - case NE_EXPRESSION: - v.type = EXPR_BOOL_VALUE; - v.u.boolean_value = left != right; - break; - default: - printf("invalid expression type\n"); - exit(1); - } - return v; -} - -ExprValue evalDoubleBinaryExpression(ExpressionKind kind, double left, double right) -{ - ExprValue v; - v.type = EXPR_DOUBLE_VALUE; - switch (kind) - { - case ADD_EXPRESSION: - v.u.double_value = left + right; - break; - case SUB_EXPRESSION: - v.u.double_value = left - right; - break; - case MUL_EXPRESSION: - v.u.double_value = left * right; - break; - case DIV_EXPRESSION: - v.u.double_value = left / right; - break; - case LT_EXPRESSION: - v.type = EXPR_BOOL_VALUE; - v.u.boolean_value = left < right; - break; - case LE_EXPRESSION: - v.type = EXPR_BOOL_VALUE; - v.u.boolean_value = left <= right; - break; - case GT_EXPRESSION: - v.type = EXPR_BOOL_VALUE; - v.u.boolean_value = left > right; - break; - case GE_EXPRESSION: - v.type = EXPR_BOOL_VALUE; - v.u.boolean_value = left >= right; - break; - case EQ_EXPRESSION: - v.type = EXPR_BOOL_VALUE; - v.u.boolean_value = left == right; - break; - case NE_EXPRESSION: - v.type = EXPR_BOOL_VALUE; - v.u.boolean_value = left != right; - break; - default: - printf("invalid expression type\n"); - exit(1); - } - return v; -} - -ExprValue evalBoolBinaryExpression(ExpressionKind type, bool left, bool right) -{ - ExprValue v; - v.type = EXPR_BOOL_VALUE; - switch (type) - { - case AND_EXPRESSION: - v.u.boolean_value = left && right; - break; - case OR_EXPRESSION: - v.u.boolean_value = left || right; - break; - default: - printf("invalid expression type when eval bool value:%d\n", type); - exit(1); - } - return v; -} - -ExprValue evalBinaryExpression(ExpressionKind type, BinaryExpression *binaryExpression) -{ - ExprValue leftVal = evalExpression(binaryExpression->left); - ExprValue rightVal = evalExpression(binaryExpression->right); - if (leftVal.type == EXPR_INT_VALUE && rightVal.type == EXPR_INT_VALUE) - { - return evalIntBinaryExpression(type, leftVal.u.int_value, rightVal.u.int_value); - } - - if (leftVal.type == EXPR_INT_VALUE && rightVal.type == EXPR_DOUBLE_VALUE) - { - return evalDoubleBinaryExpression(type, leftVal.u.int_value, rightVal.u.double_value); - } - - if (leftVal.type == EXPR_DOUBLE_VALUE && rightVal.type == EXPR_INT_VALUE) - { - return evalDoubleBinaryExpression(type, leftVal.u.double_value, rightVal.u.int_value); - } - - if (leftVal.type == EXPR_DOUBLE_VALUE && rightVal.type == EXPR_DOUBLE_VALUE) - { - return evalDoubleBinaryExpression(type, leftVal.u.double_value, rightVal.u.double_value); - } - - if (leftVal.type == EXPR_BOOL_VALUE && rightVal.type == EXPR_BOOL_VALUE) - { - return evalBoolBinaryExpression(type, leftVal.u.boolean_value, rightVal.u.boolean_value); - } - - printf("invalid expression type, left:%d, right:%d", leftVal.type, rightVal.type); - exit(1); -} - -ExprValue evalExpression(Expression *expr) -{ - ExprValue v; - switch (expr->kind) - { - case BOOL_EXPRESSION: - v.type = EXPR_BOOL_VALUE; - v.u.boolean_value = expr->u.boolean_value; - return v; - case INT_EXPRESSION: - v.type = EXPR_INT_VALUE; - v.u.int_value = expr->u.int_value; - return v; - case DOUBLE_EXPRESSION: - v.type = EXPR_DOUBLE_VALUE; - v.u.double_value = expr->u.double_value; - return v; - case MINUS_EXPRESSION: - v = evalExpression(expr->u.unary_expression); - if (v.type == EXPR_INT_VALUE) - { - v.u.int_value = -v.u.int_value; - } - else - { - v.u.double_value = -v.u.double_value; - } - return v; - case NOT_EXPRESSION: - v = evalExpression(expr->u.unary_expression); - v.u.boolean_value = !v.u.boolean_value; - return v; - case ADD_EXPRESSION: - case SUB_EXPRESSION: - case MUL_EXPRESSION: - case DIV_EXPRESSION: - case LT_EXPRESSION: - case LE_EXPRESSION: - case GT_EXPRESSION: - case GE_EXPRESSION: - case EQ_EXPRESSION: - case NE_EXPRESSION: - case AND_EXPRESSION: - case OR_EXPRESSION: - return evalBinaryExpression(expr->kind, expr->u.binary_expression); - default: - printf("invalid expression type when eval expression:%d\n", expr->kind); - exit(1); - } -} - -void printExprValue(ExprValue val) -{ - switch (val.type) - { - case EXPR_INT_VALUE: - printf(">>>%d\n", val.u.int_value); - break; - case EXPR_DOUBLE_VALUE: - printf(">>>%lf\n", val.u.double_value); - break; - case EXPR_BOOL_VALUE: - printf(">>>%s\n", val.u.boolean_value ? "true" : "false"); - break; - default: - printf("invalid expression type when print expr value:%d", val.type); - exit(1); - } -} diff --git a/src/interpreter.h b/src/interpreter.h deleted file mode 100644 index db0d4be..0000000 --- a/src/interpreter.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _INTERPRETER_H_ -#define _INTERPRETER_H_ - -#include "summoner.h" - -ExprValue evalExpression(Expression *expr); -void printExprValue(ExprValue); - -#endif From f4e6142b57683fcd5ed6a8ef197fa76a4497573a Mon Sep 17 00:00:00 2001 From: shenao78 Date: Fri, 23 Jul 2021 17:42:29 +0800 Subject: [PATCH 2/5] add new line for makefile --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index 3b45a0f..fca8a95 100644 --- a/Makefile +++ b/Makefile @@ -2,4 +2,3 @@ comp: lex compiler/lex.l yacc -d compiler/grammar.y gcc -o bin/main y.tab.c lex.yy.c compiler/create.c compiler/compiler.c compiler/codegen.c main/main.c - \ No newline at end of file From dfee2c904e3b1d5fd5c179d766c849af7d89d83b Mon Sep 17 00:00:00 2001 From: shenao78 Date: Fri, 23 Jul 2021 17:51:48 +0800 Subject: [PATCH 3/5] bug fix --- compiler/create.c | 2 ++ interpreter/eval.cpp | 1 + 2 files changed, 3 insertions(+) diff --git a/compiler/create.c b/compiler/create.c index 7f38abc..4806f71 100644 --- a/compiler/create.c +++ b/compiler/create.c @@ -90,6 +90,8 @@ Statement *alloc_assign_statement(char *variable, Expression *operand) { Statement *stmt = alloc_statement(ASSIGN_STATEMENT); AssignStatement *assign_s = (AssignStatement *)malloc(sizeof(AssignStatement)); + assign_s->variable = variable; + assign_s->operand = operand; stmt->u.assign_s = assign_s; return stmt; } diff --git a/interpreter/eval.cpp b/interpreter/eval.cpp index deb6003..0aafdc6 100644 --- a/interpreter/eval.cpp +++ b/interpreter/eval.cpp @@ -325,6 +325,7 @@ StmtResult Interpreter::eval_stmt(Statement *stmt) return this->eval_block(elseif->block, vector()); } } + if (if_s->else_block != nullptr) { return this->eval_block(if_s->else_block, vector()); From bcc90d5a27d17066f78d0fd0dfd56334a4c88781 Mon Sep 17 00:00:00 2001 From: shenao78 Date: Fri, 23 Jul 2021 18:12:14 +0800 Subject: [PATCH 4/5] add expression stmt --- compiler/create.c | 11 ++++++++--- compiler/grammar.y | 1 + compiler/summoner.h | 8 +++----- interpreter/eval.cpp | 29 +++++++++++++++++++++++++++-- 4 files changed, 39 insertions(+), 10 deletions(-) diff --git a/compiler/create.c b/compiler/create.c index 4806f71..eae53ce 100644 --- a/compiler/create.c +++ b/compiler/create.c @@ -122,9 +122,14 @@ Statement *alloc_declaration_stmt(char *name, TypeSpecifier *type, Expression *i Statement *alloc_return_stmt(Expression *expr) { Statement *stmt = alloc_statement(RETURN_STATEMENT); - ReturnStatement *return_s = (ReturnStatement *)malloc(sizeof(ReturnStatement)); - return_s->return_value = expr; - stmt->u.return_s = return_s; + stmt->u.expr_s = expr; + return stmt; +} + +Statement* alloc_expression_stmt(Expression *expr) +{ + Statement *stmt = alloc_statement(EXPRESSION_STATEMENT); + stmt->u.expr_s = expr; return stmt; } diff --git a/compiler/grammar.y b/compiler/grammar.y index 55bca99..5a44f05 100644 --- a/compiler/grammar.y +++ b/compiler/grammar.y @@ -92,6 +92,7 @@ stmt_list: stmt: IDENTIFIER '=' expr { $$ = alloc_assign_statement($1, $3); } + | expr { $$ = alloc_expression_stmt($1); } | block { $$ = alloc_block_statement($1); } | if_stmt | declaration_stmt diff --git a/compiler/summoner.h b/compiler/summoner.h index 090204a..a03bf06 100644 --- a/compiler/summoner.h +++ b/compiler/summoner.h @@ -99,6 +99,7 @@ typedef enum BREAK_STATEMENT, CONTINUE_STATEMENT, DECLARATION_STATEMENT, + EXPRESSION_STATEMENT, } StatementKind; typedef struct Declaration @@ -125,6 +126,7 @@ typedef struct Statement struct Block *block_s; struct IfStatement *if_s; struct ReturnStatement *return_s; + struct Expression *expr_s; } u; } Statement; @@ -155,17 +157,13 @@ typedef struct IfStatement Block *else_block; } IfStatement; -typedef struct ReturnStatement -{ - Expression *return_value; -} ReturnStatement; - Statement *alloc_statement(StatementKind kind); Statement *alloc_assign_statement(char *variable, Expression *operand); Statement *alloc_block_statement(Block *block); Statement *alloc_if_statement(Expression *condition, Block *then_block, Elseif *elseif_list, Block *else_block); Statement *alloc_declaration_stmt(char *name, TypeSpecifier *type, Expression *initializer); Statement *alloc_return_stmt(Expression *expr); +Statement *alloc_expression_stmt(Expression *expr); StatementList *chain_statement_list(StatementList *list, Statement *statement); Elseif *alloc_else_if(Expression *condition, Block *block); Elseif *chain_else_if_list(Elseif *list, Elseif *elseif); diff --git a/interpreter/eval.cpp b/interpreter/eval.cpp index 0aafdc6..9362901 100644 --- a/interpreter/eval.cpp +++ b/interpreter/eval.cpp @@ -4,6 +4,8 @@ #include "eval.h" #include +void print_expr_value(ExprValue val); + ExprValue eval_int_binary_expression(ExpressionKind type, int left, int right) { ExprValue v; @@ -335,9 +337,13 @@ StmtResult Interpreter::eval_stmt(Statement *stmt) } case RETURN_STATEMENT: { - ReturnStatement *return_s = stmt->u.return_s; result.type = RETURN_STATEMENT_RESULT; - result.u.return_value = this->eval_expression(return_s->return_value); + result.u.return_value = this->eval_expression(stmt->u.expr_s); + return result; + } + case EXPRESSION_STATEMENT: + { + print_expr_value(this->eval_expression(stmt->u.expr_s)); return result; } case DECLARATION_STATEMENT: @@ -377,3 +383,22 @@ StmtResult Interpreter::eval_stmt(Statement *stmt) exit(1); } } + +void print_expr_value(ExprValue val) +{ + switch (val.type) + { + case EXPR_INT_VALUE: + printf(">>>%d\n", val.u.int_value); + break; + case EXPR_DOUBLE_VALUE: + printf(">>>%lf\n", val.u.double_value); + break; + case EXPR_BOOL_VALUE: + printf(">>>%s\n", val.u.boolean_value ? "true" : "false"); + break; + default: + printf("invalid expression type when print expr value:%d", val.type); + exit(1); + } +} From 2ad060d6b64fce1707d9a239c4bf042420285298 Mon Sep 17 00:00:00 2001 From: shenao78 Date: Mon, 26 Jul 2021 17:57:48 +0800 Subject: [PATCH 5/5] unity func name --- compiler/create.c | 22 +++++++++++----------- compiler/grammar.y | 16 ++++++++-------- compiler/summoner.h | 10 +++++----- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/compiler/create.c b/compiler/create.c index eae53ce..6ae0bec 100644 --- a/compiler/create.c +++ b/compiler/create.c @@ -79,16 +79,16 @@ ArgumentList *chain_argument_list(ArgumentList *list, Expression *expr) return list; } -Statement *alloc_statement(StatementKind kind) +Statement *alloc_stmt(StatementKind kind) { Statement *stmt = (Statement *)malloc(sizeof(Statement)); stmt->kind = kind; return stmt; } -Statement *alloc_assign_statement(char *variable, Expression *operand) +Statement *alloc_assign_stmt(char *variable, Expression *operand) { - Statement *stmt = alloc_statement(ASSIGN_STATEMENT); + Statement *stmt = alloc_stmt(ASSIGN_STATEMENT); AssignStatement *assign_s = (AssignStatement *)malloc(sizeof(AssignStatement)); assign_s->variable = variable; assign_s->operand = operand; @@ -96,9 +96,9 @@ Statement *alloc_assign_statement(char *variable, Expression *operand) return stmt; } -Statement *alloc_if_statement(Expression *condition, Block *then_block, Elseif *elseif_list, Block *else_block) +Statement *alloc_if_stmt(Expression *condition, Block *then_block, Elseif *elseif_list, Block *else_block) { - Statement *stmt = alloc_statement(IF_STATEMENT); + Statement *stmt = alloc_stmt(IF_STATEMENT); IfStatement *if_s = (IfStatement *)malloc(sizeof(IfStatement)); if_s->condition = condition; if_s->then_block = then_block; @@ -110,7 +110,7 @@ Statement *alloc_if_statement(Expression *condition, Block *then_block, Elseif * Statement *alloc_declaration_stmt(char *name, TypeSpecifier *type, Expression *initializer) { - Statement *stmt = alloc_statement(DECLARATION_STATEMENT); + Statement *stmt = alloc_stmt(DECLARATION_STATEMENT); Declaration *decl_s = (Declaration *)malloc(sizeof(Declaration)); decl_s->name = name; decl_s->type = type; @@ -121,26 +121,26 @@ Statement *alloc_declaration_stmt(char *name, TypeSpecifier *type, Expression *i Statement *alloc_return_stmt(Expression *expr) { - Statement *stmt = alloc_statement(RETURN_STATEMENT); + Statement *stmt = alloc_stmt(RETURN_STATEMENT); stmt->u.expr_s = expr; return stmt; } Statement* alloc_expression_stmt(Expression *expr) { - Statement *stmt = alloc_statement(EXPRESSION_STATEMENT); + Statement *stmt = alloc_stmt(EXPRESSION_STATEMENT); stmt->u.expr_s = expr; return stmt; } -Statement *alloc_block_statement(Block *block) +Statement *alloc_block_stmt(Block *block) { - Statement *stmt = alloc_statement(BLOCK_STATEMENT); + Statement *stmt = alloc_stmt(BLOCK_STATEMENT); stmt->u.block_s = block; return stmt; } -StatementList *chain_statement_list(StatementList *list, Statement *statement) +StatementList *chain_stmt_list(StatementList *list, Statement *statement) { StatementList *stmt_list = (StatementList *)malloc(sizeof(StatementList)); stmt_list->statement = statement; diff --git a/compiler/grammar.y b/compiler/grammar.y index 5a44f05..9eb6d6b 100644 --- a/compiler/grammar.y +++ b/compiler/grammar.y @@ -86,14 +86,14 @@ paramter: ; stmt_list: - stmt {$$ = chain_statement_list(NULL, $1); } - | stmt_list new_line stmt {$$ = chain_statement_list($1, $3); } + stmt {$$ = chain_stmt_list(NULL, $1); } + | stmt_list new_line stmt {$$ = chain_stmt_list($1, $3); } ; stmt: - IDENTIFIER '=' expr { $$ = alloc_assign_statement($1, $3); } + IDENTIFIER '=' expr { $$ = alloc_assign_stmt($1, $3); } | expr { $$ = alloc_expression_stmt($1); } - | block { $$ = alloc_block_statement($1); } + | block { $$ = alloc_block_stmt($1); } | if_stmt | declaration_stmt | return_stmt @@ -122,10 +122,10 @@ return_stmt: ; if_stmt: - IF bool_expr block { $$ = alloc_if_statement($2, $3, NULL, NULL); } - | IF bool_expr block ELSE block { $$ = alloc_if_statement($2, $3, NULL, $5); } - | IF bool_expr block elseif_list { $$ = alloc_if_statement($2, $3, $4, NULL); } - | IF bool_expr block elseif_list ELSE block { $$ = alloc_if_statement($2, $3, $4, $6); } + IF bool_expr block { $$ = alloc_if_stmt($2, $3, NULL, NULL); } + | IF bool_expr block ELSE block { $$ = alloc_if_stmt($2, $3, NULL, $5); } + | IF bool_expr block elseif_list { $$ = alloc_if_stmt($2, $3, $4, NULL); } + | IF bool_expr block elseif_list ELSE block { $$ = alloc_if_stmt($2, $3, $4, $6); } ; elseif_list: diff --git a/compiler/summoner.h b/compiler/summoner.h index a03bf06..48d3d0c 100644 --- a/compiler/summoner.h +++ b/compiler/summoner.h @@ -157,14 +157,14 @@ typedef struct IfStatement Block *else_block; } IfStatement; -Statement *alloc_statement(StatementKind kind); -Statement *alloc_assign_statement(char *variable, Expression *operand); -Statement *alloc_block_statement(Block *block); -Statement *alloc_if_statement(Expression *condition, Block *then_block, Elseif *elseif_list, Block *else_block); +Statement *alloc_stmt(StatementKind kind); +Statement *alloc_assign_stmt(char *variable, Expression *operand); +Statement *alloc_block_stmt(Block *block); +Statement *alloc_if_stmt(Expression *condition, Block *then_block, Elseif *elseif_list, Block *else_block); Statement *alloc_declaration_stmt(char *name, TypeSpecifier *type, Expression *initializer); Statement *alloc_return_stmt(Expression *expr); Statement *alloc_expression_stmt(Expression *expr); -StatementList *chain_statement_list(StatementList *list, Statement *statement); +StatementList *chain_stmt_list(StatementList *list, Statement *statement); Elseif *alloc_else_if(Expression *condition, Block *block); Elseif *chain_else_if_list(Elseif *list, Elseif *elseif); Block *open_block();