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
14 changes: 10 additions & 4 deletions src/grammar.y
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@ int yyerror(const char *s);
%}

%union {
char *identifier;
double double_value;
int int_value;
struct Expression* expression;
struct Statement *statement;
}

%token <int_value> BOOL_LITERAL
%token <double_value> DOUBLE_LITERAL
%token <int_value> INT_LITERAL
%token '\n' '(' ')'

%token <identifier> IDENTIFIER;

%nonassoc '\n'
%nonassoc '='
%left AND OR
%nonassoc EQ NE
%nonassoc '>' '<' LE GE
Expand All @@ -29,6 +32,7 @@ int yyerror(const char *s);
%nonassoc NOT

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

%%
stmt_list:
Expand All @@ -37,13 +41,15 @@ stmt_list:
;

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

expr:
INT_LITERAL { $$ = allocIntExpression($1); }
| DOUBLE_LITERAL { $$ = allocDoubleExpression($1); }
| BOOL_LITERAL { $$ = allocBoolExpression($1); }
| IDENTIFIER { $$ = allocIdentifierExpression($1); }
| expr '+' expr { $$ = allocBinaryExpression(ADD_EXPRESSION, $1, $3); }
| expr '-' expr { $$ = allocBinaryExpression(SUB_EXPRESSION, $1, $3); }
| expr '*' expr { $$ = allocBinaryExpression(MUL_EXPRESSION, $1, $3); }
Expand All @@ -57,8 +63,8 @@ expr:
| expr AND expr { $$ = allocBinaryExpression(AND_EXPRESSION, $1, $3); }
| expr OR expr { $$ = allocBinaryExpression(OR_EXPRESSION, $1, $3); }
| '!' expr %prec NOT { $$ = allocUnaryExpression(NOT_EXPRESSION, $2); }
| '(' expr ')' { $$ = $2; }
| '-' expr %prec MINUS { $$ = allocUnaryExpression(MINUS_EXPRESSION, $2); }
| '(' expr ')' { $$ = $2; }
;
%%

Expand Down
16 changes: 8 additions & 8 deletions src/interpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include "interpreter.h"
#include "summoner.h"

ExprValue evalIntBinaryExpression(ExpressionType type, int left, int right)
ExprValue evalIntBinaryExpression(ExpressionKind type, int left, int right)
{
ExprValue v;
v.type = EXPR_INT_VALUE;
Expand Down Expand Up @@ -53,11 +53,11 @@ ExprValue evalIntBinaryExpression(ExpressionType type, int left, int right)
return v;
}

