/* l2xisymt.c LTX2X interpreter symbol table code */ /* BASED ON: symtab.c (common names altered) */ /* added PRINT and PRINTLN to init_symtab */ #include #include #include "l2xicmon.h" #include "l2xierr.h" #include "l2xisymt.h" #include "l2xiidbg.h" #include "l2xiexec.h" /* EXTERNALS */ extern int level; extern int DEBUG; /* GLOBALS */ SYMTAB_NODE_PTR symtab_display[MAX_NESTING_LEVEL]; TYPE_STRUCT_PTR integer_typep, real_typep, /* predefined types */ boolean_typep; TYPE_STRUCT_PTR logical_typep, string_typep, binary_typep, generic_typep, any_typep; SYMTAB_NODE_PTR false_idp, true_idp, unknown_idp; /* logical constants */ SYMTAB_NODE_PTR conste_idp, pi_idp; /* real constants */ SYMTAB_NODE_PTR undef_idp; /* `?' constant */ SYMTAB_NODE_PTR day_idp, month_idp, year_idp; SYMTAB_NODE_PTR string_idp; TYPE_STRUCT dummy_type = { /* for bad type defs */ NO_FORM, /* form */ 0, /* size */ NULL /* type id */ }; /***************************************************************************/ /* search_symtab(name, np) Search for a name in the symbol table. */ /* return pointer to entry if found, else NULL. */ SYMTAB_NODE_PTR search_symtab(name, np) char *name; /* name to look for */ SYMTAB_NODE_PTR np; /* pointer to symtab root */ { int cmp; entry_debug("search_symtab"); /* loop to check each node. If not found, continue down the left */ /* or right subtree. Return when a match */ while (np != NULL) { cmp = strcmp(name, np->name); if (cmp == 0) { /* got it */ exit_debug("search_symtab at found"); return(np); } np = cmp < 0 ? np->left : np->right; /* continue */ } exit_debug("search_symtab at not found"); return(NULL); /* not found */ } /* end search_symtab */ /***************************************************************************/ /***************************************************************************/ /* search_symtab_display(name) Search all the symbol tables in the */ /* symbol table display for a name. */ /* return the pointer to the entry if found, else NULL */ SYMTAB_NODE_PTR search_symtab_display(name) char *name; { short i; SYMTAB_NODE_PTR np; /* pointer to symbol table node */ entry_debug("search_symtab_display"); for (i = level; i >= 0; --i) { np =search_symtab(name, symtab_display[i]); if (np != NULL) { exit_debug("search_symtab_display at found"); return(np); } } exit_debug("search_symtab_display at not found"); return(NULL); } /* end search_symtab_display */ /***************************************************************************/ /***************************************************************************/ /* enter_symtab(name, npp) Enter a name into the symtab */ /* return pointer to the entry */ SYMTAB_NODE_PTR enter_symtab(name, npp) char *name; /* name to enter */ SYMTAB_NODE_PTR *npp; /* ptr to ptr to symtab root */ { int cmp; /* result of strcmp */ SYMTAB_NODE_PTR new_nodep; /* ptr to new entry */ SYMTAB_NODE_PTR np; /* ptr to node to test */ entry_debug("enter_symtab"); /* create the new node for name */ new_nodep = alloc_struct(SYMTAB_NODE); new_nodep->name = alloc_bytes(strlen(name) + 1); strcpy(new_nodep->name, name); new_nodep->left = new_nodep->right = new_nodep->next = NULL; new_nodep->info = NULL; new_nodep->defn.key = UNDEFINED; new_nodep->typep = NULL; new_nodep->level = level; new_nodep->label_index = 0; /* loop to find the insertion point (binary tree) */ while ((np = *npp) != NULL) { cmp = strcmp(name, np->name); npp = cmp < 0 ? &(np->left) : &(np->right); } *npp = new_nodep; /* replace */ exit_debug("enter_symtab"); return(new_nodep); } /* end enter_symtab */ /***************************************************************************/ /***************************************************************************/ /* init_symtab() Initialise the symtab with predefined identifiers, */ /* types, and routines */ init_symtab() /* ---------------------- in final */ { SYMTAB_NODE_PTR integer_idp, real_idp, boolean_idp; SYMTAB_NODE_PTR logical_idp, binary_idp, generic_idp, anytype_idp; int temp; time_t tp1, tp2; struct tm *ts; /* temporarily switch off any debugging output */ temp = DEBUG; DEBUG = 0; /* initialise the level 0 (the global?) symbol table */ symtab_display[0] = NULL; /* predefined Pascal types */ enter_name_local_symtab(integer_idp, "integer"); enter_name_local_symtab(real_idp, "real"); enter_name_local_symtab(boolean_idp, "boolean"); /* and extra EXPRESS types */ enter_name_local_symtab(logical_idp, "logical"); enter_name_local_symtab(string_idp, "string"); enter_name_local_symtab(binary_idp, "binary"); enter_name_local_symtab(generic_idp, "generic"); enter_name_local_symtab(anytype_idp, "???????"); integer_typep = alloc_struct(TYPE_STRUCT); real_typep = alloc_struct(TYPE_STRUCT); boolean_typep = alloc_struct(TYPE_STRUCT); logical_typep = alloc_struct(TYPE_STRUCT); string_typep = alloc_struct(TYPE_STRUCT); binary_typep = alloc_struct(TYPE_STRUCT); generic_typep = alloc_struct(TYPE_STRUCT); any_typep = alloc_struct(TYPE_STRUCT); integer_idp->defn.key = TYPE_DEFN; integer_idp->typep = integer_typep; integer_typep->form = SCALAR_FORM; integer_typep->size = sizeof(STACK_ITEM); integer_typep->type_idp = integer_idp; real_idp->defn.key = TYPE_DEFN; real_idp->typep = real_typep; real_typep->form = SCALAR_FORM; real_typep->size = sizeof(STACK_ITEM); real_typep->type_idp = real_idp; boolean_idp->defn.key = TYPE_DEFN; boolean_idp->typep = boolean_typep; boolean_typep->form = ENUM_FORM; boolean_typep->size = sizeof(STACK_ITEM); boolean_typep->type_idp = boolean_idp; boolean_typep->info.enumeration.max = 1; boolean_idp->typep->info.enumeration.const_idp = false_idp; logical_idp->defn.key = TYPE_DEFN; logical_idp->typep = boolean_typep; logical_typep->form = ENUM_FORM; logical_typep->size = sizeof(STACK_ITEM); logical_typep->type_idp = logical_idp; logical_typep->info.enumeration.max = 2; logical_idp->typep->info.enumeration.const_idp = unknown_idp; string_idp->defn.key = TYPE_DEFN; string_idp->typep = string_typep; string_typep->form = STRING_FORM; string_typep->size = sizeof(STACK_ITEM); string_typep->type_idp = string_idp; string_typep->info.string.max_length = MAX_EXPRESS_STRING; string_typep->info.string.length = 0; binary_idp->defn.key = TYPE_DEFN; binary_idp->typep = binary_typep; binary_typep->form = SCALAR_FORM; binary_typep->size = sizeof(STACK_ITEM); binary_typep->type_idp = binary_idp; generic_idp->defn.key = TYPE_DEFN; generic_idp->typep = generic_typep; generic_typep->form = SCALAR_FORM; generic_typep->size = sizeof(STACK_ITEM); generic_typep->type_idp = generic_idp; anytype_idp->defn.key = TYPE_DEFN; anytype_idp->typep = any_typep; any_typep->form = SCALAR_FORM; any_typep->size = sizeof(STACK_ITEM); any_typep->type_idp = anytype_idp; /* predefined constants */ enter_name_local_symtab(false_idp, "false"); enter_name_local_symtab(true_idp, "true"); enter_name_local_symtab(unknown_idp, "unknown"); enter_name_local_symtab(pi_idp, "pi"); enter_name_local_symtab(conste_idp, "const_e"); enter_name_local_symtab(undef_idp, "?"); enter_name_local_symtab(day_idp, "the_day"); enter_name_local_symtab(month_idp, "the_month"); enter_name_local_symtab(year_idp, "the_year"); false_idp->defn.key = CONST_DEFN; false_idp->defn.info.constant.value.integer = FALSE_REP; false_idp->typep = logical_typep; false_idp->next = unknown_idp; unknown_idp->defn.key = CONST_DEFN; unknown_idp->defn.info.constant.value.integer = UNKNOWN_REP; unknown_idp->typep = logical_typep; unknown_idp->next = true_idp; true_idp->defn.key = CONST_DEFN; true_idp->defn.info.constant.value.integer = TRUE_REP; true_idp->typep = logical_typep; pi_idp->defn.key = CONST_DEFN; pi_idp->typep = real_typep; pi_idp->defn.info.constant.value.real = 3.141592654; conste_idp->defn.key = CONST_DEFN; conste_idp->typep = real_typep; conste_idp->defn.info.constant.value.real = 2.718281828; undef_idp->defn.key = CONST_DEFN; undef_idp->typep = any_typep; undef_idp->defn.info.constant.value.character = '\?'; /* do the current date */ tp1 = time(&tp2); ts = localtime(&tp1); sprintf(dbuffer, "year = %d, month = %d, day = %d\n", (ts->tm_year+1900), (ts->tm_mon+1), (ts->tm_mday)); debug_print(dbuffer); day_idp->defn.key = CONST_DEFN; day_idp->typep = integer_typep; day_idp->defn.info.constant.value.integer = ts->tm_mday; month_idp->defn.key = CONST_DEFN; month_idp->typep = integer_typep; month_idp->defn.info.constant.value.integer = ts->tm_mon + 1; year_idp->defn.key = CONST_DEFN; year_idp->typep = integer_typep; year_idp->defn.info.constant.value.integer = ts->tm_year + 1900; /* standard routines */ enter_standard_routine("read", READ, PROC_DEFN); enter_standard_routine("readln", READLN, PROC_DEFN); enter_standard_routine("write", WRITE, PROC_DEFN); enter_standard_routine("writeln", WRITELN, PROC_DEFN); enter_standard_routine("abs", ABS, FUNC_DEFN); enter_standard_routine("cos", COS, FUNC_DEFN); enter_standard_routine("eof", EOFF, FUNC_DEFN); enter_standard_routine("eoln", EOLN, FUNC_DEFN); enter_standard_routine("exp", EXP, FUNC_DEFN); enter_standard_routine("odd", ODD, FUNC_DEFN); enter_standard_routine("round", ROUND, FUNC_DEFN); enter_standard_routine("sin", SIN, FUNC_DEFN); enter_standard_routine("sqrt", SQRT, FUNC_DEFN); enter_standard_routine("trunc", TRUNC, FUNC_DEFN); /* extra for ltx2x */ enter_standard_routine("print", L2XPRINT, PROC_DEFN); enter_standard_routine("println", L2XPRINTLN, PROC_DEFN); enter_standard_routine("system", L2XSYSTEM, PROC_DEFN); enter_standard_routine("rexpr", L2XREXPR, FUNC_DEFN); /* extra for EXPRESS */ enter_standard_routine("acos", XACOS, FUNC_DEFN); enter_standard_routine("asin", XASIN, FUNC_DEFN); enter_standard_routine("atan", XATAN, FUNC_DEFN); enter_standard_routine("log", XLOG, FUNC_DEFN); enter_standard_routine("log2", XLOG2, FUNC_DEFN); enter_standard_routine("log10", XLOG10, FUNC_DEFN); enter_standard_routine("tan", XTAN, FUNC_DEFN); enter_standard_routine("blength", XBLENGTH, FUNC_DEFN); enter_standard_routine("exists", XEXISTS, FUNC_DEFN); enter_standard_routine("format", XFORMAT, FUNC_DEFN); enter_standard_routine("hibound", XHIBOUND, FUNC_DEFN); enter_standard_routine("hiindex", XHIINDEX, FUNC_DEFN); enter_standard_routine("length", XLENGTH, FUNC_DEFN); enter_standard_routine("lobound", XLOBOUND, FUNC_DEFN); enter_standard_routine("loindex", XLOINDEX, FUNC_DEFN); enter_standard_routine("nvl", XNVL, FUNC_DEFN); enter_standard_routine("rolesof", XROLESOF, FUNC_DEFN); enter_standard_routine("sizeof", XSIZEOF, FUNC_DEFN); enter_standard_routine("typeof", XTYPEOF, FUNC_DEFN); enter_standard_routine("usedin", XUSEDIN, FUNC_DEFN); enter_standard_routine("value", XVALUE, FUNC_DEFN); enter_standard_routine("value_in", XVALUE_IN, FUNC_DEFN); enter_standard_routine("value_unique", XVALUE_UNIQUE, FUNC_DEFN); enter_standard_routine("insert", XINSERT, PROC_DEFN); enter_standard_routine("remove", XREMOVE, PROC_DEFN); /* restore debugging */ DEBUG = temp; return; } /* end init_symtab */ /***************************************************************************/ /***************************************************************************/ /* enter_standard_routine(name, routine_key, defn_key) Enter a standard */ /* procedure or function name into the symtab */ enter_standard_routine(name, routine_key, defn_key) char *name; /* name string */ ROUTINE_KEY routine_key; DEFN_KEY defn_key; { SYMTAB_NODE_PTR rtn_idp = enter_name_local_symtab(rtn_idp, name); rtn_idp->defn.key = defn_key; rtn_idp->defn.info.routine.key = routine_key; rtn_idp->defn.info.routine.parms = NULL; rtn_idp->defn.info.routine.local_symtab = NULL; rtn_idp->typep = NULL; } /* end enter_standard_routine */ /***************************************************************************/ /***************************************************************************/ /* enter_scope(symtab_root) Enter a new nesting level by creating a new */ /* scope. Push the given symbol table onto the display stack */ enter_scope(symtab_root) SYMTAB_NODE_PTR symtab_root; { entry_debug("enter_scope"); if (++level >= MAX_NESTING_LEVEL) { error(NESTING_TOO_DEEP); exit(-NESTING_TOO_DEEP); } symtab_display[level] = symtab_root; exit_debug("enter_scope"); return; } /* end enter_scope */ /***************************************************************************/ /***************************************************************************/ /* exit_scope(symtab_root) Exit the current new nesting level by closing */ /* the current scope. Pop the current symbol table off the */ /* display stack, and return a pointer to it */ SYMTAB_NODE_PTR exit_scope() { SYMTAB_NODE_PTR symtab_root = symtab_display[level--]; entry_debug("exit_scope"); exit_debug("exit_scope"); return(symtab_root); } /* end enter_scope */ /***************************************************************************/