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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
comp:
lex src/lex.l
yacc -d src/grammar.y
gcc -o bin/main y.tab.c lex.yy.c src/summoner.c src/interpreter.c
gcc -o bin/main y.tab.c lex.yy.c src/create.c src/interpreter.c src/compiler.c main/main.c
22 changes: 22 additions & 0 deletions main/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <stdio.h>
#include <stdlib.h>
#include "../src/summoner.h"

int main(int argc, char *argv[])
{
Compiler *compiler = malloc(sizeof(Compiler));
set_current_compiler(compiler);

extern int yyparse();
extern FILE *yyin;
yyin = fopen(argv[1], "r");
if (yyin == NULL)
{
printf("fail to open file:%s\n", argv[1]);
}
else
{
yyparse();
}
return 0;
}
13 changes: 13 additions & 0 deletions src/compiler.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "summoner.h"
Copy link
Contributor

Choose a reason for hiding this comment

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

静态compiler应该是全局可调,文件名改为类似util?


static Compiler *st_current_compiler;

Compiler *get_current_compiler()
{
return st_current_compiler;
}

void set_current_compiler(Compiler *compiler)
{
st_current_compiler = compiler;
}
36 changes: 35 additions & 1 deletion src/create.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ Statement *alloc_if_statement(Expression *condition, Block *then_block, Elseif *
return stmt;
}

Statement *alloc_declaration_stmt(char *name, TypeSpecifier *type, Expression *initializer)
{
Statement *stmt = alloc_statement(DECLARATION_STATEMENT);
Declaration *decl_s = malloc(sizeof(Declaration));
stmt->u.decl_s = decl_s;
return stmt;
}

Statement *alloc_block_statement(Block *block)
{
Statement *stmt = alloc_statement(BLOCK_STATEMENT);
Expand Down Expand Up @@ -133,9 +141,35 @@ Elseif *chain_else_if_list(Elseif *list, Elseif *elseif)
return list;
}

Block *open_block()
{
Block *new_block;
Compiler *compiler = get_current_compiler();
new_block = alloc_block(NULL);
new_block->outer_block = compiler->current_block;
compiler->current_block = new_block;
return new_block;
}

Block *close_block(Block *block, StatementList *stmt_list)
{
Compiler *compiler = get_current_compiler();
block->statement_list = stmt_list;
compiler->current_block = block->outer_block;
return block;
}

Block *alloc_block(StatementList *list)
{
Block *block = malloc(sizeof(Block));
block->statemen_list = list;
block->statement_list = list;
return block;
}

TypeSpecifier *alloc_type_specifier(BasicType type, char *identifier)
{
TypeSpecifier *type_s = malloc(sizeof(TypeSpecifier));
type_s->basic_type = type;
type_s->identifier = identifier;
return type_s;
}
52 changes: 30 additions & 22 deletions src/grammar.y
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
%{
#include <stdio.h>
#include <stdlib.h>
#include "src/ast.h"
#include "src/summoner.h"
#include "src/interpreter.h"

Expand All @@ -18,21 +17,24 @@ int yyerror(const char *s);
struct StatementList *statement_list;
struct Block *block;
struct Elseif *elseif;
struct TypeSpecifier *type_specifier;
}

%token <int_value> BOOL_LITERAL
%token <double_value> DOUBLE_LITERAL
%token <int_value> INT_LITERAL
%token <identifier> IDENTIFIER;
%token FUNCTION IF ELSE FOR RETURN BREAK CONTINUE NIL
%token VAR FUNCTION IF ELSE FOR RETURN BREAK CONTINUE NIL
%token BOOL_T INT_T DOUBLE_T STRING_T

%type <expression> expr bool_expr
%type <statement> stmt if_stmt
%type <statement> stmt if_stmt declaration_stmt
%type <statement_list> stmt_list
%type <block> block
%type <elseif> elseif elseif_list
%type <type_specifier> type_specifier

%nonassoc '='
%nonassoc '=' DECL_ASSIGN
%left AND OR
%nonassoc EQ NE
%nonassoc '>' '<' LE GE
Expand All @@ -53,8 +55,23 @@ stmt:
| IDENTIFIER '=' expr { $$ = alloc_assign_statement($1, $3); }
| block { $$ = alloc_block_statement($1); }
| if_stmt
| declaration_stmt
;

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); }
| IDENTIFIER DECL_ASSIGN expr { $$ = alloc_declaration_stmt($1, NULL, $3); }
;

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); }
;

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); }
Expand All @@ -72,11 +89,15 @@ elseif:
;

