Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions compiler/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ void add_definitions_to_compiler(DefinitionList *definitions)
compiler->func_definition_list = chain_func_definition_list(
compiler->func_definition_list, pos->definition->u.func_d);
break;
case DECLARATION_DEFINITION:
Copy link
Contributor

@boomyl boomyl Jul 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

目前这里是申明、常量、函数、结构体四种?常量也一并加上这次?另外变量定义也放这里?

compiler->declaration_list = chain_declaration_definition_list(
compiler->declaration_list, pos->definition->u.declaration);
default:
break;
}
Expand Down
28 changes: 27 additions & 1 deletion compiler/create.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,21 @@ Statement *alloc_declaration_stmt(char *name, TypeSpecifier *type, Expression *i
return stmt;
}

Statement *alloc_const_declaration_stmt(char *name, TypeSpecifier *type, Expression *initializer)
{
Statement *stmt = alloc_declaration_stmt(name, type, initializer);
stmt->u.decl_s->is_const = true;
return stmt;
}

Statement *alloc_return_stmt(Expression *expr)
{
Statement *stmt = alloc_stmt(RETURN_STATEMENT);
stmt->u.expr_s = expr;
return stmt;
}

Statement* alloc_expression_stmt(Expression *expr)
Statement *alloc_expression_stmt(Expression *expr)
{
Statement *stmt = alloc_stmt(EXPRESSION_STATEMENT);
stmt->u.expr_s = expr;
Expand Down Expand Up @@ -301,3 +308,22 @@ DefinitionList *chain_definition_list(DefinitionList *list, Definition *definiti
pos->next = alloc_definition_list(definition);
return list;
}

DeclarationList *chain_declaration_definition_list(DeclarationList *list, Declaration *declaration)
{
DeclarationList *next = (DeclarationList *)malloc(sizeof(DeclarationList));
next->declaration = declaration;
next->next = NULL;

if (list == NULL)
{
return next;
}

DeclarationList *pos;
for (pos = list; pos->next; pos = pos->next)
;

pos->next = next;
return list;
}
46 changes: 32 additions & 14 deletions compiler/grammar.y
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@ int yyerror(const char *s);
%token <double_value> DOUBLE_LITERAL
%token <int_value> INT_LITERAL
%token <identifier> IDENTIFIER;
%token VAR FUNCTION IF ELSE FOR RETURN BREAK CONTINUE NIL
%token VAR CONST FUNCTION IF ELSE FOR RETURN BREAK CONTINUE NIL
%token BOOL_T INT_T DOUBLE_T STRING_T

%type <expression> expr bool_expr func_call_expr
%type <statement> stmt if_stmt declaration_stmt return_stmt variable_declaration
%type <expression> expr bool_expr func_call_expr literal
%type <statement> stmt if_stmt return_stmt declaration_stmt variable_declaration_stmt const_stmt
%type <statement_list> stmt_list
%type <block> block
%type <elseif> elseif elseif_list
%type <type_specifier> type_specifier
%type <parameter_list> parameter_list paramter
%type <definition> definition func_definition
%type <definition> definition func_definition variable_definition const_definition
%type <definition_list> definition_list
%type <argument_list> argument_list

Expand Down Expand Up @@ -66,7 +66,8 @@ definition_list:

definition:
func_definition
| variable_declaration { $$ = alloc_declaration_definition($1); }
| const_definition
| variable_definition
;

func_definition:
Expand All @@ -76,6 +77,14 @@ func_definition:
| FUNCTION IDENTIFIER '(' ')' block { $$ = alloc_func_definition($2, NULL, NULL, $5); }
;

variable_definition:
variable_declaration_stmt { $$ = alloc_declaration_definition($1); }
;

const_definition:
const_stmt { $$ = alloc_declaration_definition($1); }
;

parameter_list:
paramter
| parameter_list ',' paramter { $$ = chain_parameter($1, $3); }
Expand All @@ -99,16 +108,21 @@ stmt:
| return_stmt
;

const_stmt:
CONST IDENTIFIER '=' literal { $$ = alloc_const_declaration_stmt($2, NULL, $4); }
| CONST IDENTIFIER type_specifier '=' literal { $$ = alloc_const_declaration_stmt($2, $3, $5); }
;

declaration_stmt:
IDENTIFIER DECL_ASSIGN expr { $$ = alloc_declaration_stmt($1, NULL, $3); }
| variable_declaration
| variable_declaration_stmt
;

variable_declaration:
VAR IDENTIFIER type_specifier { $$ = alloc_declaration_stmt($2, $3, NULL); }
| VAR IDENTIFIER type_specifier '=' expr { $$ = alloc_declaration_stmt($2, $3, $5); }
| VAR IDENTIFIER '=' expr { $$ = alloc_declaration_stmt($2, NULL, $4); }
;
variable_declaration_stmt:
VAR IDENTIFIER type_specifier { $$ = alloc_declaration_stmt($2, $3, NULL); }
| VAR IDENTIFIER type_specifier '=' expr { $$ = alloc_declaration_stmt($2, $3, $5); }
| VAR IDENTIFIER '=' expr { $$ = alloc_declaration_stmt($2, NULL, $4); }
;

type_specifier:
BOOL_T { $$ = alloc_type_specifier(BOOLEAN_TYPE, NULL); }
Expand Down Expand Up @@ -151,9 +165,7 @@ block:
;

expr:
INT_LITERAL { $$ = alloc_int_expression($1); }
| DOUBLE_LITERAL { $$ = alloc_double_expression($1); }
| BOOL_LITERAL { $$ = alloc_bool_expression($1); }
literal
| IDENTIFIER { $$ = alloc_identifier_expression($1); }
| expr '+' expr { $$ = alloc_binary_expression(ADD_EXPRESSION, $1, $3); }
| expr '-' expr { $$ = alloc_binary_expression(SUB_EXPRESSION, $1, $3); }
Expand All @@ -165,6 +177,12 @@ expr:
| func_call_expr
;

literal:
INT_LITERAL { $$ = alloc_int_expression($1); }
| DOUBLE_LITERAL { $$ = alloc_double_expression($1); }
| BOOL_LITERAL { $$ = alloc_bool_expression($1); }
;

bool_expr:
expr '>' expr { $$ = alloc_binary_expression(GT_EXPRESSION, $1, $3); }
| expr GE expr { $$ = alloc_binary_expression(GE_EXPRESSION, $1, $3); }
Expand Down
1 change: 1 addition & 0 deletions compiler/lex.l
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"for" return FOR;
"nil" return NIL;
"var" return VAR;
"const" return CONST;
"func" return FUNCTION;
"return" return RETURN;
"break" return BREAK;
Expand Down
3 changes: 3 additions & 0 deletions compiler/summoner.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ typedef struct Declaration
TypeSpecifier *type;
Expression *initializer;
bool is_local;
bool is_const;
} Declaration;

