int main() { sTableInit(); sStackInit(); // generate entries SymbolTableEntry* entry, *entry2, *result, *result2; Lexeme ll = "abc"; int tt = 1; printf("%d\n", s_stack->top); fflush(stdout); entry = sNewEntry ( ll, tt, sStackLevel, sStackTopId ); entry2 = sNewEntry ( "xyz", 2, 1, 1 ); printf("key=%s\nbind=%s\nSlevel=%d\nScopeId=%d\n", entry->key, entry->bind,entry->scope[0],entry->scope[1]); printf("key=%s\nbind=%s\n", entry2->key, entry2->bind); // insert to s_table sTableInsert( entry); // lookup SymbolTableKey key; sNewKey(entry->lex, entry->scope[1], key); result = s_table_lookup(s_table, key); // check printf("key=%s\nbind=%s\n", result->key, result->bind); // remove bool istat = s_table_remove(s_table, entry); if (istat) printf("remove done\n"); else printf("remove false\n"); // lookup 2 , should fail result2 = s_table_lookup(s_table, key); printf("Should be NULL %p\n", result2); // cleanup sTableDestory(); // test stack ScopeId ttt; s_stack_push(s_stack, 1); s_stack_push(s_stack, 2); s_stack_push(s_stack, 3); s_stack_push(s_stack, 4); printf("top=%d, present=%d\n", s_stack->top, s_stack->present); ttt = s_stack_pop(s_stack); printf("pop:%d\n",ttt); // printf("top=%d, present=%d\n", s_stack->top, s_stack->present); // s_stack_reset(s_stack); while(s_stack->present>=0) { printf("down:%d\n",s_stack_down(s_stack)); } s_stack_reset(s_stack); printf("top=%d, present=%d\n", s_stack->top, s_stack->present); // sStackDestroy(); }
/** lookup an Id from symtable, return the entry */ SymbolTableEntry* sTableTryLookupId(struct Node* node) { if( node->token != IDENTIFIER && node->token != DYN_ATTRIBUTE ) { fprintf(stderr,"error: sTableLookupId: argument must be IDENTIFIER or DYN_ATTRIBUTE\n"); exit(EXIT_FAILURE); } SymbolTableKey key; SymbolTableEntry* entry; ScopeId id = sStackTopId; sStackReset(); while (id>=0) { sNewKey(node->lexval.sval, id, key); if ( (entry = sTableLookup(key)) != NULL ) break; id = sStackDown(); } if (entry == NULL) { // printf("key= '%s'\n", key); // sTableShow(stderr); } return entry; }
/** lookup a func or func_literal, if not found report compiling error */ int sTableLookupFunc(struct Node* node) { if(node->token != AST_FUNC_CALL) { fprintf(stderr,"error: sTableLookupFunc: argument must be AST_FUNC_CALL\n"); exit(EXIT_FAILURE); } SymbolTableKey key; SymbolTableEntry* entry; struct Node* funcId = node->child[0]; // create key sNewKey(funcId->lexval.sval, 0, key); // function always in scope 0 // try lookup in Symbol Table entry = sTableLookup(key); if(entry == NULL) { ERRNO = ErrorFunctionCalledBeforeDeclaration; errorInfo(ERRNO, node->line, "`"); FuncHead(funcId->lexval.sval, node->typeCon, ERRORIO); errorInfoExt("' is not declared before.\n"); return ERRNO; } // if found, check parameter types GArray* caller = node->typeCon; GArray* ref = entry->typeCon; int flag = 0; /* if(entry->type == FUNC_T) { // if function if(caller->len != ref->len) { flag = (ERRNO = ErrorFunctionCallNOTEqualNumberOfParameters); errorInfo(ERRNO, node->line, "function Call `"); FuncHead(funcId->lexval.sval, caller, ERRORIO); errorInfoExt("' has inconsistent number of arguments to its declaration.\n"); } else { if ( checkTwoTypeCons(caller, ref) == 0 ) { // not equal flag = (ERRNO = ErrorFunctionCallIncompatibleParameterType); errorInfo(ERRNO, node->line, "function Call `"); FuncHead(funcId->lexval.sval, caller, ERRORIO); errorInfoExt("' has incompatible arguments to its declaration.\n"); } } } else if(entry->type == FUNC_LITERAL_T) { // func_literal if ( checkTwoTypeConsExceptDyn(caller, ref) == 0 ) { // not equal flag = (ERRNO = ErrorFuncLiteralCallIncompatibleParameterType); errorInfo(ERRNO, node->line, "function literal Call `"); FuncHead(funcId->lexval.sval, caller, ERRORIO); errorInfoExt("' has incompatible arguments to its declaration.\n"); } } else { flag = (ERRNO = ErrorFunctionCalledBeforeDeclaration); errorInfo(ERRNO, node->line,"`%s' is not declared as a function or function literal\n",funcId->lexval.sval ); errorInfoNote("`%s' is first declared at line %d\n",funcId->lexval.sval,entry->line); return ERRNO; }*/ if (flag == ErrorFunctionCallNOTEqualNumberOfParameters || flag == ErrorFunctionCallIncompatibleParameterType || flag == ErrorFuncLiteralCallIncompatibleParameterType ) { errorInfoNote("function `"); FuncHead(funcId->lexval.sval, ref, ERRORIO); errorInfoExt("' first declared at line %d\n",entry->line); return ERRNO; } // found correct one node->symbol = entry; node->type = entry->rtype; return 0; }