Support int types

This commit is contained in:
Yohann D'ANELLO 2020-05-17 00:06:02 +02:00
parent 9bae263414
commit 80abf67355
3 changed files with 73 additions and 14 deletions

View File

@ -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);
printf("%s = %c ", l->var->name, l->var->value? 'T' : 'F'); if (l->var->type == 0)
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)

View File

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

5
syntaxique/test2.my Normal file
View File

@ -0,0 +1,5 @@
bool y;
int x;
x := 42 + 21;
y := true;
print x,y,x