struct symtable * PySymtable_Build(mod_ty mod, const char *filename, PyFutureFeatures *future) { struct symtable *st = symtable_new(); asdl_seq *seq; int i; if (st == NULL) return st; st->st_filename = filename; st->st_future = future; if (!GET_IDENTIFIER(top) || !symtable_enter_block(st, top, ModuleBlock, (void *)mod, 0)) { PySymtable_Free(st); return NULL; } st->st_top = st->st_cur; st->st_cur->ste_unoptimized = OPT_TOPLEVEL; /* Any other top-level initialization? */ switch (mod->kind) { case Module_kind: seq = mod->v.Module.body; for (i = 0; i < asdl_seq_LEN(seq); i++) if (!symtable_visit_stmt(st, (stmt_ty)asdl_seq_GET(seq, i))) goto error; break; case Expression_kind: if (!symtable_visit_expr(st, mod->v.Expression.body)) goto error; break; case Interactive_kind: seq = mod->v.Interactive.body; for (i = 0; i < asdl_seq_LEN(seq); i++) if (!symtable_visit_stmt(st, (stmt_ty)asdl_seq_GET(seq, i))) goto error; break; case Suite_kind: PyErr_SetString(PyExc_RuntimeError, "this compiler does not handle Suites"); goto error; } if (!symtable_exit_block(st, (void *)mod)) { PySymtable_Free(st); return NULL; } if (symtable_analyze(st)) return st; PySymtable_Free(st); return NULL; error: (void) symtable_exit_block(st, (void *)mod); PySymtable_Free(st); return NULL; }
// Parses the output of a lexer, builds a symtable and returns it struct symtable *parse(struct lexer_state *lexer) { int error = 0; char *ident = NULL; struct function *definition = NULL; struct symtable *table = symtable_new(); // At the top level, we expect // <ident> "=" <function-expression> while(lexer->error == OK) { // First lex the function name lex(lexer); // Check for end of file if(lexer->error == END_OF_INPUT) break; // Check for lex error if(lexer->error == UNRECOGNIZED_TOKEN) { print_error(lexer, LEX_ERROR); error = 1; break; } if(lexer->type != IDENT) { print_error(lexer, EXPECTED_IDENT); error = 1; break; } // Otherwise, grab the name ident = strdup(lexer->value.sval); // Require the assign operator if(!require_token(lexer, ASSIGN)) { print_error(lexer, EXPECTED_ASSIGN); error = 1; break; } // Parse the function definition definition = parse_function(lexer); if(!definition) { error = 1; break; } // ...and finally add both to symtable symtable_add(table, ident, definition); free(ident); } // If any errors occurred, delete the symtable and return NULL if(error) { symtable_delete(table); return NULL; } // Otherwise, return the symtable return table; }
void lslinit_process (void) /*@globals undef g_symtab; @*/ /*@modifies g_symtab, internalState, fileSystem; @*/ { /* ** Open init file provided by user, or use the default LCL init file */ cstring larchpath = context_getLarchPath (); inputStream initstream = inputStream_undefined; setCodePoint (); if (inputStream_isUndefined (s_initFile)) { s_initFile = inputStream_create (cstring_makeLiteral (INITFILENAME), cstring_makeLiteralTemp (LCLINIT_SUFFIX), FALSE); if (!inputStream_getPath (larchpath, s_initFile)) { lldiagmsg (message ("Continuing without LCL init file: %s", inputStream_fileName (s_initFile))); } else { if (!inputStream_open (s_initFile)) { lldiagmsg (message ("Continuing without LCL init file: %s", inputStream_fileName (s_initFile))); } } } else { if (!inputStream_open (s_initFile)) { lldiagmsg (message ("Continuing without LCL init file: %s", inputStream_fileName (s_initFile))); } } /* Initialize checker */ lsymbol_initMod (); LCLSynTableInit (); setCodePoint (); LCLSynTableReset (); LCLTokenTableInit (); setCodePoint (); LCLScanLineInit (); setCodePoint (); LCLScanLineReset (); setCodePoint (); LCLScanInit (); setCodePoint (); /* need this to initialize LCL checker */ llassert (inputStream_isDefined (s_initFile)); if (inputStream_isOpen (s_initFile)) { setCodePoint (); LCLScanReset (s_initFile); lclinit_initMod (); lclinit_reset (); setCodePoint (); lclinit_process (); lclinit_cleanup (); setCodePoint (); check (inputStream_close (s_initFile)); } /* Initialize LSL init files, for parsing LSL signatures from LSL */ initstream = inputStream_create (cstring_makeLiteral ("lslinit.lsi"), cstring_makeLiteralTemp (".lsi"), FALSE); if (!inputStream_getPath (larchpath, initstream)) { lldiagmsg (message ("Continuing without LSL init file: %s", inputStream_fileName (initstream))); } else { if (!inputStream_open (initstream)) { lldiagmsg (message ("Continuing without LSL init file: %s", inputStream_fileName (initstream))); } } setCodePoint (); lsynTableInit (); lsynTableReset (); setCodePoint (); ltokenTableInit (); setCodePoint (); lscanLineInit (); lscanLineReset (); LSLScanInit (); if (inputStream_isOpen (initstream)) { setCodePoint (); LSLScanReset (initstream); lslinit_initProcessInitFile (); lslinit_processInitFile (); check (inputStream_close (initstream)); } inputStream_free (initstream); if (lclHadError ()) { lclplainerror (cstring_makeLiteral ("LSL init file error. Attempting to continue.")); } setCodePoint (); g_symtab = symtable_new (); /* ** sort_init must come after symtab has been initialized */ sort_init (); abstract_init (); setCodePoint (); /* ** Equivalent to importing old spec_csupport.lcl ** define immutable LCL type "bool" and bool constants TRUE and FALSE ** and initialized them to be equal to LSL's "true" and "false". ** ** Reads in CTrait.syms (derived from CTrait.lsl) on LARCH_PATH. */ LCLBuiltins (); LCLReportEolTokens (FALSE); }