static struct vector *decls(declfun_p * dcl) { struct vector *v = vec_new(); node_t *basety; int sclass, fspec; int level = SCOPE; int follow[] = {STATIC, INT, CONST, IF, '}', 0}; basety = specifiers(&sclass, &fspec); if (token->id == ID || token->id == '*' || token->id == '(') { struct token *id = NULL; node_t *ty = NULL; int params = 0; // for functioness // declarator if (level == GLOBAL) declarator(&ty, &id, ¶ms); else declarator(&ty, &id, NULL); attach_type(&ty, basety); if (level == GLOBAL && params) { if (first_funcdef(ty)) { vec_push(v, funcdef(id, ty, sclass, fspec)); return v; } else { exit_params(); } } for (;;) { if (id) { int kind; if (dcl == globaldecl) kind = GLOBAL; else if (dcl == paramdecl) kind = PARAM; else kind = LOCAL; node_t *decl = make_decl(id, ty, sclass, fspec, dcl); if (token->id == '=') decl_initializer(decl, sclass, kind); ensure_decl(decl, sclass, kind); vec_push(v, decl); } if (token->id != ',') break; expect(','); id = NULL; ty = NULL; // declarator declarator(&ty, &id, NULL); attach_type(&ty, basety); } } else if (isenum(basety) || isstruct(basety) || isunion(basety)) { // struct/union/enum int node_id; node_t *decl; if (isstruct(basety)) node_id = STRUCT_DECL; else if (isunion(basety)) node_id = UNION_DECL; else node_id = ENUM_DECL; decl = ast_decl(node_id); DECL_SYM(decl) = TYPE_TSYM(basety); vec_push(v, decl); } else { error("invalid token '%s' in declaration", token->name); } match(';', follow); return v; }
/** Initialize the Express package. */ void EXPRESSinitialize( void ) { Function func_abs, func_acos, func_asin, func_atan, func_blength, func_cos, func_exists, func_exp, func_format, func_hibound, func_hiindex, func_length, func_lobound, func_log, func_log10, func_log2, func_loindex, func_odd, func_rolesof, func_sin, func_sizeof, func_sqrt, func_tan, func_typeof, func_value, func_value_in, func_value_unique; Procedure proc_insert, proc_remove; _MEMinitialize(); ERRORinitialize(); OBJinitialize(); HASHinitialize(); /* comes first - used by just about everything else! */ DICTinitialize(); LISTinitialize(); /* ditto */ ERRORinitialize_after_LIST(); STACKinitialize(); PASSinitialize(); RESOLVEinitialize(); SYMBOLinitialize(); SCOPEinitialize(); TYPEinitialize(); /* cannot come before SCOPEinitialize */ VARinitialize(); ALGinitialize(); ENTITYinitialize(); SCHEMAinitialize(); CASE_ITinitialize(); EXPinitialize(); /* LOOP_CTLinitialize();*/ STMTinitialize(); SCANinitialize(); EXPRESSbuiltins = DICTcreate( 35 ); #define funcdef(x,y,c,r) \ x = ALGcreate(OBJ_FUNCTION);\ x->symbol.name = y;\ x->u.func->pcount = c; \ x->u.func->return_type = r; \ x->u.func->builtin = true; \ resolved_all(x); \ DICTdefine(EXPRESSbuiltins,y,(Generic)x,0,OBJ_FUNCTION); #define procdef(x,y,c) x = ALGcreate(OBJ_PROCEDURE);\ x->symbol.name = y;\ x->u.proc->pcount = c; \ x->u.proc->builtin = true; \ resolved_all(x); \ DICTdefine(EXPRESSbuiltins,y,(Generic)x,0,OBJ_PROCEDURE); /* third arg is # of parameters */ /* eventually everything should be data-driven, but for now */ /* uppercase def's are global to allow passing necessary information */ /* into resolver */ procdef( proc_insert, KW_INSERT, 3 ); procdef( proc_remove, KW_REMOVE, 2 ); funcdef( func_abs, KW_ABS, 1, Type_Number ); funcdef( func_acos, KW_ACOS, 1, Type_Real ); funcdef( func_asin, KW_ASIN, 1, Type_Real ); funcdef( func_atan, KW_ATAN, 2, Type_Real ); funcdef( func_blength, KW_BLENGTH, 1, Type_Integer ); funcdef( func_cos, KW_COS, 1, Type_Real ); funcdef( func_exists, KW_EXISTS, 1, Type_Boolean ); funcdef( func_exp, KW_EXP, 1, Type_Real ); funcdef( func_format, KW_FORMAT, 2, Type_String ); funcdef( func_hibound, KW_HIBOUND, 1, Type_Integer ); funcdef( func_hiindex, KW_HIINDEX, 1, Type_Integer ); funcdef( func_length, KW_LENGTH, 1, Type_Integer ); funcdef( func_lobound, KW_LOBOUND, 1, Type_Integer ); funcdef( func_log, KW_LOG, 1, Type_Real ); funcdef( func_log10, KW_LOG10, 1, Type_Real ); funcdef( func_log2, KW_LOG2, 1, Type_Real ); funcdef( func_loindex, KW_LOINDEX, 1, Type_Integer ); funcdef( FUNC_NVL, KW_NVL, 2, Type_Generic ); funcdef( func_odd, KW_ODD, 1, Type_Logical ); funcdef( func_rolesof, KW_ROLESOF, 1, Type_Set_Of_String ); funcdef( func_sin, KW_SIN, 1, Type_Real ); funcdef( func_sizeof, KW_SIZEOF, 1, Type_Integer ); funcdef( func_sqrt, KW_SQRT, 1, Type_Real ); funcdef( func_tan, KW_TAN, 1, Type_Real ); funcdef( func_typeof, KW_TYPEOF, 1, Type_Set_Of_String ); funcdef( FUNC_USEDIN, KW_USEDIN, 2, Type_Bag_Of_Generic ); funcdef( func_value, KW_VALUE, 1, Type_Number ); funcdef( func_value_in, KW_VALUE_IN, 2, Type_Logical ); funcdef( func_value_unique, KW_VALUE_UNIQUE, 1, Type_Logical ); ERROR_bail_out = ERRORcreate( "Aborting due to internal error(s)", SEVERITY_DUMP ); ERROR_syntax = ERRORcreate( "%s in %s %s", SEVERITY_EXIT ); /* i.e., "syntax error in procedure foo" */ ERROR_ref_nonexistent = ERRORcreate( "USE/REF of non-existent object (%s in schema %s)", SEVERITY_ERROR ); ERROR_tilde_expansion_failed = ERRORcreate( "Tilde expansion for %s failed in EXPRESS_PATH environment variable", SEVERITY_ERROR ); ERROR_schema_not_in_own_schema_file = ERRORcreate( "Schema %s was not found in its own schema file (%s)", SEVERITY_ERROR ); ERROR_unlabelled_param_type = ERRORcreate( "Return type or local variable requires type label in `%s'", SEVERITY_ERROR ); ERROR_file_unreadable = ERRORcreate( "Could not read file %s: %s", SEVERITY_ERROR ); ERROR_file_unwriteable = ERRORcreate( "Could not write file %s: %s", SEVERITY_ERROR ); ERROR_warn_unsupported_lang_feat = ERRORcreate("Unsupported language feature (%s) at %s:%d",SEVERITY_WARNING); OBJcreate( OBJ_EXPRESS, EXPRESS_get_symbol, "express file", OBJ_UNUSED_BITS ); ERRORcreate_warning( "unknown_subtype", ERROR_unknown_subtype ); ERRORcreate_warning( "unsupported", ERROR_warn_unsupported_lang_feat ); EXPRESS_PATHinit(); /* note, must follow defn of errors it needs! */ }
void program(){ symbol_t t = 0, id = 0; nextSym(); if(sym->type == CONST){ nextSym(); constant(); } if(isType(sym)){ do{ t = copySym(sym); nextSym(); if(sym->type==MAIN){ nextSym(); mainfunc(t); mfree(t); break; } if(sym->type != ID){ msg(ERR, "missing a identifier after a type name", line); ERROR_STATUS = 1; do nextSym(); while(sym->type != ID && sym->type != SEMIC && sym->type != SEOF); if(sym->type == SEOF) break; if(sym->type == SEMIC){ nextSym(); continue; } } id = copySym(sym); nextSym(); if(sym->type == LPAREN)break; variable(t, id); mfree(t); }while(isType(sym) || sym->type == VOID); }else if(sym->type==VOID){ t = copySym(sym); nextSym(); if(sym->type==MAIN){ nextSym(); mainfunc(t); mfree(t); }else{ if(sym->type != ID){ msg(ERR, "missing a identifier after a type name", line); ERROR_STATUS = 1; do nextSym(); while(sym->type != ID && sym->type !=SEOF); }else{ id = copySym(sym); nextSym(); if(sym->type!=LPAREN){ msg(ERR, "missing \'(\'", line); ERROR_STATUS = 1; // something } } } } while(sym->type==LPAREN){ nextSym(); funcdef(t, id); mfree(t);mfree(id); if(!(isType(sym)||sym->type==VOID))break; t = copySym(sym); nextSym(); if(sym->type==MAIN){ nextSym(); mainfunc(t); mfree(t); break; } if(sym->type!=ID){ msg(ERR, "missing a identifier after a type name", line); ERROR_STATUS = 1; do nextSym(); while(sym->type != ID && sym->type !=SEOF); if(sym->type == SEOF) break; } id = copySym(sym); nextSym(); } if(sym->type!=SEOF){ ERROR_STATUS = 1; msg(MSG, "Error occured!", 0); } }