├── Makefile ├── abstract_tree.h ├── basic.h ├── compiler.h ├── compiler.l ├── compiler.y ├── debug.c ├── debug.h ├── errors.c ├── errors.h ├── generator.c ├── generator.h ├── hashtable.c ├── hashtable.h ├── linked_list.c ├── linked_list.h ├── math_tools.c ├── symbols_table.c ├── symbols_table.h └── test.prout /Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS= -Wall -ansi -pedantic -O3 -fomit-frame-pointer -g 2 | CC= gcc ${CFLAGS} 3 | YFLAGS= -y -d 4 | LFLAGS= 5 | SNAME= tradV1 6 | LYSRC= y.tab.c lex.yy.c 7 | LSRC= compiler.l 8 | YSRC= compiler.y 9 | SRC= debug.c generator.c symbols_table.c errors.c 10 | OBJ= $(SRC:.c=.o) 11 | LYOBJ= $(LYSRC:.c=.o) 12 | 13 | all : ${SNAME} clean 14 | @echo success making ${SNAME} 15 | dev : ${SNAME} 16 | @echo success making ${SNAME} 17 | ${SNAME} : ${OBJ} 18 | @echo making ${SNAME} 19 | @flex ${LFLAGS} ${LSRC} 20 | @bison ${YFLAGS} ${YSRC} 21 | @gcc -c ${LYSRC} 22 | @gcc -o ${SNAME} ${LYOBJ} ${OBJ} 23 | %.o : %.c 24 | @echo -n 'compiling $< ... ' 25 | @${CC} -o $@ -c $< 26 | @echo done 27 | clean : 28 | @echo cleaning object files 29 | @rm -f ${OBJ} ${LYOBJ} 30 | cleanall : clean 31 | @echo cleaning executable file 32 | @rm -f ${SNAME} 33 | -------------------------------------------------------------------------------- /abstract_tree.h: -------------------------------------------------------------------------------- 1 | #ifndef _ABSTRACT_TREE_H 2 | #define _ABSTRACT_TREE_H 3 | 4 | #include 5 | 6 | #define AT_DEFINE_CHOICE(ST,E,U,UN) \ 7 | ({ \ 8 | ST _s; \ 9 | _s = (__typeof__(_s)) malloc(sizeof(_s)); \ 10 | _s->e = E; \ 11 | _s->u.UN = U; \ 12 | _s; \ 13 | }) 14 | 15 | 16 | /* exp node*/ 17 | 18 | enum at_enum_exp 19 | { 20 | AT_ENUM_EXP_EXPITERSEMIC, 21 | AT_ENUM_EXP_INTVAL, 22 | AT_ENUM_EXP_REALVAL, 23 | AT_ENUM_EXP_STRINGVAL, 24 | AT_ENUM_EXP_NEG, 25 | AT_ENUM_EXP_PLUS, 26 | AT_ENUM_EXP_MINUS, 27 | AT_ENUM_EXP_MULTIPLY, 28 | AT_ENUM_EXP_DIVIDE, 29 | AT_ENUM_EXP_EQUALS, 30 | AT_ENUM_EXP_GE, 31 | AT_ENUM_EXP_LE, 32 | AT_ENUM_EXP_DIFFERENT, 33 | AT_ENUM_EXP_GT, 34 | AT_ENUM_EXP_LT, 35 | AT_ENUM_EXP_AND, 36 | AT_ENUM_EXP_OR, 37 | AT_ENUM_EXP_LVALUE, 38 | AT_ENUM_EXP_AFFECT, 39 | AT_ENUM_EXP_IF, 40 | AT_ENUM_EXP_IFELSE, 41 | AT_ENUM_EXP_WHILE, 42 | AT_ENUM_EXP_FOR, 43 | AT_ENUM_EXP_LET, 44 | AT_ENUM_EXP_EXPITERID 45 | }; 46 | 47 | struct at_exp 48 | { 49 | enum at_enum_exp e; 50 | union 51 | { 52 | struct at_expitersemic *expitersemic; 53 | struct at_intval *intval; 54 | struct at_realval *realval; 55 | struct at_stringval *stringval; 56 | struct at_neg *neg; 57 | struct at_plus *plus; 58 | struct at_minus *minus; 59 | struct at_multiply *multiply; 60 | struct at_divide *divide; 61 | struct at_equals *equals; 62 | struct at_ge *ge; 63 | struct at_le *le; 64 | struct at_different *different; 65 | struct at_gt *gt; 66 | struct at_lt *lt; 67 | struct at_and *and; 68 | struct at_or *or; 69 | struct at_lvalue *lvalue; 70 | struct at_affect *affect; 71 | struct at_if *ift; 72 | struct at_ifelse *ifelse; 73 | struct at_while *whiled; 74 | struct at_for *ford; 75 | struct at_let *let; 76 | struct at_expiterid *expiterid; 77 | } u; 78 | }; 79 | 80 | struct at_expitersemic 81 | { 82 | struct at_exp *exp; 83 | struct at_expitersemic *next; 84 | }; 85 | 86 | struct at_expitercomma 87 | { 88 | struct at_exp *exp; 89 | struct at_expitercomma *next; 90 | }; 91 | 92 | struct at_expiterid 93 | { 94 | char *idname; 95 | struct at_expitercomma *iter; 96 | }; 97 | 98 | struct at_intval 99 | { 100 | int val; 101 | }; 102 | 103 | struct at_realval 104 | { 105 | float val; 106 | }; 107 | 108 | struct at_stringval 109 | { 110 | char *val; 111 | }; 112 | 113 | struct at_neg 114 | { 115 | struct at_exp *exp; 116 | }; 117 | 118 | struct at_plus 119 | { 120 | struct at_exp *expl; 121 | struct at_exp *expr; 122 | }; 123 | 124 | struct at_minus 125 | { 126 | struct at_exp *expl; 127 | struct at_exp *expr; 128 | }; 129 | 130 | struct at_multiply 131 | { 132 | struct at_exp *expl; 133 | struct at_exp *expr; 134 | }; 135 | 136 | struct at_divide 137 | { 138 | struct at_exp *expl; 139 | struct at_exp *expr; 140 | }; 141 | 142 | struct at_equals 143 | { 144 | struct at_exp *expl; 145 | struct at_exp *expr; 146 | }; 147 | 148 | struct at_ge 149 | { 150 | struct at_exp *expl; 151 | struct at_exp *expr; 152 | }; 153 | 154 | struct at_le 155 | { 156 | struct at_exp *expl; 157 | struct at_exp *expr; 158 | }; 159 | 160 | struct at_different 161 | { 162 | struct at_exp *expl; 163 | struct at_exp *expr; 164 | }; 165 | 166 | struct at_gt 167 | { 168 | struct at_exp *expl; 169 | struct at_exp *expr; 170 | }; 171 | 172 | struct at_lt 173 | { 174 | struct at_exp *expl; 175 | struct at_exp *expr; 176 | }; 177 | 178 | struct at_and 179 | { 180 | struct at_exp *expl; 181 | struct at_exp *expr; 182 | }; 183 | 184 | struct at_or 185 | { 186 | struct at_exp *expl; 187 | struct at_exp *expr; 188 | }; 189 | 190 | struct at_affect 191 | { 192 | struct at_lvalue *lvalue; 193 | struct at_exp *exp; 194 | }; 195 | 196 | struct at_if 197 | { 198 | struct at_exp *cond; 199 | struct at_exp *exp; 200 | }; 201 | 202 | struct at_ifelse 203 | { 204 | struct at_exp *cond; 205 | struct at_exp *expthen; 206 | struct at_exp *expelse; 207 | }; 208 | 209 | struct at_while 210 | { 211 | struct at_exp *cond; 212 | struct at_exp *exp; 213 | }; 214 | 215 | struct at_for 216 | { 217 | char *idname; 218 | struct at_exp *init; 219 | struct at_exp *end; 220 | struct at_exp *exp; 221 | }; 222 | 223 | /* let node*/ 224 | 225 | struct at_let 226 | { 227 | struct at_decs *decs; 228 | struct at_expitersemic *expitersemic; 229 | }; 230 | 231 | /* typeid node*/ 232 | enum at_enum_typeid 233 | { 234 | AT_TID_INT, 235 | AT_TID_REAL, 236 | AT_TID_STRING 237 | }; 238 | 239 | 240 | /* lvalue node*/ 241 | 242 | enum at_enum_lvalue 243 | { 244 | AT_ENUM_LVALUE_VAR, 245 | AT_ENUM_LVALUE_TAB 246 | }; 247 | 248 | struct at_lvalue 249 | { 250 | enum at_enum_lvalue e; 251 | union 252 | { 253 | struct at_exp *exp; 254 | } u; 255 | char *idname; 256 | }; 257 | 258 | 259 | /* decs node*/ 260 | 261 | struct at_decs 262 | { 263 | struct at_dec *dec; 264 | struct at_decs *next; 265 | }; 266 | 267 | /* vardec node*/ 268 | 269 | enum at_enum_vardec 270 | { 271 | AT_ENUM_VARDEC_NOTYPE, 272 | AT_ENUM_VARDEC_TYPE 273 | }; 274 | 275 | struct at_vardec 276 | { 277 | char *idname; 278 | struct at_exp *exp; 279 | 280 | enum at_enum_vardec e; 281 | union 282 | { 283 | enum at_enum_typeid idtype; 284 | } u; 285 | }; 286 | 287 | /* 288 | enum at_enum_tyfields 289 | { 290 | AT_ENUM_TYFIELDS_INT, 291 | AT_ENUM_TYFIELDS_REAL, 292 | AT_ENUM_TYFIELDS_STRING 293 | }; 294 | */ 295 | struct at_tyfields 296 | { 297 | /* 298 | enum at_enum_tyfields e; 299 | union 300 | { 301 | int valint; 302 | float valreal; 303 | char *varstring; 304 | } u; 305 | */ 306 | enum at_enum_typeid idtype; 307 | char *idname; 308 | struct at_tyfields *next; 309 | }; 310 | 311 | enum at_enum_fundec 312 | { 313 | AT_ENUM_FUNDEC_FUNC, 314 | AT_ENUM_FUNDEC_PROC 315 | }; 316 | 317 | struct at_fundec 318 | { 319 | char *idname; 320 | struct at_tyfields *tyfields; 321 | struct at_exp *exp; 322 | enum at_enum_fundec e; 323 | union 324 | { 325 | enum at_enum_typeid idtype; 326 | } u; 327 | }; 328 | 329 | enum at_enum_tabdec 330 | { 331 | AT_ENUM_TABDEC_NORMAL, 332 | AT_ENUM_TABDEC_AFFECT 333 | }; 334 | 335 | struct at_tabdec 336 | { 337 | char *idname; 338 | int size; 339 | enum at_enum_typeid idtype; 340 | enum at_enum_tabdec e; 341 | union 342 | { 343 | struct at_expitercomma *expitercomma; 344 | } u; 345 | }; 346 | 347 | /* dec node*/ 348 | 349 | enum at_enum_dec 350 | { 351 | AT_ENUM_DEC_VARDEC, 352 | AT_ENUM_DEC_FUNDEC, 353 | AT_ENUM_DEC_TABDEC 354 | }; 355 | 356 | struct at_dec 357 | { 358 | enum at_enum_dec e; 359 | union 360 | { 361 | struct at_vardec *vardec; 362 | struct at_fundec *fundec; 363 | struct at_tabdec *tabdec; 364 | } u; 365 | }; 366 | 367 | #endif 368 | -------------------------------------------------------------------------------- /basic.h: -------------------------------------------------------------------------------- 1 | #ifndef _BASIC_H 2 | #define _BASIC_H 3 | 4 | #include 5 | 6 | #define WRITES(FD,S) write(FD,S,sizeof(S)) 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /compiler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2006-2008 Sarzyniec Luc 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | * see the COPYING file for more informations */ 18 | 19 | #ifndef _COMPILER_H 20 | #define _COMPILER_H 21 | 22 | #define likely(X) __builtin_expect(!!(X),1) 23 | #define unlikely(X) __builtin_expect(!!(X),0) 24 | #define typeofm(T,M) __typeof__(((T *)0)->M) 25 | #define sizeofm(T,M) sizeof(typeofm(T,M)) 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /compiler.l: -------------------------------------------------------------------------------- 1 | %{ 2 | #include "abstract_tree.h" 3 | #include "y.tab.h" 4 | #include 5 | 6 | #define ID_MAX_LEN 16 7 | 8 | /* enlever commentaires et identificateurs trop longs */ 9 | void yyerror(char *msg); 10 | %} 11 | 12 | %% 13 | \( { return LP; } 14 | \) { return RP; } 15 | \{ { return LCB; } 16 | \} { return RCB; } 17 | \[ { return LSB; } 18 | \] { return RSB; } 19 | \; { return SEMICOLON; } 20 | if { return IF; } 21 | then { return THEN; } 22 | else { return ELSE; } 23 | while { return WHILE; } 24 | do { return DO; } 25 | for { return FOR; } 26 | to { return TO; } 27 | let { return LET; } 28 | in { return IN; } 29 | end { return END; } 30 | \, { return COMMA; } 31 | \+ { return PLUS; } 32 | \- { return MINUS; } 33 | \* { return MULTIPLY; } 34 | \/ { return DIVIDE; } 35 | \>= { return GE; } 36 | \<= { return LE; } 37 | \<\> { return DIFFERENT; } 38 | \> { return GT; } 39 | \< { return LT; } 40 | \&\& { return AND; } 41 | \|\| { return OR; } 42 | := { return AFFECT; } 43 | : { return COLON; } 44 | = { return EQUALS; } 45 | var { return VAR; } 46 | function { return FUNCTION; } 47 | int { return INT; } 48 | real { return REAL; } 49 | string { return STRING; } 50 | [a-zA-Z_][a-zA-Z_0-9]* { 51 | if (strlen(yytext) > ID_MAX_LEN) 52 | yyerror("ident too long"); 53 | else 54 | { 55 | int len; 56 | len = strlen(yytext) + 1; 57 | yylval.string = (__typeof__(yylval.string)) 58 | malloc((len * sizeof(yylval.string))); 59 | memcpy(yylval.string,yytext,len); 60 | return ID; 61 | } 62 | } 63 | [0-9]+ { 64 | yylval.intval = atoi(yytext); 65 | return INTVAL; 66 | } 67 | [0-9]+\.[0-9]+ { 68 | yylval.realval = atof(yytext); 69 | return REALVAL; 70 | } 71 | \".*\" { 72 | int len; 73 | len = strlen(yytext); 74 | yylval.string = (__typeof__(yylval.string)) 75 | malloc((len * sizeof(yylval.string))); 76 | memcpy(yylval.string,yytext + 1,len - 1); 77 | yylval.string[len] = 0; 78 | return STRINGVAL; 79 | } 80 | \/\*.*\*\/ ; 81 | [ \t] ; 82 | [\n] { yylval.line++; } 83 | . { fprintf(stderr,"(caractere inconnu) "); yyerror(yytext); } 84 | 85 | %% 86 | 87 | int 88 | yywrap(void) 89 | { 90 | return 1; 91 | } 92 | -------------------------------------------------------------------------------- /compiler.y: -------------------------------------------------------------------------------- 1 | %{ 2 | /* #define _COMPILER_DEBUG */ 3 | #include 4 | #include 5 | #include "abstract_tree.h" 6 | #include "symbols_table.h" 7 | #include "errors.h" 8 | #include "debug.h" 9 | #include "generator.h" 10 | 11 | extern int err_error; 12 | 13 | struct st_node *curblock, *initblock; 14 | 15 | int yylex(void); 16 | void yyerror(char *msg); 17 | %} 18 | 19 | %start program 20 | %token LP RP LCB RCB LSB RSB SEMICOLON IF THEN ELSE WHILE DO FOR TO LET IN END COMMA PLUS MINUS MULTIPLY DIVIDE GE LE DIFFERENT GT LT AND OR AFFECT COLON EQUALS VAR FUNCTION INT REAL STRING NEG 21 | %token INTVAL 22 | %token REALVAL 23 | %token ID STRINGVAL 24 | 25 | %nonassoc DO 26 | %nonassoc THEN 27 | %nonassoc ELSE 28 | %nonassoc AFFECT 29 | %nonassoc EQUALS DIFFERENT GT LT GE LE 30 | %left AND OR 31 | %left MINUS PLUS 32 | %left MULTIPLY DIVIDE 33 | %left NEG 34 | 35 | %union { 36 | struct at_exp *r_exp; 37 | struct at_expitersemic *r_expitersemic; 38 | struct at_expitercomma *r_expitercomma; 39 | struct at_decs *r_decs; 40 | struct at_dec *r_dec; 41 | struct at_lvalue *r_lvalue; 42 | struct at_vardec *r_vardec; 43 | struct at_fundec *r_fundec; 44 | struct at_tabdec *r_tabdec; 45 | struct at_tyfields *r_tyfields; 46 | enum at_enum_typeid r_typeid; 47 | 48 | int intval; 49 | float realval; 50 | char *string; 51 | unsigned int line; 52 | } 53 | 54 | %type exp program 55 | %type expitersemic expitersemicP 56 | %type expitercomma expitercommaP expitercomma1 57 | %type dec 58 | %type decs decsdecs 59 | %type lvalue 60 | %type vardec 61 | %type tyfields tyfieldsiter tyfieldsiterP 62 | %type fundec 63 | %type tabdec 64 | %type typeid 65 | %type idfunc 66 | 67 | %% 68 | 69 | program : exp 70 | { 71 | if ($1) 72 | { 73 | #ifdef _COMPILER_DEBUG 74 | printf("abstract tree: "); 75 | print_at_exp($1); 76 | printf("\n\n"); 77 | printf("symbols table: "); 78 | print_st_node(initblock); 79 | printf("\n\n"); 80 | #endif 81 | if (err_error) 82 | { 83 | fprintf(stderr, 84 | "Error, can't generate code\n"); 85 | } 86 | else 87 | { 88 | #ifdef _COMPILER_DEBUG 89 | printf("---generating code---\n"); 90 | #endif 91 | generate($1); 92 | #ifdef _COMPILER_DEBUG 93 | printf("\n---code generated---\n"); 94 | #endif 95 | } 96 | } 97 | } 98 | exp : LP expitersemic RP 99 | { 100 | struct at_expitersemic *e; 101 | e = (__typeof__(e)) malloc(sizeof(e)); 102 | 103 | $$ = AT_DEFINE_CHOICE(struct at_exp *, 104 | AT_ENUM_EXP_EXPITERSEMIC, $2, expitersemic); 105 | } 106 | | INTVAL 107 | { 108 | struct at_intval *e; 109 | e = (__typeof__(e)) malloc(sizeof(e)); 110 | e->val = $1; 111 | 112 | $$ = AT_DEFINE_CHOICE(struct at_exp *, 113 | AT_ENUM_EXP_INTVAL, e, intval); 114 | } 115 | | REALVAL 116 | { 117 | struct at_realval *e; 118 | e = (__typeof__(e)) malloc(sizeof(e)); 119 | e->val = $1; 120 | 121 | $$ = AT_DEFINE_CHOICE(struct at_exp *, 122 | AT_ENUM_EXP_REALVAL, e, realval); 123 | } 124 | | STRINGVAL 125 | { 126 | int len; 127 | struct at_stringval *e; 128 | e = (__typeof__(e)) malloc(sizeof(e)); 129 | e->val = $1; 130 | 131 | $$ = AT_DEFINE_CHOICE(struct at_exp *, 132 | AT_ENUM_EXP_STRINGVAL, e, stringval); 133 | } 134 | | MINUS exp %prec NEG 135 | { 136 | struct at_neg *e; 137 | e = (__typeof__(e)) malloc(sizeof(e)); 138 | e->exp = $2; 139 | 140 | $$ = AT_DEFINE_CHOICE(struct at_exp *,AT_ENUM_EXP_NEG, 141 | e, neg); 142 | } 143 | | exp PLUS exp 144 | { 145 | struct at_plus *e; 146 | e = (__typeof__(e)) malloc(sizeof(e)); 147 | e->expl = $1; 148 | e->expr = $3; 149 | 150 | $$ = AT_DEFINE_CHOICE(struct at_exp *,AT_ENUM_EXP_PLUS, 151 | e, plus); 152 | } 153 | | exp MINUS exp 154 | { 155 | struct at_minus *e; 156 | e = (__typeof__(e)) malloc(sizeof(e)); 157 | e->expl = $1; 158 | e->expr = $3; 159 | 160 | $$ = AT_DEFINE_CHOICE(struct at_exp *,AT_ENUM_EXP_MINUS, 161 | e, minus); 162 | } 163 | | exp MULTIPLY exp 164 | { 165 | struct at_multiply *e; 166 | e = (__typeof__(e)) malloc(sizeof(e)); 167 | e->expl = $1; 168 | e->expr = $3; 169 | 170 | $$ = AT_DEFINE_CHOICE(struct at_exp *, 171 | AT_ENUM_EXP_MULTIPLY, e, multiply); 172 | } 173 | | exp DIVIDE exp 174 | { 175 | struct at_divide *e; 176 | e = (__typeof__(e)) malloc(sizeof(e)); 177 | e->expl = $1; 178 | e->expr = $3; 179 | 180 | $$ = AT_DEFINE_CHOICE(struct at_exp *, 181 | AT_ENUM_EXP_DIVIDE, e, divide); 182 | } 183 | | exp EQUALS exp 184 | { 185 | struct at_equals *e; 186 | e = (__typeof__(e)) malloc(sizeof(e)); 187 | e->expl = $1; 188 | e->expr = $3; 189 | 190 | $$ = AT_DEFINE_CHOICE(struct at_exp *, 191 | AT_ENUM_EXP_EQUALS, e, equals); 192 | } 193 | | exp GE exp 194 | { 195 | struct at_ge *e; 196 | e = (__typeof__(e)) malloc(sizeof(e)); 197 | e->expl = $1; 198 | e->expr = $3; 199 | 200 | $$ = AT_DEFINE_CHOICE(struct at_exp *,AT_ENUM_EXP_GE, 201 | e, ge); 202 | } 203 | | exp LE exp 204 | { 205 | struct at_le *e; 206 | e = (__typeof__(e)) malloc(sizeof(e)); 207 | e->expl = $1; 208 | e->expr = $3; 209 | 210 | $$ = AT_DEFINE_CHOICE(struct at_exp *,AT_ENUM_EXP_LE, 211 | e, le); 212 | } 213 | | exp DIFFERENT exp 214 | { 215 | struct at_different *e; 216 | e = (__typeof__(e)) malloc(sizeof(e)); 217 | e->expl = $1; 218 | e->expr = $3; 219 | 220 | $$ = AT_DEFINE_CHOICE(struct at_exp *, 221 | AT_ENUM_EXP_DIFFERENT, e, different); 222 | } 223 | | exp GT exp 224 | { 225 | struct at_gt *e; 226 | e = (__typeof__(e)) malloc(sizeof(e)); 227 | e->expl = $1; 228 | e->expr = $3; 229 | 230 | $$ = AT_DEFINE_CHOICE(struct at_exp *, AT_ENUM_EXP_GT, 231 | e, gt); 232 | } 233 | | exp LT exp 234 | { 235 | struct at_lt *e; 236 | e = (__typeof__(e)) malloc(sizeof(e)); 237 | e->expl = $1; 238 | e->expr = $3; 239 | 240 | $$ = AT_DEFINE_CHOICE(struct at_exp *,AT_ENUM_EXP_LT, 241 | e, lt); 242 | } 243 | | exp AND exp 244 | { 245 | struct at_and *e; 246 | e = (__typeof__(e)) malloc(sizeof(e)); 247 | e->expl = $1; 248 | e->expr = $3; 249 | 250 | $$ = AT_DEFINE_CHOICE(struct at_exp *,AT_ENUM_EXP_AND, 251 | e, and); 252 | } 253 | | exp OR exp 254 | { 255 | struct at_or *e; 256 | e = (__typeof__(e)) malloc(sizeof(e)); 257 | e->expl = $1; 258 | e->expr = $3; 259 | 260 | $$ = AT_DEFINE_CHOICE(struct at_exp *,AT_ENUM_EXP_OR, 261 | e, or); 262 | } 263 | | lvalue 264 | { 265 | $$ = AT_DEFINE_CHOICE(struct at_exp *, 266 | AT_ENUM_EXP_LVALUE, $1, lvalue); 267 | if (!st_node_lookup_entry(curblock,$1->idname)) 268 | err_msg_error(ERR_ENUM_ERROR_UNDECLARED,yylval.line,$1->idname); 269 | } 270 | | lvalue AFFECT exp 271 | { 272 | struct at_affect *e; 273 | e = (__typeof__(e)) malloc(sizeof(e)); 274 | e->lvalue = $1; 275 | e->exp = $3; 276 | 277 | $$ = AT_DEFINE_CHOICE(struct at_exp *, 278 | AT_ENUM_EXP_AFFECT, e, affect); 279 | if (!st_node_lookup_entry(curblock,$1->idname)) 280 | err_msg_error(ERR_ENUM_ERROR_UNDECLARED,yylval.line,$1->idname); 281 | } 282 | | IF exp THEN exp 283 | { 284 | struct at_if *e; 285 | e = (__typeof__(e)) malloc(sizeof(e)); 286 | e->cond = $2; 287 | e->exp = $4; 288 | 289 | $$ = AT_DEFINE_CHOICE(struct at_exp *,AT_ENUM_EXP_IF, 290 | e, ift); 291 | } 292 | | IF exp THEN exp ELSE exp 293 | { 294 | struct at_ifelse *e; 295 | e = (__typeof__(e)) malloc(sizeof(e)); 296 | e->cond = $2; 297 | e->expthen = $4; 298 | e->expelse = $6; 299 | 300 | $$ = AT_DEFINE_CHOICE(struct at_exp *, 301 | AT_ENUM_EXP_IFELSE, e, ifelse); 302 | } 303 | | WHILE exp DO exp 304 | { 305 | struct at_while *e; 306 | e = (__typeof__(e)) malloc(sizeof(e)); 307 | e->cond = $2; 308 | e->exp = $4; 309 | 310 | $$ = AT_DEFINE_CHOICE(struct at_exp *,AT_ENUM_EXP_WHILE, 311 | e, whiled); 312 | } 313 | | FOR ID AFFECT exp TO exp DO exp 314 | { 315 | struct at_for *e; 316 | e = (__typeof__(e)) malloc(sizeof(e)); 317 | e->idname = $2; 318 | e->init = $4; 319 | e->end = $6; 320 | e->exp = $8; 321 | $$ = AT_DEFINE_CHOICE(struct at_exp *,AT_ENUM_EXP_FOR, 322 | e, ford); 323 | if (!st_node_lookup_entry(curblock,$2)) 324 | err_msg_error(ERR_ENUM_ERROR_UNDECLARED,yylval.line,$2); 325 | } 326 | | LET decsdecs IN expitersemic END 327 | { 328 | struct at_let *e; 329 | e = (__typeof__(e)) malloc(sizeof(e)); 330 | e->decs = $2; 331 | e->expitersemic = $4; 332 | 333 | __typeof__(curblock) tmp; 334 | tmp = curblock->parent; 335 | if (curblock->parent) 336 | curblock->parent = curblock->parent->parent; 337 | curblock = tmp; 338 | 339 | $$ = AT_DEFINE_CHOICE(struct at_exp *,AT_ENUM_EXP_LET,e, 340 | let); 341 | } 342 | | ID LP expitercomma RP 343 | { 344 | struct at_expiterid *e; 345 | e = (__typeof__(e)) malloc(sizeof(e)); 346 | e->idname = $1; 347 | e->iter = $3; 348 | 349 | $$ = AT_DEFINE_CHOICE(struct at_exp *, 350 | AT_ENUM_EXP_EXPITERID, e, expiterid); 351 | 352 | if (!st_node_lookup_entry(curblock,$1)) 353 | err_msg_error(ERR_ENUM_ERROR_UNDECLARED,yylval.line,$1); 354 | } 355 | ; 356 | expitersemic : exp expitersemicP 357 | { 358 | struct at_expitersemic *e; 359 | e = (__typeof__(e)) malloc(sizeof(e)); 360 | e->exp = $1; 361 | e->next = $2; 362 | $$ = e; 363 | } 364 | | 365 | { 366 | $$ = 0; 367 | } 368 | ; 369 | expitersemicP : SEMICOLON exp expitersemicP 370 | { 371 | struct at_expitersemic *e; 372 | e = (__typeof__(e)) malloc(sizeof(e)); 373 | e->exp = $2; 374 | e->next = $3; 375 | $$ = e; 376 | } 377 | | 378 | { 379 | $$ = 0; 380 | } 381 | ; 382 | expitercomma : exp expitercommaP 383 | { 384 | struct at_expitercomma *e; 385 | e = (__typeof__(e)) malloc(sizeof(e)); 386 | e->exp = $1; 387 | e->next = $2; 388 | $$ = e; 389 | } 390 | | 391 | { 392 | $$ = 0; 393 | } 394 | ; 395 | expitercomma1 : exp expitercommaP 396 | { 397 | struct at_expitercomma *e; 398 | e = (__typeof__(e)) malloc(sizeof(e)); 399 | e->exp = $1; 400 | e->next = $2; 401 | $$ = e; 402 | } 403 | ; 404 | expitercommaP : COMMA exp expitercommaP 405 | { 406 | struct at_expitercomma *e; 407 | e = (__typeof__(e)) malloc(sizeof(e)); 408 | e->exp = $2; 409 | e->next = $3; 410 | $$ = e; 411 | } 412 | | 413 | { 414 | $$ = 0; 415 | } 416 | ; 417 | lvalue : ID 418 | { 419 | struct at_lvalue *l; 420 | l = (__typeof__(l)) malloc(sizeof(l)); 421 | l->idname = $1; 422 | l->e = AT_ENUM_LVALUE_VAR; 423 | $$ = l; 424 | } 425 | | ID LSB exp RSB 426 | { 427 | struct at_lvalue *l; 428 | l = AT_DEFINE_CHOICE(__typeof__(l),AT_ENUM_LVALUE_TAB, 429 | $3, exp); 430 | l->idname = $1; 431 | $$ = l; 432 | } 433 | ; 434 | decsdecs : decs 435 | { 436 | curblock = st_node_init(curblock); 437 | $$ = $1; 438 | } 439 | decs : dec decs 440 | { 441 | struct at_decs *s; 442 | s = (__typeof__(s)) malloc(sizeof(s)); 443 | s->dec = $1; 444 | s->next = $2; 445 | $$ = s; 446 | } 447 | | 448 | { 449 | $$ = 0; 450 | } 451 | ; 452 | dec : vardec 453 | { 454 | st_node_add_entry(curblock, 455 | st_entry_init(($1)->idname,ST_ENUM_TYPE_VAR)); 456 | $$ = AT_DEFINE_CHOICE(struct at_dec *, 457 | AT_ENUM_DEC_VARDEC, $1, vardec); 458 | } 459 | | fundec 460 | { 461 | $$ = AT_DEFINE_CHOICE(struct at_dec *, 462 | AT_ENUM_DEC_FUNDEC, $1, fundec); 463 | /* print_fundec(($$)->u.fundec); */ 464 | } 465 | | tabdec 466 | { 467 | st_node_add_entry(curblock, 468 | st_entry_init(($1)->idname,ST_ENUM_TYPE_TAB)); 469 | $$ = AT_DEFINE_CHOICE(struct at_dec *, 470 | AT_ENUM_DEC_TABDEC, $1, tabdec); 471 | } 472 | ; 473 | vardec : VAR ID AFFECT exp 474 | { 475 | struct at_vardec *v; 476 | v = (__typeof__(v)) malloc(sizeof(v)); 477 | v->e = AT_ENUM_VARDEC_NOTYPE; 478 | v->idname = $2; 479 | v->exp = $4; 480 | $$ = v; 481 | } 482 | | VAR ID COLON typeid AFFECT exp 483 | { 484 | struct at_vardec *v; 485 | v = AT_DEFINE_CHOICE(__typeof__(v),AT_ENUM_VARDEC_TYPE, 486 | $4, idtype); 487 | v->idname = $2; 488 | v->exp = $6; 489 | $$ = v; 490 | } 491 | ; 492 | /* 493 | * Used for recursive declared functions 494 | * Without this, there is an undeclared function error 495 | */ 496 | idfunc : ID 497 | { 498 | $$ = $1; 499 | 500 | st_node_add_entry(curblock, 501 | st_entry_init($$,ST_ENUM_TYPE_FUNC)); 502 | } 503 | fundec : FUNCTION idfunc LP tyfields RP EQUALS exp 504 | { 505 | struct at_fundec *f; 506 | f = (__typeof__(f)) malloc(sizeof(f)); 507 | f->e = AT_ENUM_FUNDEC_PROC; 508 | f->idname = $2; 509 | f->tyfields = $4; 510 | f->exp = $7; 511 | $$ = f; 512 | 513 | __typeof__(curblock) tmp; 514 | tmp = curblock->parent; 515 | if (curblock->parent) 516 | curblock->parent = curblock->parent->parent; 517 | curblock = tmp; 518 | } 519 | | FUNCTION idfunc LP tyfields RP COLON typeid EQUALS exp 520 | { 521 | struct at_fundec *f; 522 | f = AT_DEFINE_CHOICE(__typeof__(f),AT_ENUM_FUNDEC_FUNC, 523 | $7, idtype); 524 | f->idname = $2; 525 | f->tyfields = $4; 526 | f->exp = $9; 527 | $$ = f; 528 | 529 | __typeof__(curblock) tmp; 530 | tmp = curblock->parent; 531 | if (curblock->parent) 532 | curblock->parent = curblock->parent->parent; 533 | curblock = tmp; 534 | } 535 | ; 536 | tabdec : VAR ID COLON typeid LSB ID RSB 537 | { 538 | struct at_tabdec *t; 539 | t = (__typeof__(t)) malloc(sizeof(t)); 540 | t->idname = $2; 541 | t->size = atoi($6); 542 | t->idtype = $4; 543 | $$ = t; 544 | } 545 | | VAR ID COLON typeid LSB ID RSB AFFECT LCB expitercomma1 RCB 546 | { 547 | struct at_tabdec *t; 548 | t = AT_DEFINE_CHOICE(__typeof__(t), 549 | AT_ENUM_TABDEC_AFFECT, $10, expitercomma); 550 | t->idname = $2; 551 | t->size = atoi($6); 552 | t->idtype = $4; 553 | $$ = t; 554 | } 555 | ; 556 | tyfields : tyfieldsiter 557 | { 558 | $$ = $1; 559 | } 560 | | 561 | { 562 | $$ = 0; 563 | } 564 | ; 565 | tyfieldsiter : ID COLON typeid tyfieldsiterP 566 | { 567 | struct at_tyfields *t; 568 | t = (__typeof__(t)) malloc(sizeof(t)); 569 | t->idname = $1; 570 | t->idtype = $3; 571 | t->next = $4; 572 | 573 | st_node_add_entry(curblock, 574 | st_entry_init(t->idname,ST_ENUM_TYPE_VAR)); 575 | 576 | $$ = t; 577 | } 578 | ; 579 | tyfieldsiterP : COMMA ID COLON typeid tyfieldsiterP 580 | { 581 | struct at_tyfields *t; 582 | t = (__typeof__(t)) malloc(sizeof(t)); 583 | t->idname = $2; 584 | t->idtype = $4; 585 | t->next = $5; 586 | 587 | st_node_add_entry(curblock, 588 | st_entry_init(t->idname,ST_ENUM_TYPE_VAR)); 589 | 590 | $$ = t; 591 | } 592 | | 593 | { 594 | curblock = st_node_init(curblock); 595 | $$ = 0; 596 | } 597 | ; 598 | typeid : INT { $$ = AT_TID_INT; } 599 | | REAL { $$ = AT_TID_REAL; } 600 | | STRING { $$ = AT_TID_STRING; } 601 | ; 602 | 603 | %% 604 | 605 | void 606 | yyerror(char *msg) 607 | { 608 | fprintf(stderr,"%d: error: %s\n",yylval.line,msg); 609 | } 610 | 611 | int 612 | main(void) 613 | { 614 | yylval.line = 1; 615 | curblock = st_node_init(0); 616 | initblock = curblock; 617 | 618 | st_node_add_entry(curblock, st_entry_init("printi",ST_ENUM_TYPE_FUNC)); 619 | st_node_add_entry(curblock, st_entry_init("printr",ST_ENUM_TYPE_FUNC)); 620 | st_node_add_entry(curblock, st_entry_init("prints",ST_ENUM_TYPE_FUNC)); 621 | 622 | yyparse(); 623 | /* st_node_free(curblock); */ 624 | return 0; 625 | } 626 | -------------------------------------------------------------------------------- /debug.c: -------------------------------------------------------------------------------- 1 | #include "debug.h" 2 | #include "abstract_tree.h" 3 | #include "symbols_table.h" 4 | 5 | #include 6 | 7 | void print_at_exp(struct at_exp *exp) 8 | { 9 | printf("exp("); 10 | if (!exp) 11 | return; 12 | switch (exp->e) 13 | { 14 | case AT_ENUM_EXP_LET: 15 | print_at_let(exp->u.let); 16 | break; 17 | default: 18 | break; 19 | } 20 | printf(")"); 21 | } 22 | 23 | void print_at_let(struct at_let *let) 24 | { 25 | printf("let("); 26 | if (!let) 27 | return; 28 | print_at_decs(let->decs); 29 | printf(")"); 30 | } 31 | 32 | void print_at_decs(struct at_decs *decs) 33 | { 34 | printf("decs("); 35 | if (!decs) 36 | return; 37 | while (decs) 38 | { 39 | print_at_dec(decs->dec); 40 | decs = decs->next; 41 | } 42 | printf(")"); 43 | } 44 | 45 | void print_at_dec(struct at_dec *dec) 46 | { 47 | printf("dec("); 48 | if (!dec) 49 | return; 50 | switch(dec->e) 51 | { 52 | case AT_ENUM_DEC_VARDEC: 53 | print_at_vardec(dec->u.vardec); 54 | break; 55 | case AT_ENUM_DEC_FUNDEC: 56 | print_at_fundec(dec->u.fundec); 57 | break; 58 | default: 59 | break; 60 | } 61 | printf(")"); 62 | } 63 | 64 | void print_at_vardec(struct at_vardec *vardec) 65 | { 66 | printf("vardec("); 67 | if (!vardec) 68 | return; 69 | printf("idname:%s ",(vardec->idname ? vardec->idname : "{none}")); 70 | switch(vardec->e) 71 | { 72 | case AT_ENUM_VARDEC_TYPE: 73 | print_at_typeid(vardec->u.idtype); 74 | break; 75 | default: 76 | break; 77 | } 78 | printf(")"); 79 | print_at_exp(vardec->exp); 80 | } 81 | 82 | void print_at_fundec(struct at_fundec *fundec) 83 | { 84 | printf("fundec("); 85 | if (!fundec) 86 | return; 87 | 88 | printf("idname:%s ",(fundec->idname ? fundec->idname : "{none}")); 89 | 90 | switch(fundec->e) 91 | { 92 | case AT_ENUM_FUNDEC_FUNC: 93 | print_at_typeid(fundec->u.idtype); 94 | break; 95 | default: 96 | break; 97 | } 98 | 99 | print_at_tyfields(fundec->tyfields); 100 | print_at_exp(fundec->exp); 101 | 102 | printf(")"); 103 | } 104 | 105 | void print_at_tyfields(struct at_tyfields *tyfields) 106 | { 107 | printf("tyfields("); 108 | if (!tyfields) 109 | return; 110 | 111 | while (tyfields) 112 | { 113 | printf("idname:%s ",(tyfields->idname ? tyfields->idname 114 | : "{none}")); 115 | print_at_typeid(tyfields->idtype); 116 | printf(","); 117 | tyfields = tyfields->next; 118 | } 119 | printf("\010"); 120 | 121 | printf(")"); 122 | } 123 | 124 | void print_at_typeid(enum at_enum_typeid idtype) 125 | { 126 | printf("idtype("); 127 | switch(idtype) 128 | { 129 | case AT_TID_INT: 130 | printf("INT"); 131 | break; 132 | case AT_TID_REAL: 133 | printf("REAL"); 134 | break; 135 | case AT_TID_STRING: 136 | printf("STRING"); 137 | break; 138 | default: 139 | break; 140 | } 141 | printf(")"); 142 | } 143 | 144 | void print_st_node(struct st_node *node) 145 | { 146 | __typeof__(node->childs) ptr; 147 | 148 | if (!node) 149 | return; 150 | 151 | printf("Block[%d] ",node->num); 152 | print_st_entries(node->entries); 153 | 154 | ptr = node->siblings; 155 | while (ptr) 156 | { 157 | printf("|"); 158 | print_st_node(ptr); 159 | ptr = ptr->siblings; 160 | } 161 | 162 | if (node->childs) 163 | { 164 | printf("{"); 165 | print_st_node(node->childs); 166 | printf("}"); 167 | } 168 | 169 | } 170 | 171 | void print_st_entries(struct st_entry *entry) 172 | { 173 | if (!entry) 174 | return; 175 | 176 | printf("name:%s [",entry->name); 177 | switch (entry->type) 178 | { 179 | case ST_ENUM_TYPE_VAR: 180 | printf("VAR"); 181 | break; 182 | case ST_ENUM_TYPE_FUNC: 183 | printf("FUNC"); 184 | break; 185 | case ST_ENUM_TYPE_TAB: 186 | printf("TAB"); 187 | break; 188 | default: 189 | break; 190 | } 191 | printf("], "); 192 | 193 | if (entry->next) 194 | print_st_entries(entry->next); 195 | } 196 | 197 | -------------------------------------------------------------------------------- /debug.h: -------------------------------------------------------------------------------- 1 | #ifndef _DEBUG_H 2 | #define _DEBUG_H 3 | 4 | #include "abstract_tree.h" 5 | #include "symbols_table.h" 6 | 7 | void print_at_exp(struct at_exp *exp); 8 | void print_at_let(struct at_let *let); 9 | void print_at_decs(struct at_decs *decs); 10 | void print_at_dec(struct at_dec *dec); 11 | void print_at_vardec(struct at_vardec *vardec); 12 | void print_at_fundec(struct at_fundec *fundec); 13 | void print_at_tyfields(struct at_tyfields *tyfields); 14 | void print_at_typeid(enum at_enum_typeid idtype); 15 | 16 | void print_st_node(struct st_node *node); 17 | void print_st_entries(struct st_entry *entry); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /errors.c: -------------------------------------------------------------------------------- 1 | #include "errors.h" 2 | #include 3 | 4 | int err_error = 0; 5 | 6 | struct err_list list[] = { 7 | { ERR_ENUM_ERROR_UNDECLARED, "undeclared variable" }, 8 | { ERR_ENUM_WARN_UNINITIALIZED, "initialised variable" }, 9 | { ERR_ENUM_WARN_UNUSED, "unused variable" }, 10 | { 0, 0 } 11 | }; 12 | 13 | char * 14 | err_lookup_enum(enum err_enum_list e) 15 | { 16 | struct err_list *ptr; 17 | ptr = list; 18 | 19 | while (ptr->errmsg) 20 | { 21 | if (ptr->e == e) 22 | break; 23 | } 24 | 25 | if (ptr->errmsg) 26 | return ptr->errmsg; 27 | else 28 | return 0; 29 | } 30 | 31 | void 32 | err_msg_error( 33 | enum err_enum_list e, 34 | int line, 35 | char *name) 36 | { 37 | if (!err_error) 38 | err_error = 1; 39 | fprintf(stderr,"%d: error: %s %s\n",line,err_lookup_enum(e),name); 40 | } 41 | 42 | void 43 | err_msg_warn( 44 | enum err_enum_list e, 45 | int line, 46 | char *name) 47 | { 48 | fprintf(stderr,"%d: warning: %s %s\n",line,err_lookup_enum(e),name); 49 | } 50 | -------------------------------------------------------------------------------- /errors.h: -------------------------------------------------------------------------------- 1 | #ifndef _ERRORS_H 2 | #define _ERRORS_H 3 | 4 | enum err_enum_list 5 | { 6 | ERR_ENUM_ERROR_UNDECLARED, 7 | ERR_ENUM_WARN_UNUSED, 8 | ERR_ENUM_WARN_UNINITIALIZED 9 | }; 10 | 11 | struct err_list 12 | { 13 | enum err_enum_list e; 14 | char *errmsg; 15 | }; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /generator.c: -------------------------------------------------------------------------------- 1 | #include "generator.h" 2 | #include "abstract_tree.h" 3 | #include "basic.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int fd = 0; 11 | int nbimbr = 1; 12 | 13 | void generate_new_line() 14 | { 15 | int i = nbimbr; 16 | WRITES(fd,"\n"); 17 | while(i-- > 0) 18 | WRITES(fd,GEN_INDENT); 19 | } 20 | 21 | void generate(struct at_exp *exp) 22 | { 23 | fd = open("resultat.c",O_CREAT | O_WRONLY | O_TRUNC); 24 | 25 | WRITES(fd,"#include \n"); 26 | WRITES(fd,"void printi(int i) { printf(\"%d\\n\",i); }\n"); 27 | WRITES(fd,"void printr(float f) { printf(\"%f\\n\",f); }\n"); 28 | WRITES(fd,"void prints(char *s) { printf(\"%s\\n\",s); }\n"); 29 | WRITES(fd,"int main(void)\n{"); 30 | generate_new_line(); 31 | generate_exp(exp); 32 | WRITES(fd,"\n}\n"); 33 | } 34 | 35 | void generate_exp(struct at_exp *exp) 36 | { 37 | if (!exp) 38 | return; 39 | switch (exp->e) 40 | { 41 | case AT_ENUM_EXP_EXPITERSEMIC: 42 | generate_expitersemic(exp->u.expitersemic); 43 | break; 44 | case AT_ENUM_EXP_INTVAL: 45 | generate_intval(exp->u.intval); 46 | break; 47 | case AT_ENUM_EXP_REALVAL: 48 | generate_realval(exp->u.realval); 49 | break; 50 | case AT_ENUM_EXP_STRINGVAL: 51 | generate_stringval(exp->u.stringval); 52 | break; 53 | case AT_ENUM_EXP_NEG: 54 | generate_neg(exp->u.neg); 55 | break; 56 | case AT_ENUM_EXP_PLUS: 57 | generate_plus(exp->u.plus); 58 | break; 59 | case AT_ENUM_EXP_MINUS: 60 | generate_minus(exp->u.minus); 61 | break; 62 | case AT_ENUM_EXP_MULTIPLY: 63 | generate_multiply(exp->u.multiply); 64 | break; 65 | case AT_ENUM_EXP_DIVIDE: 66 | generate_divide(exp->u.divide); 67 | break; 68 | case AT_ENUM_EXP_EQUALS: 69 | generate_equals(exp->u.equals); 70 | break; 71 | case AT_ENUM_EXP_GE: 72 | generate_ge(exp->u.ge); 73 | break; 74 | case AT_ENUM_EXP_LE: 75 | generate_le(exp->u.le); 76 | break; 77 | case AT_ENUM_EXP_DIFFERENT: 78 | generate_different(exp->u.different); 79 | break; 80 | case AT_ENUM_EXP_GT: 81 | generate_gt(exp->u.gt); 82 | break; 83 | case AT_ENUM_EXP_LT: 84 | generate_lt(exp->u.lt); 85 | break; 86 | case AT_ENUM_EXP_AND: 87 | generate_and(exp->u.and); 88 | break; 89 | case AT_ENUM_EXP_OR: 90 | generate_or(exp->u.or); 91 | break; 92 | case AT_ENUM_EXP_LVALUE: 93 | generate_lvalue(exp->u.lvalue); 94 | break; 95 | case AT_ENUM_EXP_AFFECT: 96 | generate_affect(exp->u.affect); 97 | break; 98 | case AT_ENUM_EXP_IF: 99 | generate_ift(exp->u.ift); 100 | break; 101 | case AT_ENUM_EXP_IFELSE: 102 | generate_ifelse(exp->u.ifelse); 103 | break; 104 | case AT_ENUM_EXP_WHILE: 105 | generate_whiled(exp->u.whiled); 106 | break; 107 | case AT_ENUM_EXP_FOR: 108 | generate_ford(exp->u.ford); 109 | break; 110 | case AT_ENUM_EXP_LET: 111 | generate_let(exp->u.let); 112 | break; 113 | case AT_ENUM_EXP_EXPITERID: 114 | generate_expiterid(exp->u.expiterid); 115 | break; 116 | default: 117 | break; 118 | } 119 | } 120 | 121 | void generate_expitersemic(struct at_expitersemic *expitersemic) 122 | { 123 | while (expitersemic) 124 | { 125 | generate_exp(expitersemic->exp); 126 | WRITES(fd,";"); 127 | generate_new_line(); 128 | expitersemic = expitersemic->next; 129 | } 130 | } 131 | 132 | void generate_intval(struct at_intval *intval) 133 | { 134 | char buff[64]; 135 | int len; 136 | len = snprintf(buff,sizeof(buff),"%d",intval->val); 137 | write(fd,buff,len); 138 | /* 139 | fprintf((FILE *)fd,"%d",intval->val); 140 | */ 141 | } 142 | 143 | void generate_realval(struct at_realval *realval) 144 | { 145 | char buff[64]; 146 | int len; 147 | len = snprintf(buff,sizeof(buff),"%f",realval->val); 148 | write(fd,buff,len); 149 | } 150 | 151 | void generate_stringval(struct at_stringval *stringval) 152 | { 153 | WRITES(fd,"\""); 154 | write(fd,stringval->val,strlen(stringval->val)); 155 | } 156 | 157 | void generate_neg(struct at_neg *neg) 158 | { 159 | WRITES(fd,"-("); 160 | generate_exp(neg->exp); 161 | WRITES(fd,")"); 162 | } 163 | 164 | void generate_plus(struct at_plus *plus) 165 | { 166 | GEN_BINARY_EXP(plus," + "); 167 | } 168 | 169 | void generate_minus(struct at_minus *minus) 170 | { 171 | GEN_BINARY_EXP(minus," - "); 172 | } 173 | 174 | void generate_multiply(struct at_multiply *multiply) 175 | { 176 | GEN_BINARY_EXP(multiply," * "); 177 | } 178 | 179 | void generate_divide(struct at_divide *divide) 180 | { 181 | GEN_BINARY_EXP(divide," / "); 182 | } 183 | 184 | void generate_equals(struct at_equals *equals) 185 | { 186 | GEN_BINARY_EXP(equals," == "); 187 | } 188 | 189 | void generate_ge(struct at_ge *ge) 190 | { 191 | GEN_BINARY_EXP(ge," >= "); 192 | } 193 | 194 | void generate_le(struct at_le *le) 195 | { 196 | GEN_BINARY_EXP(le," <= "); 197 | } 198 | 199 | void generate_different(struct at_different *different) 200 | { 201 | GEN_BINARY_EXP(different," != "); 202 | } 203 | 204 | void generate_gt(struct at_gt *gt) 205 | { 206 | GEN_BINARY_EXP(gt," > "); 207 | } 208 | 209 | void generate_lt(struct at_lt *lt) 210 | { 211 | GEN_BINARY_EXP(lt," < "); 212 | } 213 | 214 | void generate_and(struct at_and *and) 215 | { 216 | GEN_BINARY_EXP(and," && "); 217 | } 218 | 219 | void generate_or(struct at_or *or) 220 | { 221 | GEN_BINARY_EXP(or," || "); 222 | } 223 | 224 | void generate_lvalue(struct at_lvalue *lvalue) 225 | { 226 | write(fd,lvalue->idname,strlen(lvalue->idname)); 227 | switch (lvalue->e) 228 | { 229 | case AT_ENUM_LVALUE_TAB: 230 | WRITES(fd,"["); 231 | generate_exp(lvalue->u.exp); 232 | WRITES(fd,"]"); 233 | break; 234 | default: 235 | break; 236 | } 237 | } 238 | 239 | void generate_affect(struct at_affect *affect) 240 | { 241 | generate_lvalue(affect->lvalue); 242 | WRITES(fd," = "); 243 | generate_exp(affect->exp); 244 | } 245 | 246 | void generate_ift(struct at_if *ift) 247 | { 248 | WRITES(fd,"if ("); 249 | generate_exp(ift->cond); 250 | WRITES(fd,")"); 251 | generate_new_line(); 252 | WRITES(fd,"{"); 253 | nbimbr++; 254 | generate_new_line(); 255 | generate_exp(ift->exp); 256 | WRITES(fd,";"); 257 | nbimbr--; 258 | generate_new_line(); 259 | WRITES(fd,"}"); 260 | generate_new_line(); 261 | } 262 | 263 | void generate_ifelse(struct at_ifelse *ifelse) 264 | { 265 | WRITES(fd,"if ("); 266 | generate_exp(ifelse->cond); 267 | WRITES(fd,")"); 268 | generate_new_line(); 269 | WRITES(fd,"{"); 270 | nbimbr++; 271 | generate_new_line(); 272 | generate_exp(ifelse->expthen); 273 | WRITES(fd,";"); 274 | nbimbr--; 275 | generate_new_line(); 276 | WRITES(fd,"}"); 277 | generate_new_line(); 278 | WRITES(fd,"else"); 279 | generate_new_line(); 280 | WRITES(fd,"{"); 281 | nbimbr++; 282 | generate_new_line(); 283 | generate_exp(ifelse->expelse); 284 | WRITES(fd,";"); 285 | nbimbr--; 286 | generate_new_line(); 287 | WRITES(fd,"}"); 288 | generate_new_line(); 289 | } 290 | 291 | void generate_whiled(struct at_while *whiled) 292 | { 293 | WRITES(fd,"while ("); 294 | generate_exp(whiled->cond); 295 | WRITES(fd,")"); 296 | generate_new_line(); 297 | WRITES(fd,"{"); 298 | nbimbr++; 299 | generate_new_line(); 300 | generate_exp(whiled->exp); 301 | WRITES(fd,";"); 302 | nbimbr--; 303 | generate_new_line(); 304 | WRITES(fd,"}"); 305 | generate_new_line(); 306 | } 307 | 308 | void generate_ford(struct at_for *ford) 309 | { 310 | WRITES(fd,"for ("); 311 | write(fd,ford->idname,strlen(ford->idname)); 312 | WRITES(fd," = "); 313 | generate_exp(ford->init); 314 | WRITES(fd,"; "); 315 | generate_exp(ford->end); 316 | WRITES(fd,";;) "); 317 | generate_new_line(); 318 | WRITES(fd,"{"); 319 | nbimbr++; 320 | generate_new_line(); 321 | generate_exp(ford->exp); 322 | WRITES(fd,";"); 323 | nbimbr--; 324 | generate_new_line(); 325 | WRITES(fd,"}"); 326 | generate_new_line(); 327 | } 328 | 329 | void generate_expitercomma(struct at_expitercomma *expitercomma) 330 | { 331 | while (expitercomma->next) 332 | { 333 | generate_exp(expitercomma->exp); 334 | WRITES(fd,", "); 335 | expitercomma = expitercomma->next; 336 | } 337 | generate_exp(expitercomma->exp); 338 | 339 | } 340 | 341 | void generate_expiterid(struct at_expiterid *expiterid) 342 | { 343 | write(fd,expiterid->idname,strlen(expiterid->idname)); 344 | WRITES(fd,"("); 345 | generate_expitercomma(expiterid->iter); 346 | WRITES(fd,")"); 347 | } 348 | 349 | void generate_let(struct at_let *let) 350 | { 351 | if (!let) 352 | return; 353 | 354 | WRITES(fd,"{"); 355 | nbimbr++; 356 | generate_new_line(); 357 | generate_decs(let->decs); 358 | generate_expitersemic(let->expitersemic); 359 | nbimbr--; 360 | generate_new_line(); 361 | WRITES(fd,"}"); 362 | generate_new_line(); 363 | } 364 | 365 | void generate_decs(struct at_decs *decs) 366 | { 367 | if (!decs) 368 | return; 369 | while (decs) 370 | { 371 | generate_dec(decs->dec); 372 | decs = decs->next; 373 | } 374 | } 375 | 376 | void generate_dec(struct at_dec *dec) 377 | { 378 | if (!dec) 379 | return; 380 | 381 | switch(dec->e) 382 | { 383 | case AT_ENUM_DEC_VARDEC: 384 | generate_vardec(dec->u.vardec); 385 | break; 386 | case AT_ENUM_DEC_FUNDEC: 387 | generate_fundec(dec->u.fundec); 388 | break; 389 | case AT_ENUM_DEC_TABDEC: 390 | generate_tabdec(dec->u.tabdec); 391 | break; 392 | default: 393 | break; 394 | } 395 | } 396 | 397 | void generate_vardec(struct at_vardec *vardec) 398 | { 399 | if (!vardec) 400 | return; 401 | switch(vardec->e) 402 | { 403 | case AT_ENUM_VARDEC_TYPE: 404 | generate_typeid(vardec->u.idtype); 405 | break; 406 | default: 407 | generate_typeid(AT_TID_INT); 408 | break; 409 | } 410 | write(fd,vardec->idname,strlen(vardec->idname)); 411 | WRITES(fd," = "); 412 | generate_exp(vardec->exp); 413 | WRITES(fd,";"); 414 | generate_new_line(); 415 | } 416 | 417 | void generate_fundec(struct at_fundec *fundec) 418 | { 419 | if (!fundec) 420 | return; 421 | 422 | switch(fundec->e) 423 | { 424 | case AT_ENUM_FUNDEC_FUNC: 425 | generate_typeid(fundec->u.idtype); 426 | break; 427 | case AT_ENUM_FUNDEC_PROC: 428 | WRITES(fd,"void "); 429 | break; 430 | default: 431 | break; 432 | } 433 | 434 | write(fd,fundec->idname,strlen(fundec->idname)); 435 | WRITES(fd,"("); 436 | generate_tyfields(fundec->tyfields); 437 | WRITES(fd,")"); 438 | generate_new_line(); 439 | WRITES(fd,"{"); 440 | nbimbr++; 441 | generate_new_line(); 442 | generate_exp(fundec->exp); 443 | nbimbr--; 444 | generate_new_line(); 445 | WRITES(fd,"}"); 446 | generate_new_line(); 447 | } 448 | 449 | void generate_tabdec(struct at_tabdec *tabdec) 450 | { 451 | char buff[64]; 452 | int len; 453 | 454 | if (!tabdec) 455 | return; 456 | 457 | generate_typeid(tabdec->idtype); 458 | write(fd,tabdec->idname,strlen(tabdec->idname)); 459 | WRITES(fd,"["); 460 | len = snprintf(buff,sizeof(buff),"%d",tabdec->size); 461 | write(fd,buff,len); 462 | WRITES(fd,"]"); 463 | 464 | switch(tabdec->e) 465 | { 466 | case AT_ENUM_TABDEC_AFFECT: 467 | WRITES(fd," = { "); 468 | generate_expitercomma(tabdec->u.expitercomma); 469 | WRITES(fd," }"); 470 | break; 471 | default: 472 | break; 473 | } 474 | WRITES(fd,";"); 475 | generate_new_line(); 476 | } 477 | 478 | void generate_tyfields(struct at_tyfields *tyfields) 479 | { 480 | if (!tyfields) 481 | return; 482 | 483 | while (tyfields->next) 484 | { 485 | generate_typeid(tyfields->idtype); 486 | write(fd,tyfields->idname,strlen(tyfields->idname)); 487 | WRITES(fd,","); 488 | tyfields = tyfields->next; 489 | } 490 | generate_typeid(tyfields->idtype); 491 | write(fd,tyfields->idname,strlen(tyfields->idname)); 492 | } 493 | 494 | void generate_typeid(enum at_enum_typeid idtype) 495 | { 496 | switch(idtype) 497 | { 498 | case AT_TID_INT: 499 | WRITES(fd,"int "); 500 | break; 501 | case AT_TID_REAL: 502 | WRITES(fd,"float "); 503 | break; 504 | case AT_TID_STRING: 505 | WRITES(fd,"char *"); 506 | break; 507 | default: 508 | break; 509 | } 510 | } 511 | -------------------------------------------------------------------------------- /generator.h: -------------------------------------------------------------------------------- 1 | #ifndef _GENERATOR_H 2 | #define _GENERATOR_H 3 | 4 | #include "abstract_tree.h" 5 | 6 | #define GEN_INDENT " " 7 | 8 | #define GEN_BINARY_EXP(ST,OPS) \ 9 | generate_exp((ST)->expl); \ 10 | WRITES(fd,OPS); \ 11 | generate_exp((ST)->expr); 12 | 13 | 14 | void generate_new_line(); 15 | void generate(struct at_exp *exp); 16 | void generate_exp(struct at_exp *exp); 17 | void generate_expitersemic(struct at_expitersemic *expitersemic); 18 | void generate_intval(struct at_intval *intval); 19 | void generate_realval(struct at_realval *realval); 20 | void generate_stringval(struct at_stringval *stringval); 21 | void generate_neg(struct at_neg *neg); 22 | void generate_plus(struct at_plus *plus); 23 | void generate_minus(struct at_minus *minus); 24 | void generate_multiply(struct at_multiply *multiply); 25 | void generate_divide(struct at_divide *divide); 26 | void generate_equals(struct at_equals *equals); 27 | void generate_ge(struct at_ge *ge); 28 | void generate_le(struct at_le *le); 29 | void generate_different(struct at_different *different); 30 | void generate_gt(struct at_gt *gt); 31 | void generate_lt(struct at_lt *lt); 32 | void generate_and(struct at_and *and); 33 | void generate_or(struct at_or *or); 34 | void generate_lvalue(struct at_lvalue *lvalue); 35 | void generate_affect(struct at_affect *affect); 36 | void generate_ift(struct at_if *ift); 37 | void generate_ifelse(struct at_ifelse *ifelse); 38 | void generate_whiled(struct at_while *whiled); 39 | void generate_ford(struct at_for *ford); 40 | void generate_expitercomma(struct at_expitercomma *expitercomma); 41 | void generate_expiterid(struct at_expiterid *expiterid); 42 | void generate_let(struct at_let *let); 43 | void generate_decs(struct at_decs *decs); 44 | void generate_dec(struct at_dec *dec); 45 | void generate_vardec(struct at_vardec *vardec); 46 | void generate_fundec(struct at_fundec *fundec); 47 | void generate_tabdec(struct at_tabdec *tabdec); 48 | void generate_tyfields(struct at_tyfields *tyfields); 49 | void generate_typeid(enum at_enum_typeid idtype); 50 | 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /hashtable.c: -------------------------------------------------------------------------------- 1 | #include "hashtable.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "math_tools.h" 8 | #include "compiler.h" 9 | 10 | struct hashtable *hashtable_init(int size) 11 | { 12 | struct hashtable *end; 13 | end = (struct hashtable *) malloc(sizeof(struct hashtable)); 14 | end->size = size; 15 | end->cells = (struct cell **) malloc(size*sizeof(struct cell *)); 16 | memset((char *)end->cells,0,size*sizeof(struct cell *)); 17 | return end; 18 | } 19 | 20 | unsigned int hashtable_hash(char *str) 21 | { 22 | unsigned int end; 23 | end = 0; 24 | while (*str) 25 | { 26 | end = (*str * *str) + end; 27 | str++; 28 | } 29 | return end; 30 | } 31 | 32 | struct cell *hashtable_lookup(struct hashtable *t, char *key, struct hashtable_value **value) 33 | { 34 | struct cell *end,*c; 35 | 36 | c = *(t->cells + (hashtable_hash(key) % t->size)); 37 | end = 0; 38 | while ((c) && (!end)) 39 | { 40 | if (!strcmp(c->key,key)) 41 | end = c; 42 | else 43 | c = c->next; 44 | } 45 | if ((end) && (value)) 46 | *value = c->value; 47 | return end; 48 | } 49 | 50 | void hashtable_delete(struct hashtable *t) 51 | { 52 | int i; 53 | struct cell *ptr,*tmpptr; 54 | i = 0; 55 | while (i < t->size) 56 | { 57 | ptr = *(t->cells + i++); 58 | while (ptr) 59 | { 60 | hashtable_value_free(ptr->value); 61 | free(ptr->key); 62 | tmpptr = ptr->next; 63 | free(ptr); 64 | ptr = tmpptr; 65 | } 66 | } 67 | free(t->cells); 68 | free(t); 69 | } 70 | 71 | struct hashtable *hashtable_add(struct hashtable *t, char *key, struct hashtable_value *value) 72 | { 73 | struct cell **table,*newcell; 74 | int len; 75 | 76 | table = (t->cells + (hashtable_hash(key) % t->size)); 77 | newcell = (struct cell *) malloc(sizeof(struct cell)); 78 | len = strlen(key) + 1; 79 | 80 | newcell->key = (char *) malloc(len*sizeof(char)); 81 | memcpy(newcell->key,key,len); 82 | /* newcell->key[len] = 0; */ 83 | newcell->value = value; 84 | 85 | newcell->next = *table; 86 | *table = newcell; 87 | 88 | return t; 89 | } 90 | 91 | void hashtable_value_free(struct hashtable_value *val) 92 | { 93 | /* to be changed if more types */ 94 | hashtable_err_value_free(val); 95 | /* 96 | switch (val->type) 97 | { 98 | case HSH_TYPE_ERR : 99 | hashtable_err_value_free(val); 100 | break; 101 | } 102 | */ 103 | } 104 | 105 | struct hashtable_value *hashtable_err_value_init(enum err_id id, enum err_state st, char *msg, void (*func_err)(int)) 106 | { 107 | struct hashtable_value *end; 108 | 109 | end = (struct hashtable_value *) malloc(sizeof(struct hashtable_value)); 110 | end->u.err = (struct hashtable_err_value *) malloc(sizeof(struct hashtable_err_value)); 111 | end->u.err->id = id; 112 | end->u.err->state = st; 113 | end->u.err->msg = msg; 114 | end->u.err->func = func_err; 115 | 116 | return end; 117 | } 118 | 119 | void hashtable_err_value_free(struct hashtable_value *val) 120 | { 121 | free(val->u.err); 122 | free(val); 123 | } 124 | 125 | struct hashtable_err_value *hashtable_err_lookup(struct hashtable *t, enum err_id id) 126 | { 127 | struct hashtable_value *val; 128 | 129 | __extension__ char key[my_itoa_buffer_size(id,10)]; 130 | my_itoa(id,10,key); 131 | if (hashtable_lookup(t,key,&val)) 132 | return val->u.err; 133 | else 134 | return 0; 135 | } 136 | 137 | -------------------------------------------------------------------------------- /hashtable.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2006, 2007 Sarzyniec Luc 2 | * This software is released under GNU/GPL the license 3 | * see the COPYING file for more informations */ 4 | 5 | #ifndef _HASHTABLE_H 6 | #define _HASHTABLE_H 7 | 8 | #include "../parse_options.h" 9 | #include "../network/protocols.h" 10 | 11 | enum hashtable_type 12 | { 13 | HSH_TYPE_ERR 14 | }; 15 | 16 | struct hashtable_value 17 | { 18 | union hashtable_union 19 | { 20 | struct hashtable_err_value *err; 21 | } u; 22 | enum hashtable_type type; 23 | }; 24 | 25 | struct cell 26 | { 27 | char *key; 28 | struct hashtable_value *value; 29 | struct cell *next; 30 | }; 31 | 32 | struct hashtable 33 | { 34 | int size; 35 | struct cell **cells; 36 | }; 37 | 38 | struct hashtable *hashtable_init(int size); 39 | unsigned int hashtable_hash(char *str); 40 | struct cell *hashtable_lookup(struct hashtable *t, char *key, struct hashtable_value **value); 41 | struct hashtable *hashtable_add(struct hashtable *t, char *key, struct hashtable_value *value); 42 | void hashtable_delete(struct hashtable *t); 43 | void hashtable_value_free(struct hashtable_value *val); 44 | 45 | #include "../error.h" 46 | struct hashtable_value *hashtable_err_value_init(enum err_id , enum err_state, char *,void (*func_err)(int)); 47 | void hashtable_err_value_free(struct hashtable_value *val); 48 | struct hashtable_err_value *hashtable_err_lookup(struct hashtable *, enum err_id); 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /linked_list.c: -------------------------------------------------------------------------------- 1 | /* This file is a part of groinc 2 | * 3 | * Copyright (C) 2006, 2007 Sarzyniec Luc 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * see the COPYING file for more informations */ 19 | 20 | #include "linked_list.h" 21 | #include 22 | #include 23 | 24 | struct linked_list *linked_list_init() 25 | { 26 | struct linked_list *end; 27 | end = (struct linked_list *) malloc(sizeof(struct linked_list)); 28 | end->next = 0; 29 | end->value = 0; 30 | return end; 31 | } 32 | 33 | void linked_list_free(struct linked_list *l) 34 | { 35 | struct linked_list *ptr; 36 | ptr = l; 37 | while (l) 38 | { 39 | ptr = l; 40 | l = l->next; 41 | linked_list_value_free(ptr->value); 42 | free(ptr); 43 | } 44 | } 45 | 46 | struct linked_list_value *linked_list_add(struct linked_list *l,struct linked_list_value *val) 47 | { 48 | if (l->value) 49 | { 50 | struct linked_list *ptr; 51 | ptr = l; 52 | while (l->next) 53 | l = l->next; 54 | l->next = linked_list_init(); 55 | l = l->next; 56 | } 57 | l->value = val; 58 | return val; 59 | } 60 | 61 | struct linked_list_value *linked_list_err_value_init(enum err_id id, char *arg) 62 | { 63 | struct linked_list_value *end; 64 | 65 | end = (struct linked_list_value *) malloc(sizeof(struct linked_list_value)); 66 | end->type = LKD_TYPE_ERR; 67 | 68 | end->u.err = (struct linked_list_err_value *) malloc(sizeof(struct linked_list_err_value)); 69 | end->u.err->id = id; 70 | end->u.err->arg = arg; 71 | 72 | return end; 73 | } 74 | 75 | void linked_list_err_value_free(struct linked_list_value *val) 76 | { 77 | free(val->u.err); 78 | free(val); 79 | } 80 | 81 | void linked_list_value_free(struct linked_list_value *val) 82 | { 83 | if (val) 84 | { 85 | switch (val->type) 86 | { 87 | case LKD_TYPE_ERR : 88 | linked_list_err_value_free(val); 89 | break; 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /linked_list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2006, 2007 Sarzyniec Luc 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | * see the COPYING file for more informations */ 18 | 19 | #ifndef _LINKED_LIST_H 20 | #define _LINKED_LIST_H 21 | 22 | #include 23 | 24 | #include "../network/headers.h" 25 | 26 | enum linked_list_type 27 | { 28 | LKD_TYPE_ERR 29 | }; 30 | 31 | struct linked_list_value 32 | { 33 | union linked_list_union 34 | { 35 | struct linked_list_err_value *err; 36 | } u; 37 | enum linked_list_type type; 38 | }; 39 | 40 | 41 | struct linked_list 42 | { 43 | struct linked_list_value *value; 44 | struct linked_list *next; 45 | }; 46 | 47 | 48 | struct linked_list *linked_list_init(); 49 | void linked_list_free(struct linked_list *); 50 | struct linked_list_value *linked_list_add(struct linked_list *,struct linked_list_value *); 51 | void linked_list_value_free(struct linked_list_value *); 52 | 53 | #include "../error.h" 54 | struct linked_list_value *linked_list_err_value_init(enum err_id, char *); 55 | void linked_list_err_value_free(struct linked_list_value *val); 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /math_tools.c: -------------------------------------------------------------------------------- 1 | /* This file is a part of groinc 2 | * 3 | * Copyright (C) 2006, 2007 Sarzyniec Luc 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * see the COPYING file for more informations */ 19 | 20 | #include "math_tools.h" 21 | 22 | #include 23 | 24 | static const char *lbase = { "0123456789abcdefghijklmnopqrstuvwxyz" }; 25 | static const char *ubase = { "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" }; 26 | static const char nbase = 36; 27 | 28 | int my_ctoi(char c) 29 | { 30 | char end = -1; 31 | char *ptr,*base; 32 | base = (char *) lbase; 33 | ptr = base; 34 | while((*ptr) && (*ptr != c)) 35 | ptr++; 36 | 37 | if (!*ptr) 38 | { 39 | base = (char *) ubase; 40 | ptr = base; 41 | while ((*ptr) && (*ptr != c)) 42 | ptr++; 43 | } 44 | 45 | if (*ptr) 46 | { 47 | end = ptr - base; 48 | } 49 | 50 | return end; 51 | } 52 | 53 | char my_itoc(unsigned int number) 54 | { 55 | return ubase[number % nbase]; 56 | } 57 | 58 | unsigned int my_pow(unsigned int n, unsigned int p) 59 | { 60 | unsigned int end; 61 | end = 1; 62 | /* WARNING : risk of overflow */ 63 | while (p > 0) 64 | { 65 | if (p % 2) 66 | { 67 | p--; 68 | end = end * n; 69 | } 70 | p >>= 1; 71 | n *= n; 72 | } 73 | return end; 74 | } 75 | 76 | /* The size needed to store a number as a string (counting the ending '\0') */ 77 | unsigned int my_itoa_buffer_size(unsigned int number, unsigned char base) 78 | { 79 | unsigned int end,pow; 80 | 81 | end = 1; 82 | pow = 1; 83 | 84 | /* getting the order of the number */ 85 | while (pow * base <= number) 86 | { 87 | end++; 88 | pow = pow * base; 89 | } 90 | 91 | return end + 1; 92 | } 93 | 94 | char *my_itoa(unsigned int number, unsigned char base, char *buff) 95 | { 96 | unsigned int order,tmp,pow; 97 | 98 | order = 1; 99 | tmp = number; 100 | pow = 1; 101 | 102 | /* getting the order of the number */ 103 | while (pow * base <= number) 104 | { 105 | order++; 106 | pow = pow * base; 107 | } 108 | 109 | /* initialize the returned string */ 110 | buff[order] = 0; 111 | 112 | /* reuse of the variable order */ 113 | order = 0; 114 | 115 | while(pow) 116 | { 117 | tmp = number / pow; 118 | buff[order++] = my_itoc(tmp); 119 | number = number - (tmp * pow); 120 | pow /= base; 121 | } 122 | return buff; 123 | } 124 | 125 | /* The size needed to store the addicted chars to store a number as a string (you need first use my_itoa_buffer_size) */ 126 | unsigned int my_itoa_char_char_size(unsigned int number, unsigned char nbc,unsigned char base) 127 | { 128 | int len; 129 | 130 | if ((len = (my_itoa_buffer_size(number,base) - 1)) < nbc) 131 | nbc = nbc - len; 132 | else 133 | nbc = 0; 134 | return nbc; 135 | } 136 | 137 | char *my_itoa_char(unsigned int number, unsigned char nbc,unsigned char base, char c, char *buff) 138 | { 139 | unsigned int len; 140 | 141 | if ((len = my_itoa_char_char_size(number,nbc,base))) 142 | memset(buff,c,len); 143 | my_itoa(number,base,(buff + len)); 144 | 145 | return buff; 146 | } 147 | 148 | int my_atoi(char *str, unsigned char base) 149 | { 150 | int end,nb,pow; 151 | nb = 0; 152 | 153 | while ((*str) && (my_ctoi(*str) >= 0)) 154 | { nb++; 155 | str++; 156 | } 157 | 158 | pow = 1; 159 | end = 0; 160 | while (nb--) 161 | { 162 | end = end + ((my_ctoi(*--str) % base) * pow); 163 | pow *= base; 164 | } 165 | return end; 166 | } 167 | 168 | int my_atoi_len(char *str, unsigned int len, unsigned char base) 169 | { 170 | int end,nb,pow; 171 | 172 | nb = len; 173 | while ((*str) && (my_ctoi(*str) >= 0)) 174 | { 175 | str++; 176 | len--; 177 | } 178 | nb = nb - len; 179 | pow = 1; 180 | end = 0; 181 | while (nb--) 182 | { 183 | end = end + ((my_ctoi(*--str) % base) * pow); 184 | pow *= base; 185 | } 186 | return end; 187 | } 188 | 189 | -------------------------------------------------------------------------------- /symbols_table.c: -------------------------------------------------------------------------------- 1 | #include "symbols_table.h" 2 | #include /* malloc */ 3 | #include /* strcmp */ 4 | 5 | static int global_num = 0; 6 | 7 | struct st_node * 8 | st_node_init(struct st_node *parent) 9 | { 10 | struct st_node *ret, *ptr; 11 | 12 | ret = (__typeof__(ret)) malloc(sizeof(ret)); 13 | ret->num = global_num++; 14 | ret->parent = parent; 15 | ret->siblings = 0; 16 | 17 | if (parent) 18 | { 19 | if (parent->childs) 20 | { 21 | ptr = parent->childs; 22 | while (ptr->siblings) 23 | ptr = ptr->siblings; 24 | ptr->siblings = ret; 25 | } 26 | else 27 | parent->childs = ret; 28 | } 29 | 30 | ret->childs = 0; 31 | ret->entries = 0; 32 | 33 | return ret; 34 | } 35 | /* 36 | struct st_node * 37 | st_node_child_add( 38 | struct st_node *node, 39 | struct st_node *child) 40 | { 41 | __typeof__(node) childs; 42 | childs = node->childs; 43 | 44 | child->parent = node; 45 | 46 | while (childs->childs) 47 | { 48 | if (childs == child) 49 | return; 50 | childs = childs->next; 51 | } 52 | childs->next = child; 53 | } 54 | 55 | struct st_node * 56 | st_node_child_remove( 57 | struct st_node *node, 58 | struct st_node *child) 59 | { 60 | __typeof__(node) childs, prec; 61 | childs = node->childs; 62 | 63 | child->parent = node; 64 | 65 | while ((childs != child) && (childs->next)) 66 | { 67 | prec = childs; 68 | childs = childs->next; 69 | } 70 | 71 | if (childs == child) 72 | prec->next = childs->next; 73 | } 74 | */ 75 | 76 | void 77 | st_node_free(struct st_node *node) 78 | { 79 | __typeof__(node) ptr, ptr2; 80 | 81 | if (!node) 82 | return; 83 | 84 | st_entries_free(node->entries); 85 | 86 | ptr = node->childs; 87 | 88 | while (ptr) 89 | { 90 | ptr2 = ptr->siblings; 91 | st_node_free(ptr); 92 | ptr = ptr2; 93 | } 94 | 95 | free(node); 96 | } 97 | 98 | struct st_node * 99 | st_node_add_entry( 100 | struct st_node *node, 101 | struct st_entry *entry) 102 | { 103 | if (node->entries) 104 | { 105 | __typeof(node->entries) ptr; 106 | ptr = node->entries; 107 | while (ptr->next) 108 | ptr = ptr->next; 109 | ptr->next = entry; 110 | } 111 | else 112 | node->entries = entry; 113 | 114 | return node; 115 | } 116 | 117 | void 118 | st_entries_free(struct st_entry *entry) 119 | { 120 | if (!entry) 121 | return; 122 | 123 | free(entry->name); 124 | 125 | if (entry->next) 126 | st_entries_free(entry->next); 127 | 128 | free(entry); 129 | } 130 | 131 | struct st_entry * 132 | st_entry_init( 133 | char *name, 134 | enum st_enum_type type) 135 | { 136 | struct st_entry *ret; 137 | ret = (__typeof__(ret)) malloc(sizeof(ret)); 138 | 139 | ret->name = name; 140 | ret->type = type; 141 | ret->next = 0; 142 | 143 | return ret; 144 | } 145 | 146 | /* return the first hierarchical entry */ 147 | struct st_entry * 148 | st_node_lookup_entry( 149 | struct st_node *node, 150 | char *name) 151 | { 152 | __typeof__(node) ptrn; 153 | struct st_entry *ptre, *ret; 154 | 155 | ret = 0; 156 | ptrn = node; 157 | 158 | while ((!ret) && (ptrn)) 159 | { 160 | ptre = ptrn->entries; 161 | while ((!ret) && (ptre)) 162 | { 163 | if (!strcmp(ptre->name,name)) 164 | ret = ptre; 165 | else 166 | ptre = ptre->next; 167 | } 168 | ptrn = ptrn->parent; 169 | } 170 | 171 | return ret; 172 | } 173 | -------------------------------------------------------------------------------- /symbols_table.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYMBOLS_TABLE_H 2 | #define _SYMBOLS_TABLE_H 3 | 4 | enum st_enum_type 5 | { 6 | ST_ENUM_TYPE_VAR, 7 | ST_ENUM_TYPE_FUNC, 8 | ST_ENUM_TYPE_TAB 9 | }; 10 | 11 | struct st_entry 12 | { 13 | char *name; 14 | enum st_enum_type type; 15 | struct st_entry *next; 16 | }; 17 | 18 | struct st_node 19 | { 20 | struct st_entry *entries; 21 | int num; 22 | struct st_node *parent; 23 | struct st_node *childs; 24 | struct st_node *siblings; 25 | }; 26 | 27 | 28 | struct st_node *st_node_init(struct st_node *parent); 29 | void st_node_free(struct st_node *node); 30 | struct st_node *st_node_add_entry(struct st_node *node, struct st_entry *entry); 31 | void st_entries_free(struct st_entry *entry); 32 | struct st_entry *st_entry_init(char *name, enum st_enum_type type); 33 | struct st_entry *st_node_lookup_entry(struct st_node *node, char *name); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /test.prout: -------------------------------------------------------------------------------- 1 | let 2 | var i : int := 0 3 | function fibo( a : int ) : int = 4 | if a = 0 5 | then 0 6 | else if a = 1 7 | then 1 8 | else (fibo(a-2) + fibo(a-1)) 9 | in 10 | (let 11 | var z : int := 1 12 | in 13 | printi(i) 14 | end) 15 | ; 16 | 17 | (while i <= 10 do 18 | (printi(fibo(i)); 19 | prints("\t"); 20 | i := i+1) 21 | ) 22 | end 23 | 24 | --------------------------------------------------------------------------------