Skip to content

Commit

Permalink
Merge pull request #4 from Bytom/add_more_statements
Browse files Browse the repository at this point in the history
add if statement
  • Loading branch information
shenao78 committed Jul 20, 2021
2 parents 42ab411 + 0405763 commit 83d98d5
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 28 deletions.
67 changes: 51 additions & 16 deletions src/grammar.y
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,23 @@ int yyerror(const char *s);
int int_value;
struct Expression* expression;
struct Statement *statement;
struct StatementList *statement_list;
struct Block *block;
struct Elseif *elseif;
}

%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

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

%nonassoc '\n'
%nonassoc '='
%left AND OR
%nonassoc EQ NE
Expand All @@ -31,18 +40,39 @@ int yyerror(const char *s);
%nonassoc MINUS
%nonassoc NOT

%type <expression> expr
%type <statement> stmt

%%

stmt_list:
stmt
| stmt_list stmt
stmt {$$ = allocStatementList($1); }
| stmt_list '\n' stmt {$$ = chainStatementList($1, $3); }
;

stmt:
expr '\n' { printExprValue(evalExpression($1)); }
expr { printExprValue(evalExpression($1)); }
| IDENTIFIER '=' expr { $$ = allocAssignStatement($1, $3); }
| block { $$ = allocBlockStatement($1); }
| if_stmt
;

if_stmt:
IF '(' bool_expr ')' block { $$ = allocIfStatement($3, $5, NULL, NULL); }
| IF '(' bool_expr ')' block ELSE block { $$ = allocIfStatement($3, $5, NULL, $7); }
| IF '(' bool_expr ')' block elseif_list { $$ = allocIfStatement($3, $5, $6, NULL); }
| IF '(' bool_expr ')' block elseif_list ELSE block { $$ = allocIfStatement($3, $5, $6, $8); }
;

elseif_list:
elseif
| elseif_list elseif { $$ = chainElseifList($1, $2); }
;

elseif:
ELSE IF '(' bool_expr ')' block { $$ = allocElseif($4, $6); }
;

block:
'{' stmt_list '}' { $$ = allocBlock($2); }
| '{' '}' { $$ = allocBlock(NULL); }
;

expr:
Expand All @@ -54,18 +84,23 @@ expr:
| expr '-' expr { $$ = allocBinaryExpression(SUB_EXPRESSION, $1, $3); }
| expr '*' expr { $$ = allocBinaryExpression(MUL_EXPRESSION, $1, $3); }
| expr '/' expr { $$ = allocBinaryExpression(DIV_EXPRESSION, $1, $3); }
| expr '>' expr { $$ = allocBinaryExpression(GT_EXPRESSION, $1, $3); }
| expr GE expr { $$ = allocBinaryExpression(GE_EXPRESSION, $1, $3); }
| expr '<' expr { $$ = allocBinaryExpression(LT_EXPRESSION, $1, $3); }
| expr LE expr { $$ = allocBinaryExpression(LE_EXPRESSION, $1, $3); }
| expr EQ expr { $$ = allocBinaryExpression(EQ_EXPRESSION, $1, $3); }
| expr NE expr { $$ = allocBinaryExpression(NE_EXPRESSION, $1, $3); }
| expr AND expr { $$ = allocBinaryExpression(AND_EXPRESSION, $1, $3); }
| expr OR expr { $$ = allocBinaryExpression(OR_EXPRESSION, $1, $3); }
| '!' expr %prec NOT { $$ = allocUnaryExpression(NOT_EXPRESSION, $2); }
| '-' expr %prec MINUS { $$ = allocUnaryExpression(MINUS_EXPRESSION, $2); }
| '(' expr ')' { $$ = $2; }
| bool_expr
;

bool_expr:
expr '>' expr { $$ = allocBinaryExpression(GT_EXPRESSION, $1, $3); }
| expr GE expr { $$ = allocBinaryExpression(GE_EXPRESSION, $1, $3); }
| expr '<' expr { $$ = allocBinaryExpression(LT_EXPRESSION, $1, $3); }
| expr LE expr { $$ = allocBinaryExpression(LE_EXPRESSION, $1, $3); }
| expr EQ expr { $$ = allocBinaryExpression(EQ_EXPRESSION, $1, $3); }
| expr NE expr { $$ = allocBinaryExpression(NE_EXPRESSION, $1, $3); }
| expr AND expr { $$ = allocBinaryExpression(AND_EXPRESSION, $1, $3); }
| expr OR expr { $$ = allocBinaryExpression(OR_EXPRESSION, $1, $3); }
| '!' expr %prec NOT { $$ = allocUnaryExpression(NOT_EXPRESSION, $2); }
;

%%