ExprValue evalDoubleBinaryExpression(ExpressionType type, double left, double right)
ExprValue evalDoubleBinaryExpression(ExpressionKind kind, double left, double right)
{
ExprValue v;
v.type = EXPR_DOUBLE_VALUE;
switch (type)
switch (kind)
{
case ADD_EXPRESSION:
v.u.double_value = left + right;
Expand Down Expand Up @@ -102,7 +102,7 @@ ExprValue evalDoubleBinaryExpression(ExpressionType type, double left, double ri
return v;
}

ExprValue evalBoolBinaryExpression(ExpressionType type, bool left, bool right)
ExprValue evalBoolBinaryExpression(ExpressionKind type, bool left, bool right)
{
ExprValue v;
v.type = EXPR_BOOL_VALUE;
Expand All @@ -121,7 +121,7 @@ ExprValue evalBoolBinaryExpression(ExpressionType type, bool left, bool right)
return v;
}

ExprValue evalBinaryExpression(ExpressionType type, BinaryExpression *binaryExpression)
ExprValue evalBinaryExpression(ExpressionKind type, BinaryExpression *binaryExpression)
{
ExprValue leftVal = evalExpression(binaryExpression->left);
ExprValue rightVal = evalExpression(binaryExpression->right);
Expand Down Expand Up @@ -157,7 +157,7 @@ ExprValue evalBinaryExpression(ExpressionType type, BinaryExpression *binaryExpr
ExprValue evalExpression(Expression *expr)
{
ExprValue v;
switch (expr->type)
switch (expr->kind)
{
case BOOL_EXPRESSION:
v.type = EXPR_BOOL_VALUE;
Expand Down Expand Up @@ -198,9 +198,9 @@ ExprValue evalExpression(Expression *expr)
case NE_EXPRESSION:
case AND_EXPRESSION:
case OR_EXPRESSION:
return evalBinaryExpression(expr->type, expr->u.binary_expression);
return evalBinaryExpression(expr->kind, expr->u.binary_expression);
default:
printf("invalid expression type when eval expression:%d\n", expr->type);
printf("invalid expression type when eval expression:%d\n", expr->kind);
exit(1);
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/lex.l
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@
return INT_LITERAL;
}

[A-Za-z_][A-Za-z_0-9]* {
char *new_str = malloc(strlen(yytext) + 1);
strcpy(new_str, yytext);
yylval.identifier = new_str;
return IDENTIFIER;
}

[ \t] ;

. {
Expand Down
44 changes: 35 additions & 9 deletions src/summoner.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,67 @@
#include <stdlib.h>
#include "summoner.h"

Expression *allocExpression(ExpressionType type) {
Expression *allocExpression(ExpressionKind kind)
{
Expression *expr = malloc(sizeof(Expression));
expr->type = type;
expr->kind = kind;
return expr;
}

Expression *allocIntExpression(int value) {
Expression *allocIntExpression(int value)
{
Expression *expr = allocExpression(INT_EXPRESSION);
expr->u.int_value = value;
return expr;
}

Expression *allocDoubleExpression(double value) {
Expression *allocDoubleExpression(double value)
{
Expression *expr = allocExpression(DOUBLE_EXPRESSION);
expr->u.double_value = value;
return expr;
}

Expression *allocBoolExpression(bool value) {
Expression *allocIdentifierExpression(char *identifier)
{
Expression *expr = allocExpression(IDENTIFIER_EXPRESSION);
expr->u.identifier = identifier;
return expr;
}

Expression *allocBoolExpression(bool value)
{
Expression *expr = allocExpression(BOOL_EXPRESSION);
expr->u.boolean_value = value;
return expr;
}

Expression *allocUnaryExpression(ExpressionType type, Expression *unaryExpr) {
Expression *expr = allocExpression(type);
Expression *allocUnaryExpression(ExpressionKind kind, Expression *unaryExpr)
{
Expression *expr = allocExpression(kind);
expr->u.unary_expression = unaryExpr;
return expr;
}

Expression *allocBinaryExpression(ExpressionType type, Expression *left, Expression *right) {
Expression *expr = allocExpression(type);
Expression *allocBinaryExpression(ExpressionKind kind, Expression *left, Expression *right)
{
Expression *expr = allocExpression(kind);
BinaryExpression *binary = malloc(sizeof(BinaryExpression));
binary->left = left;
binary->right = right;
expr->u.binary_expression = binary;
return expr;
}

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

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;
}
47 changes: 42 additions & 5 deletions src/summoner.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ typedef enum
BOOL_EXPRESSION = 1,
INT_EXPRESSION,
DOUBLE_EXPRESSION,
IDENTIFIER_EXPRESSION,
ADD_EXPRESSION,
SUB_EXPRESSION,
MUL_EXPRESSION,
Expand All @@ -42,18 +43,19 @@ typedef enum
AND_EXPRESSION, /* && */
OR_EXPRESSION, /* || */
NOT_EXPRESSION, /* ! */
} ExpressionType;
} ExpressionKind;

typedef struct BinaryExpression BinaryExpression;

typedef struct Expression
{
ExpressionType type;
ExpressionKind kind;
union
{
bool boolean_value;
int int_value;
double double_value;
char *identifier;
BinaryExpression *binary_expression;
struct Expression *unary_expression;
} u;
Expand All @@ -66,11 +68,46 @@ typedef struct BinaryExpression
Expression *right;
} BinaryExpression;

Expression *allocExpression(ExpressionType type);
Expression *allocExpression(ExpressionKind kind);
Expression *allocIntExpression(int value);
Expression *allocDoubleExpression(double value);
Expression *allocBoolExpression(bool value);
Expression *allocUnaryExpression(ExpressionType type, Expression *unaryExpr);
Expression *allocBinaryExpression(ExpressionType type, Expression *left, Expression *right);
Expression *allocIdentifierExpression(char *identifier);
Expression *allocUnaryExpression(ExpressionKind kind, Expression *unaryExpr);
Expression *allocBinaryExpression(ExpressionKind kind, Expression *left, Expression *right);

typedef enum
{
ASSIGN_STATEMENT = 1,
IF_STATEMENT,
FOR_STATEMENT,
RETURN_STATEMENT,
BREAK_STATEMENT,
CONTINUE_STATEMENT,
} StatementKind;

typedef struct AssignStatement
{
char *variable;
Expression *operand;
} AssignStatement;

typedef struct Statement
{
StatementKind kind;
union
{
AssignStatement *assign_s;
} u;
} Statement;

typedef struct StatementList
{
Statement *statement;
struct StatementList *next;
} StatementList;

Statement *allocStatement(StatementKind kind);
Statement *allocAssignStatement(char *variable, Expression *operand);

#endif