diff --git a/syntaxique/lang.y b/syntaxique/lang.y index 386fde6..b7da368 100644 --- a/syntaxique/lang.y +++ b/syntaxique/lang.y @@ -18,7 +18,8 @@ void yyerror(char *s) typedef struct var // a variable { char *name; - int value; + int type; + int value; // 0 = bool, 1 = int struct var *next; } var; @@ -30,14 +31,14 @@ typedef struct varlist // variable reference (used for print statement) 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; struct expr *left, *right; } expr; typedef struct stmt // command { - int type; // ASSIGN, ';', WHILE, PRINT + int type; // ASSIGN, ';', WHILE, IF, PRINT var *var; expr *expr; struct stmt *left, *right; @@ -48,15 +49,17 @@ typedef struct stmt // command /* All data pertaining to the programme are accessible from these two vars. */ var *program_vars; +var *program_ints; stmt *program_stmts; /****************************************************************************/ /* 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)); v->name = s; + v->type = type; v->value = 0; // make variable false initially v->next = NULL; return v; @@ -65,8 +68,27 @@ var* make_ident (char *s) var* find_ident (char *s) { var *v = program_vars; - while (v && strcmp(v->name,s)) v = v->next; - if (!v) { yyerror("undeclared variable"); exit(1); } + while (v && strcmp(v->name,s)) + 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; } @@ -115,15 +137,18 @@ stmt* make_stmt (int type, var *var, expr *expr, varlist *l; expr *e; stmt *s; + int val; } -%type declist +%type bool_declist +%type int_declist %type varlist %type expr %type 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 IDENT +%token INT %left ';' @@ -131,15 +156,25 @@ stmt* make_stmt (int type, var *var, expr *expr, %left AND %right NOT %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); } - | declist ',' IDENT { ($$ = make_ident($3))->next = $1; } +bool_declist : IDENT { $$ = make_ident($1, 0); } + | 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 ';' stmt @@ -168,6 +203,10 @@ expr : IDENT { $$ = make_expr(0,find_ident($1),NULL,NULL); } | TRUE { $$ = make_expr(TRUE,NULL,NULL,NULL); } | FALSE { $$ = make_expr(FALSE,NULL,NULL,NULL); } | '(' 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. } 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; 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) diff --git a/syntaxique/langlex.l b/syntaxique/langlex.l index 09a51bc..450a6fb 100644 --- a/syntaxique/langlex.l +++ b/syntaxique/langlex.l @@ -5,6 +5,7 @@ DIG [0-9] %% "bool" { return BOOL; } +"int" { return TYPE_INT; } "while" { return WHILE; } "do" { return DO; } "od" { return OD; } @@ -15,6 +16,7 @@ DIG [0-9] "print" { return PRINT; } "true" { return TRUE; } "false" { return FALSE; } +{DIG}+ { yylval.val = atoi(yytext); return INT; } ":=" { return ASSIGN; } "^" { return XOR; } @@ -22,6 +24,8 @@ DIG [0-9] "&&" { return AND; } "!" { return NOT; } "<=>" { return EQUIV; } +"+" { return PLUS; } +"*" { return TIMES; } [a-z_][a-z0-9_]* { yylval.i = strdup(yytext); return IDENT; } diff --git a/syntaxique/test2.my b/syntaxique/test2.my new file mode 100644 index 0000000..ed8eb0e --- /dev/null +++ b/syntaxique/test2.my @@ -0,0 +1,5 @@ +bool y; +int x; +x := 42 + 21; +y := true; +print x,y,x