int yyerror(char const *str) {
Expand Down
22 changes: 15 additions & 7 deletions src/lex.l
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,24 @@

%%

[+\-*/\(\)<>!\n] {
[+\-*/\(\)<>!{}\n] {
return *yytext;
}

">=" return GE;
"<=" return LE;
"==" return EQ;
"!=" return NE;
"&&" return AND;
"||" return OR;
">=" return GE;
"<=" return LE;
"==" return EQ;
"!=" return NE;
"&&" return AND;
"||" return OR;
"if" return IF;
"else" return ELSE;
"for" return FOR;
"nil" return NIL;
"func" return FUNCTION;
"return" return RETURN;
"break" return BREAK;
"continue" return CONTINUE;

"true"|"false" {
yylval.int_value = strcmp(yytext, "false");
Expand Down
77 changes: 75 additions & 2 deletions src/summoner.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,88 @@ Expression *allocBinaryExpression(ExpressionKind kind, Expression *left, Express
return expr;
}

Statement *allocStatement(StatementKind kind) {
Statement *allocStatement(StatementKind kind)
{
Statement *stmt = malloc(sizeof(Statement));
stmt->kind = kind;
return stmt;
}

Statement *allocAssignStatement(char *variable, Expression *operand) {
Statement *allocAssignStatement(char *variable, Expression *operand)
{
Statement *stmt = allocStatement(ASSIGN_STATEMENT);
AssignStatement *assign_s = malloc(sizeof(AssignStatement));
stmt->u.assign_s = assign_s;
return stmt;
}

Statement *allocIfStatement(Expression *condition, Block *then_block, Elseif *elseif_list, Block *else_block)
{
Statement *stmt = allocStatement(IF_STATEMENT);
IfStatement *if_s = malloc(sizeof(IfStatement));
if_s->condition = condition;
if_s->then_block = then_block;
if_s->elseif_list = elseif_list;
if_s->else_block = else_block;
stmt->u.if_s = if_s;
return stmt;
}

Statement *allocBlockStatement(Block *block)
{
Statement *stmt = allocStatement(BLOCK_STATEMENT);
stmt->u.block_s = block;
return stmt;
}

StatementList *allocStatementList(Statement *statement)
{
StatementList *stmt_list = malloc(sizeof(StatementList));
stmt_list->statement = statement;
return stmt_list;
}

StatementList *chainStatementList(StatementList *list, Statement *statement)
{
if (list == NULL)
{
return allocStatementList(statement);
}

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

pos->next = allocStatementList(statement);
return list;
}

Elseif *allocElseif(Expression *condition, Block *block)
{
Elseif *elseif = malloc(sizeof(Elseif));
elseif->condition = condition;
elseif->block = block;
return elseif;
}

Elseif *chainElseifList(Elseif *list, Elseif *elseif)
{
if (list == NULL)
{
return elseif;
}

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

pos->next = elseif;
return list;
}

Block *allocBlock(StatementList *list)
{
Block *block = malloc(sizeof(Block));
block->statemen_list = list;
return block;
}
34 changes: 31 additions & 3 deletions src/summoner.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ typedef enum
NOT_EXPRESSION, /* ! */
} ExpressionKind;

typedef struct BinaryExpression BinaryExpression;

typedef struct Expression
{
ExpressionKind kind;
Expand All @@ -56,7 +54,7 @@ typedef struct Expression
int int_value;
double double_value;
char *identifier;
BinaryExpression *binary_expression;
struct BinaryExpression *binary_expression;
struct Expression *unary_expression;
} u;

Expand All @@ -79,6 +77,7 @@ Expression *allocBinaryExpression(ExpressionKind kind, Expression *left, Express
typedef enum
{
ASSIGN_STATEMENT = 1,
BLOCK_STATEMENT,
IF_STATEMENT,
FOR_STATEMENT,
RETURN_STATEMENT,
Expand All @@ -98,6 +97,8 @@ typedef struct Statement
union
{
AssignStatement *assign_s;
struct Block *block_s;
struct IfStatement *if_s;
} u;
} Statement;

Expand All @@ -107,7 +108,34 @@ typedef struct StatementList
struct StatementList *next;
} StatementList;

typedef struct Block
{
StatementList *statemen_list;
} Block;

typedef struct Elseif
{
Expression *condition;
Block *block;
struct Elseif *next;
} Elseif;

typedef struct IfStatement
{
Expression *condition;
Block *then_block;
Elseif *elseif_list;
Block *else_block;
} IfStatement;

Statement *allocStatement(StatementKind kind);
Statement *allocAssignStatement(char *variable, Expression *operand);
Statement *allocBlockStatement(Block *block);
Statement *allocIfStatement(Expression *condition, Block *then_block, Elseif *elseif_list, Block *else_block);
StatementList *allocStatementList(Statement *statement);
StatementList *chainStatementList(StatementList *list, Statement *statement);
Elseif *allocElseif(Expression *condition, Block *block);
Elseif *chainElseifList(Elseif *list, Elseif *elseif);
Block *allocBlock(StatementList *list);

#endif

0 comments on commit 83d98d5

Please sign in to comment.