/* Copyleft 2002, Tero Tilus * * $Id: ejsc_parser.y,v 1.8 2002/07/09 14:11:39 terotil Exp $ * * This file is part of ejscc, a program to compile Extended Java * Sketchpad Constructions to ordinary syntax. * * Ejscc is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Ejscc is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ %token NAME %token STRING %token COMMENT %token INT %token FLOAT %token BEGIN_BLOCK END_BLOCK %{ #define MAXVARS 16 #define MAXARGLISTS 8 #define MAXSYMS 300 /* Keep up with linenumbers */ int yylineno=1; /* Index constructions to generate evalIds */ int evalIndex=0; /* Error "handling" */ int yyerror(char *s) { fprintf(stderr, "%s\n", s); fflush(stderr); return 0; } /* Get first non-null index in tVariable array */ int first_null_index(tVariable *vp) { int i; for (i=0 ; i1); (*($1)).scope = (*currentSym).symTable[i]; /* In case of function definition, fix name */ if ( ((*((*currentSym).symTable[i])).symTSize != 0) && ((*(*((*currentSym).symTable[i])).symValue).type == tOb) ) { // free((*currentSym).symTable[i].symName); (*((*currentSym).symTable[i])).symName = (*(*((*currentSym).symTable[i])).symValue).value.o.objName; } #ifdef EJSCCDEBUG if ( ejsccdebug ) { printf("ejsccdebug: Assigned to '%s'.\n", name); fflush(stdout); } #endif } | NAME '=' attribute ';' { int i; i = append_symbol_to_current($1, $3); (*($3)).scope = (*currentSym).symTable[i]; #ifdef EJSCCDEBUG if ( ejsccdebug ) { printf("ejsccdebug: Assigned to '%s'.\n", $1); fflush(stdout); } #endif } | COMMENT ; maybecomment: COMMENT | ; construction_object: NAME attributes formats codeblock { tVariable *val; int ***tmp_eval; int i,j,k; /* Allocate memory */ val = (tVariable *)malloc(sizeof(tVariable)); /* Create construction object */ (*val).type = tOb; (*val).evalId = evalIndex; evalIndex += EVALIDSTEP; // Unique id (*val).value.o.objName = $1; // Name /* Allocate memory for return values and reset them */ (*val).value.o.returnValues = (char **)malloc(MAXSYMS * sizeof(char *)); memset((*val).value.o.returnValues, (int)NULL, MAXSYMS * sizeof(char *)); /* Decide type. Existing codeblock means definition */ if ( $4 == true ) { (*val).value.o.type = Definition; } else { (*val).value.o.type = Object; } /* Evaluation id's to keep track on the need of re-evaluation of arguments */ (*val).value.o.arguments = $2; /* Argument list */ tmp_eval = (*val).value.o.argumentEvalId = (int ***)malloc(MAXARGLISTS * sizeof(int **)); for ( i=0 ; i3; /* Format list */ (*tmp_eval) = (*val).value.o.formatEvalId = (int **)malloc(MAXARGLISTS * sizeof(int *)); for ( i=0 ; i$ = val; #ifdef EJSCCDEBUG if ( ejsccdebug ) { printf("ejsccdebug: Found %s.\n", get_name(val)); fflush(stdout); } #endif } ; attributes: attributes '(' attributelist ')' { int i = first_null_index_($1); #ifdef EJSCCDEBUG if ( ejsccdebug ) { printf("ejsccdebug: Yet another argument list found.\n"); fflush(stdout); } #endif if ( i > MAXARGLISTS-1 ) { /* FIXME: realloc */ yyerror("Error. Too many attributelists.\n"); } else { $$ = $1; $$[i] = $3; } } | '(' attributelist ')' { int size = MAXARGLISTS; int i; #ifdef EJSCCDEBUG if ( ejsccdebug ) { printf("ejsccdebug: Argument list found.\n"); fflush(stdout); } #endif $$ = (tVariable **)malloc(size * sizeof(tVariable *)); for (i=0 ; i$[i++]=NULL); $$[0] = $2; } ; attributelist: attributelist ',' attribute { int i = first_null_index($1); if ( i > MAXVARS-1 ) { /* FIXME: realloc */ yyerror("Error. Too many attributes.\n"); } else { $$ = $1; $$[i] = (*($3)); } } | attribute { int size = MAXVARS; int i; $$ = (tVariable *)malloc(size * sizeof(tVariable)); /* Set all variables to 'nullVar' */ for (i=0 ; i$[i++]=nullVar); $$[0] = (*($1)); } | { $$ = NULL; } ; attribute: maybecomment simple_attribute maybecomment { $$ = $2; } | maybecomment construction_object maybecomment %prec COBJ_ATTR { $$ = $2; } ; simple_attribute: number { $$ = (tVariable*)malloc(sizeof(tVariable)); (*($$)) = $1; } | STRING { $$ = (tVariable*)malloc(sizeof(tVariable)); (*($$)) = $1; } | NAME { $$ = (tVariable*)malloc(sizeof(tVariable)); (*($$)) = $1; } formats: '[' formatlist ']' { #ifdef EJSCCDEBUG if ( ejsccdebug ) { printf("ejsccdebug: Format list found.\n"); fflush(stdout); } #endif $$ = $2; } | { $$ = NULL; } ; formatlist: formatlist ',' format { int i = first_null_index($1); if ( i > MAXVARS-1 ) { /* FIXME: realloc */ fprintf(stderr, "Fatal error: Too many formats on line %d.\n", yylineno); exit(1); } else { $$ = $1; $$[i] = (*($3)); } } | format { int size = MAXVARS; int i; $$ = (tVariable *)malloc(size * sizeof(tVariable)); /* Set all variables to 'nullVar' */ for (i=0 ; i$[i++]=nullVar); $$[0] = (*($1)); } ; format: maybecomment simple_attribute maybecomment { $$ = $2; } | maybecomment format_call maybecomment { /* $$ = (tVariable*)malloc(sizeof(tVariable)); (*($$)) = $2; */ $$ = &$2; } ; format_call: NAME '(' attributelist ')' { int ***tmp_eval; int i,j,k; #ifdef EJSCCDEBUG if ( ejsccdebug ) { printf("ejsccdebug: Format call '%s' found.\n", $1); fflush(stdout); } #endif $$ = tOb; $$ = $1; $$ = Format; /* Allocate memory for argument lists */ $$ = (tVariable**)malloc(2*sizeof(tVariable*)); $$[0] = $3; $$[1] = NULL; tmp_eval = $$ = (int ***)malloc(2 * sizeof(int **)); for ( i=0 ; i<2 ; i++ ) { tmp_eval[i] = (int **)malloc(MAXVARS * sizeof(int*)); for ( j=0 ; j$ = (char **)malloc(MAXSYMS * sizeof(char *)); memset($$, (int)NULL, MAXSYMS * sizeof(char *)); /* Formats don't have formats... */ $$ = NULL; $$ = NULL; $$ = currentSym; } ; codeblock: BEGIN_BLOCK ';' construction END_BLOCK { $$ = true; } | { $$ = false; } ; number: INT { $$ = $1; } | FLOAT { $$ = $1; } ; %% #include "ejsc_lexer.c"