block:
'{' stmt_list '}' { $$ = alloc_block($2); }
| '{' new_line stmt_list '}' { $$ = alloc_block($3); }
| '{' stmt_list new_line '}' { $$ = alloc_block($2); }
| '{' new_line stmt_list new_line '}' { $$ = alloc_block($3); }
| '{' new_line '}' { $$ = alloc_block(NULL); }
'{' stmt_list { $<block>$ = open_block(); }
'}' { $$ = close_block($<block>3, $2); }
| '{' new_line stmt_list { $<block>$ = open_block(); }
'}' { $$ = close_block($<block>4, $3); }
| '{' stmt_list new_line { $<block>$ = open_block(); }
'}' { $$ = close_block($<block>4, $2); }
| '{' new_line stmt_list new_line { $<block>$ = open_block(); }
'}' { $$ = close_block($<block>5, $3); }
| '{' new_line '}' { $<block>$ = alloc_block(NULL); }
| '{' '}' { $$ = alloc_block(NULL); }
;

Expand Down Expand Up @@ -117,16 +138,3 @@ int yyerror(char const *str) {
fprintf(stderr, "parse error near %s\n", yytext);
return 0;
}

int main(int argc, char *argv[]) {
extern FILE *yyin;
yyin = fopen(argv[1], "r");
if(yyin==NULL)
{
printf("fail to open file:%s\n", argv[1]);
} else
{
yyparse();
}
return 0;
}
6 changes: 6 additions & 0 deletions src/lex.l
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
return *yytext;
}

":=" return DECL_ASSIGN;
">=" return GE;
"<=" return LE;
"==" return EQ;
Expand All @@ -20,10 +21,15 @@
"else" return ELSE;
"for" return FOR;
"nil" return NIL;
"var" return VAR;
"func" return FUNCTION;
"return" return RETURN;
"break" return BREAK;
"continue" return CONTINUE;
"bool" return BOOL_T;
"int" return INT_T;
"double" return DOUBLE_T;
"string" return STRING_T;

"true"|"false" {
yylval.int_value = strcmp(yytext, "false");
Expand Down
44 changes: 42 additions & 2 deletions src/summoner.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,25 @@ typedef enum
NOT_EXPRESSION, /* ! */
} ExpressionKind;

typedef enum
{
INTERFACE_TYPE = 1,
BOOLEAN_TYPE,
INT_TYPE,
DOUBLE_TYPE,
STRING_TYPE,
STRUCT_TYPE,
} BasicType;

typedef struct TypeSpecifier
{
BasicType basic_type;
char *identifier;
} TypeSpecifier;

typedef struct Expression
{
TypeSpecifier *type;
ExpressionKind kind;
union
{
Expand Down Expand Up @@ -83,8 +100,16 @@ typedef enum
RETURN_STATEMENT,
BREAK_STATEMENT,
CONTINUE_STATEMENT,
DECLARATION_STATEMENT,
} StatementKind;

typedef struct Declaration
{
char *name;
TypeSpecifier *type;
Expression *initializer;
} Declaration;

typedef struct AssignStatement
{
char *variable;
Expand All @@ -96,7 +121,8 @@ typedef struct Statement
StatementKind kind;
union
{
AssignStatement *assign_s;
struct AssignStatement *assign_s;
struct Declaration *decl_s;
struct Block *block_s;
struct IfStatement *if_s;
} u;
Expand All @@ -110,7 +136,8 @@ typedef struct StatementList

typedef struct Block
{
StatementList *statemen_list;
StatementList *statement_list;
struct Block *outer_block;
} Block;

typedef struct Elseif
Expand All @@ -132,10 +159,23 @@ 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);
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);
Block *open_block();
Block *close_block(Block *block, StatementList *stmt_list);
Block *alloc_block(StatementList *list);

TypeSpecifier *alloc_type_specifier(BasicType type, char *identifier);

typedef struct Compiler
{
Block *current_block;
} Compiler;

Compiler *get_current_compiler();
void set_current_compiler(Compiler *compiler);

#endif