typedef struct DeclarationList {
Expand Down Expand Up @@ -163,6 +164,7 @@ 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_const_declaration_stmt(char *name, TypeSpecifier *type, Expression *initializer);
Statement *alloc_return_stmt(Expression *expr);
Statement *alloc_expression_stmt(Expression *expr);
StatementList *chain_stmt_list(StatementList *list, Statement *statement);
Expand Down Expand Up @@ -220,6 +222,7 @@ typedef struct FuncDefinition
Definition *alloc_func_definition(char *name, ParameterList *parameters, TypeSpecifier *return_type, Block *block);
FuncDefinition *chain_func_definition_list(FuncDefinition *list, FuncDefinition *next);
Definition *alloc_declaration_definition(Statement *declaration_stmt);
DeclarationList *chain_declaration_definition_list(DeclarationList *list, Declaration *declaration);
DefinitionList *alloc_definition_list(Definition *definition);
DefinitionList *chain_definition_list(DefinitionList *list, Definition *definition);

Expand Down
12 changes: 12 additions & 0 deletions interpreter/eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,13 @@ ExprValue Interpreter::eval_expression(Expression *expr)

void Interpreter::exec()
{
for (DeclarationList *pos = this->declaration_list; pos != nullptr; pos = pos->next)
{
Declaration *declaration = pos->declaration;
bool is_const = declaration->is_const;
this->current_scope->put_identifier(new Identifier(declaration->name, this->eval_expression(declaration->initializer), is_const));
}

FuncDefinition *func_d = this->find_func_definition("main");
if (func_d == nullptr)
{
Expand Down Expand Up @@ -305,6 +312,11 @@ StmtResult Interpreter::eval_stmt(Statement *stmt)
cout << "\"" << assign_s->variable << "\" is undefined" << endl;
exit(1);
}
if (identifier->get_is_const())
{
cout << "assign const is invalid" << endl;
exit(1);
}

identifier->set_value(this->eval_expression(assign_s->operand));
return result;
Expand Down
6 changes: 5 additions & 1 deletion interpreter/eval.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,16 @@ class Identifier
{
public:
Identifier(string name, ExprValue value) : name(name), value(value) {}
Identifier(string name, ExprValue value, bool is_const) : name(name), value(value), is_const(is_const) {}
void set_value(ExprValue value) { this->value = value; }
string get_name() { return this->name; }
ExprValue get_value() { return this->value; }
bool get_is_const() { return this->is_const; }

private:
string name;
ExprValue value;
bool is_const;
};

class Scope
Expand Down Expand Up @@ -82,12 +85,13 @@ class Scope
class Interpreter
{
public:
Interpreter(FuncDefinition *func_list) : func_definition_list(func_list), current_scope(nullptr){};
Interpreter(FuncDefinition *func_list, DeclarationList *declaration_list) : func_definition_list(func_list), declaration_list(declaration_list), current_scope(new Scope(nullptr)){};
void exec();

private:
Scope *current_scope;
FuncDefinition *func_definition_list;
DeclarationList *declaration_list;

ExprValue *eval_func(FuncDefinition *fd, ArgumentList *arg_list);
FuncDefinition *find_func_definition(const char *name);
Expand Down
4 changes: 2 additions & 2 deletions interpreter/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ int main(int argc, char *argv[])
yyparse();
}

Interpreter *interpreter = new Interpreter(compiler->func_definition_list);
Interpreter *interpreter = new Interpreter(compiler->func_definition_list, compiler->declaration_list);
interpreter->exec();
return 0;
}
}