Support int types
This commit is contained in:
parent
9bae263414
commit
80abf67355
|
@ -18,7 +18,8 @@ void yyerror(char *s)
|
||||||
typedef struct var // a variable
|
typedef struct var // a variable
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
int value;
|
int type;
|
||||||
|
int value; // 0 = bool, 1 = int
|
||||||
struct var *next;
|
struct var *next;
|
||||||
} var;
|
} var;
|
||||||
|
|
||||||
|
@ -30,14 +31,14 @@ typedef struct varlist // variable reference (used for print statement)
|
||||||
|
|
||||||
typedef struct expr // boolean expression
|
typedef struct expr // boolean expression
|
||||||
{
|
{
|
||||||
int type; // TRUE, FALSE, OR, AND, EQUIV, NOT, 0 (variable)
|
int type; // TRUE, FALSE, OR, AND, EQUIV, NOT, 0 (variable), PLUS, TIMES, INT
|
||||||
var *var;
|
var *var;
|
||||||
struct expr *left, *right;
|
struct expr *left, *right;
|
||||||
} expr;
|
} expr;
|
||||||
|
|
||||||
typedef struct stmt // command
|
typedef struct stmt // command
|
||||||
{
|
{
|
||||||
int type; // ASSIGN, ';', WHILE, PRINT
|
int type; // ASSIGN, ';', WHILE, IF, PRINT
|
||||||
var *var;
|
var *var;
|
||||||
expr *expr;
|
expr *expr;
|
||||||
struct stmt *left, *right;
|
struct stmt *left, *right;
|
||||||
|
@ -48,15 +49,17 @@ typedef struct stmt // command
|
||||||
/* All data pertaining to the programme are accessible from these two vars. */
|
/* All data pertaining to the programme are accessible from these two vars. */
|
||||||
|
|
||||||
var *program_vars;
|
var *program_vars;
|
||||||
|
var *program_ints;
|
||||||
stmt *program_stmts;
|
stmt *program_stmts;
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/* Functions for settting up data structures at parse time. */
|
/* Functions for settting up data structures at parse time. */
|
||||||
|
|
||||||
var* make_ident (char *s)
|
var* make_ident (char *s, int type) // type = 0 for a boolean var, type = 1 for an int var
|
||||||
{
|
{
|
||||||
var *v = malloc(sizeof(var));
|
var *v = malloc(sizeof(var));
|
||||||
v->name = s;
|
v->name = s;
|
||||||
|
v->type = type;
|
||||||
v->value = 0; // make variable false initially
|
v->value = 0; // make variable false initially
|
||||||
v->next = NULL;
|
v->next = NULL;
|
||||||
return v;
|
return v;
|
||||||
|
@ -65,8 +68,27 @@ var* make_ident (char *s)
|
||||||
var* find_ident (char *s)
|
var* find_ident (char *s)
|
||||||
{
|
{
|
||||||
var *v = program_vars;
|
var *v = program_vars;
|
||||||
while (v && strcmp(v->name,s)) v = v->next;
|
while (v && strcmp(v->name,s))
|
||||||
if (!v) { yyerror("undeclared variable"); exit(1); }
|
v = v->next;
|
||||||
|
if (!v) {
|
||||||
|
v = program_ints;
|
||||||
|
while (v && strcmp(v->name, s))
|
||||||
|
v = v->next;
|
||||||
|
}
|
||||||
|
if (!v) {
|
||||||
|
yyerror("undeclared variable");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
var* make_int(int val)
|
||||||
|
{
|
||||||
|
var *v = malloc(sizeof(var));
|
||||||
|
v->name = NULL;
|
||||||
|
v->type = 1; // int
|
||||||
|
v->value = val;
|
||||||
|
v->next = NULL;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,15 +137,18 @@ stmt* make_stmt (int type, var *var, expr *expr,
|
||||||
varlist *l;
|
varlist *l;
|
||||||
expr *e;
|
expr *e;
|
||||||
stmt *s;
|
stmt *s;
|
||||||
|
int val;
|
||||||
}
|
}
|
||||||
|
|
||||||
%type <v> declist
|
%type <v> bool_declist
|
||||||
|
%type <v> int_declist
|
||||||
%type <l> varlist
|
%type <l> varlist
|
||||||
%type <e> expr
|
%type <e> expr
|
||||||
%type <s> stmt assign
|
%type <s> stmt assign
|
||||||
|
|
||||||
%token BOOL WHILE DO OD IF THEN ELSE FI ASSIGN PRINT OR AND XOR NOT TRUE FALSE
|
%token BOOL TYPE_INT WHILE DO OD IF THEN ELSE FI ASSIGN PRINT OR AND XOR NOT TRUE FALSE
|
||||||
%token <i> IDENT
|
%token <i> IDENT
|
||||||
|
%token <val> INT
|
||||||
|
|
||||||
%left ';'
|
%left ';'
|
||||||
|
|
||||||
|
@ -131,15 +156,25 @@ stmt* make_stmt (int type, var *var, expr *expr,
|
||||||
%left AND
|
%left AND
|
||||||
%right NOT
|
%right NOT
|
||||||
%left EQUIV
|
%left EQUIV
|
||||||
|
%left PLUS
|
||||||
|
%left TIMES
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
prog : bools stmt { program_stmts = $2; }
|
prog : bools ints stmt { program_stmts = $3; }
|
||||||
|
| bools stmt { program_stmts = $2; }
|
||||||
|
| ints stmt { program_stmts = $2; }
|
||||||
|
| stmt { program_stmts = $1; }
|
||||||
|
|
||||||
bools : BOOL declist ';' { program_vars = $2; }
|
bools : BOOL bool_declist ';' { program_vars = $2; }
|
||||||
|
|
||||||
declist : IDENT { $$ = make_ident($1); }
|
bool_declist : IDENT { $$ = make_ident($1, 0); }
|
||||||
| declist ',' IDENT { ($$ = make_ident($3))->next = $1; }
|
| bool_declist ',' IDENT { ($$ = make_ident($3, 0))->next = $1; }
|
||||||
|
|
||||||
|
ints : TYPE_INT int_declist ';' { program_ints = $2; }
|
||||||
|
|
||||||
|
int_declist : IDENT { $$ = make_ident($1, 1); }
|
||||||
|
| int_declist ',' IDENT { ($$ = make_ident($3, 1))->next = $1; }
|
||||||
|
|
||||||
stmt : assign
|
stmt : assign
|
||||||
| stmt ';' stmt
|
| stmt ';' stmt
|
||||||
|
@ -168,6 +203,10 @@ expr : IDENT { $$ = make_expr(0,find_ident($1),NULL,NULL); }
|
||||||
| TRUE { $$ = make_expr(TRUE,NULL,NULL,NULL); }
|
| TRUE { $$ = make_expr(TRUE,NULL,NULL,NULL); }
|
||||||
| FALSE { $$ = make_expr(FALSE,NULL,NULL,NULL); }
|
| FALSE { $$ = make_expr(FALSE,NULL,NULL,NULL); }
|
||||||
| '(' expr ')' { $$ = $2; }
|
| '(' expr ')' { $$ = $2; }
|
||||||
|
| INT { $$ = make_expr(INT, make_int($1), NULL, NULL); }
|
||||||
|
| expr TIMES expr { $$ = make_expr(TIMES, NULL, $1, $3); }
|
||||||
|
| expr PLUS expr { $$ = make_expr(PLUS, NULL, $1, $3); }
|
||||||
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
@ -192,7 +231,13 @@ int eval (expr *e)
|
||||||
// Toutefois, on privilégie cette forme car faux = 0 et vrai = tout entier non nul.
|
// Toutefois, on privilégie cette forme car faux = 0 et vrai = tout entier non nul.
|
||||||
}
|
}
|
||||||
case NOT: return !eval(e->left);
|
case NOT: return !eval(e->left);
|
||||||
case 0: return e->var->value;
|
case PLUS:
|
||||||
|
return eval(e->left) + eval(e->right);
|
||||||
|
case TIMES:
|
||||||
|
return eval(e->left) * eval(e->right);
|
||||||
|
case INT:
|
||||||
|
case 0:
|
||||||
|
return e->var->value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +248,12 @@ void print_vars (varlist *l)
|
||||||
|
|
||||||
if (!l) return;
|
if (!l) return;
|
||||||
print_vars(l->next);
|
print_vars(l->next);
|
||||||
|
if (l->var->type == 0)
|
||||||
printf("%s = %c ", l->var->name, l->var->value ? 'T' : 'F');
|
printf("%s = %c ", l->var->name, l->var->value ? 'T' : 'F');
|
||||||
|
else if (l->var->type == 1)
|
||||||
|
printf("%s = %d ", l->var->name, l->var->value);
|
||||||
|
else
|
||||||
|
fprintf(stderr, "The type of the var %s is unknown", l->var->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void execute (stmt *s)
|
void execute (stmt *s)
|
||||||
|
|
|
@ -5,6 +5,7 @@ DIG [0-9]
|
||||||
%%
|
%%
|
||||||
|
|
||||||
"bool" { return BOOL; }
|
"bool" { return BOOL; }
|
||||||
|
"int" { return TYPE_INT; }
|
||||||
"while" { return WHILE; }
|
"while" { return WHILE; }
|
||||||
"do" { return DO; }
|
"do" { return DO; }
|
||||||
"od" { return OD; }
|
"od" { return OD; }
|
||||||
|
@ -15,6 +16,7 @@ DIG [0-9]
|
||||||
"print" { return PRINT; }
|
"print" { return PRINT; }
|
||||||
"true" { return TRUE; }
|
"true" { return TRUE; }
|
||||||
"false" { return FALSE; }
|
"false" { return FALSE; }
|
||||||
|
{DIG}+ { yylval.val = atoi(yytext); return INT; }
|
||||||
|
|
||||||
":=" { return ASSIGN; }
|
":=" { return ASSIGN; }
|
||||||
"^" { return XOR; }
|
"^" { return XOR; }
|
||||||
|
@ -22,6 +24,8 @@ DIG [0-9]
|
||||||
"&&" { return AND; }
|
"&&" { return AND; }
|
||||||
"!" { return NOT; }
|
"!" { return NOT; }
|
||||||
"<=>" { return EQUIV; }
|
"<=>" { return EQUIV; }
|
||||||
|
"+" { return PLUS; }
|
||||||
|
"*" { return TIMES; }
|
||||||
|
|
||||||
[a-z_][a-z0-9_]* { yylval.i = strdup(yytext); return IDENT; }
|
[a-z_][a-z0-9_]* { yylval.i = strdup(yytext); return IDENT; }
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
bool y;
|
||||||
|
int x;
|
||||||
|
x := 42 + 21;
|
||||||
|
y := true;
|
||||||
|
print x,y,x
|
Loading…
Reference in New Issue