void free_ast (astree* root) { while (not root->children.empty()) { astree* child = root->children.back(); root->children.pop_back(); free_ast (child); } DEBUGF ('f', "free [%p]-> %d:%d.%d: %s: \"%s\")\n", root, root->filenr, root->linenr, root->offset, get_yytname (root->symbol), root->lexinfo->c_str()); delete root; }
static void dump_node (FILE* outfile, astree* node) { fprintf (outfile, "%3ld %ld.%03ld %-3d %-15s (%s) ", node->filenr, node->linenr, node->offset, node->symbol, get_yytname (node->symbol), node->lexinfo->c_str()); bool need_space = false; for (size_t child = 0; child < node->children.size(); ++child) { if (need_space) fprintf (outfile, " "); need_space = true; fprintf (outfile, "%p", node->children.at(child)); } }
astree* new_astree (int symbol, int filenr, int linenr, int offset, const char* lexinfo) { astree* tree = new astree(); tree->symbol = symbol; tree->filenr = filenr; tree->linenr = linenr; tree->offset = offset; tree->lexinfo = intern_stringset (lexinfo); DEBUGF ('f', "astree %p->{%d:%d.%d: %s: \"%s\"}\n", tree, tree->filenr, tree->linenr, tree->offset, get_yytname (tree->symbol), tree->lexinfo->c_str()); return tree; }
static void dump_astree_rec2 (FILE* outfile, astree* root, int depth) { if (root == NULL) return; int i = 0; while (i < depth){ fprintf(outfile, " "); i++; } fprintf(outfile, "%s", get_yytname(root->symbol)); if(strcmp(root->lexinfo->c_str(), "") != 0) fprintf(outfile, " (%s)", root->lexinfo->c_str()); fprintf(outfile, "\n"); for (size_t child = 0; child < root->children.size(); ++child){ dump_astree_rec2 (outfile, root->children[child], depth +1); } }
void freeast (astree root) { astree child = NULL; if (root == NULL) return; assert (is_astree (root)); for (child = root->first; child != NULL;) { astree asttofree = child; assert (is_astree (asttofree)); child = child->next; freeast (asttofree); } DEBUGF ('f', "free [%X]-> %d:%d.%d: %s: %p->\"%s\")\n", (uintptr_t) root, root->filenr, root->linenr, root->offset, get_yytname (root->symbol), root->lexinfo, root->lexinfo); memset (root, 0, sizeof (struct astree_rep)); free (root); }
void traverseFunc(astree* root, int symbol) { for (size_t a = 0; a < root->children.size(); ++a) { int sym = root->children[a]->symbol; astree* curr = root->children[a]; switch(sym) { case TOK_VARDECL: case '=': travVardecl(curr); break; case TOK_IF: case TOK_WHILE: validCompare(curr); symbol_stack.push_back(nullptr); blockcount++; traverseAstree(curr->children[1]); blockcount--; symbol_stack.pop_back(); break; case TOK_IFELSE: validCompare(curr); symbol_stack.push_back(nullptr); blockcount++; traverseAstree(curr->children[1]); blockcount--; symbol_stack.pop_back(); symbol_stack.push_back(nullptr); blockcount++; traverseAstree(curr->children[2]); blockcount--; symbol_stack.pop_back(); break; case TOK_RETURN: if( getReturnType(curr->children[0]) != symbol ) { char *tname = (char* )get_yytname (symbol); if (strstr (tname, "TOK_") == tname) tname += 4; errprintf("%zu.%zu.%zu Return type does not match return" " type of " "function (%s)\n", curr->filenr, curr->linenr, curr->offset, tname); } break; case TOK_CALL: checkCall(curr); break; } } }
astree* new_astree (int symbol, int filenr, int linenr, int offset, const char* lexinfo) { astree* tree = new astree(); tree->symbol = symbol; tree->filenr = filenr; tree->linenr = linenr; tree->offset = offset; tree->lexinfo = intern_stringset (lexinfo); tree->attributes = 0; // (asg4). tree->block_nr = 0; // (asg4). tree->parent = nullptr; // (asg4). tree->sym = nullptr; // (asg4). tree->emit_str = nullptr; // (asg5). DEBUGF ('f', "astree %p->{%d:%d.%d: %s: \"%s\"}\n", tree, tree->filenr, tree->linenr, tree->offset, get_yytname (tree->symbol), tree->lexinfo->c_str()); return tree; }
static void dump_node (FILE *outfile, astree node, int depth) { assert (is_astree (node)); while (depth > 0){ fprintf(outfile,"| "); depth--; } char *tname = (char *)get_yytname(node->symbol); if (strstr(tname, "TOK_") == tname) tname += 4; fprintf(outfile,"%s \"%s\" %d.%d.%d", tname,peek_stringtable(node->lexinfo), node->filenr,node->linenr, node->offset); /* fprintf (outfile, "%p-> astree {%s(%d), %d:%d.%03d, %p->\"%s\",\n", (void*) node, get_yytname (node->symbol), node->symbol, node->filenr, node->linenr, node->offset, node->lexinfo, node->lexinfo); fprintf (outfile, "%*sfirst=%p, last=%p, next=%p}", depth * 3 + 12, "", (void*) node->first, (void*) node->last, (void*) node->next);*/ }
void dumptok(FILE *out){ unsigned char printfile = -1; for(int i=0; i<=token_list.last; i++){ if(printfile != token_list.tokens[i]->filenr){ printfile = token_list.tokens[i]->filenr; fprintf(out, "#%3d \"%s\"\n", printfile, getfilename(printfile)); } fprintf(out, "%4d%4d.%03d%6d %-15s (%s)\n", token_list.tokens[i]->filenr, token_list.tokens[i]->linenr, token_list.tokens[i]->offset, token_list.tokens[i]->symbol, get_yytname(token_list.tokens[i]->symbol), //need to convert symbol to literal here token_list.tokens[i]->lexeme ); } }
bool searcher(astree* root, string type, SymbolTable* table){ if(root == NULL) return true; SymbolTable* currtab = table; for(size_t child = 0; child < root->children.size(); ++child){ string currsym = get_yytname(root->children[child]->symbol); if(currsym == "return_"){ if(root->children[child]->children.size() != 0 && type == "void") return false; if(root->children[child]->children.size() == 1){ string roottype = checker(root->children[child]->children[0], table); if(roottype != type) return false; } } if(currsym == "block"){ currtab = root->children[child]->blockpt; } if(!searcher(root->children[child], type, currtab)) return false; } return true; }
astree new_astree (int symbol, int filenr, int linenr, int offset, char *lexinfo) { size_t size = sizeof (struct astree_rep); astree tree = malloc (size); assert (tree != NULL); tree->tag = astree_tag; tree->symbol = symbol; tree->filenr = filenr; tree->linenr = linenr; tree->offset = offset; tree->lexinfo = strdup (lexinfo); assert (tree->lexinfo != NULL); tree->first = NULL; tree->last = NULL; tree->next = NULL; DEBUGF ('f', "malloc (%d) = %p-> %d:%d.%d: %s: %p->\"%s\"\n", size, tree, tree->filenr, tree->linenr, tree->offset, get_yytname (tree->symbol), tree->lexinfo, tree->lexinfo); return tree; }
astree new_astree (int symbol, int filenr, int linenr, int offset, cstring lex) { size_t size = sizeof (struct astree_rep); astree tree = malloc (size); assert (tree != NULL); tree->tag = astree_tag; tree->symbol = symbol; tree->filenr = filenr; tree->linenr = linenr; tree->offset = offset; tree->lexinfo = intern_stringtable(thestringtable,lex); assert (tree->lexinfo != NULL); tree->first = NULL; tree->last = NULL; tree->next = NULL; tree->blocknr = 0; tree->attrs = 0; DEBUGF ('f', "malloc (%d) = %p-> %d:%d.%d: %s: %p->\"%s\"\n", size, tree, tree->filenr, tree->linenr, tree->offset, get_yytname (tree->symbol), tree->lexinfo, tree->lexinfo); return tree; }
// Main switch statement used for setting any given attribute // determined with scanned token. void set_attributes(astree* n) { if (n == NULL) return; DEBUGF('z', "%s\n", get_yytname(n->symbol)); switch (n->symbol) { case TOK_INTCON: n->attributes.set(ATTR_const); case TOK_INT: n->attributes.set(ATTR_int); break; case TOK_CHARCON: n->attributes.set(ATTR_const); case TOK_CHAR: n->attributes.set(ATTR_char); break; case TOK_STRINGCON: n->attributes.set(ATTR_const); case TOK_STRING: n->attributes.set(ATTR_string); break; case TOK_VOID: n->attributes.set(ATTR_void); break; case TOK_BOOL: n->attributes.set(ATTR_bool); break; case TOK_STRUCT: n->attributes.set(ATTR_struct); break; case TOK_NULL: n->attributes.set(ATTR_const); break; case TOK_FIELD: n->attributes.set(ATTR_field); break; case TOK_FUNCTION: n->attributes.set(ATTR_function); break; case TOK_ARRAY: n->attributes.set(ATTR_array); break; case TOK_VARDECL: n->attributes.set(ATTR_variable); break; case TOK_PROTOTYPE: n->attributes.set(ATTR_proto); break; default: break; } }
static void dump_astree_rec (FILE *outfile, astree root, int depth) { astree child = NULL; if (root == NULL) return; assert (is_astree (root)); const char *tname = get_yytname(root->symbol); if (strstr (tname, "TOK_") == tname) tname += 4; if(depth == 0){ fprintf (outfile, "%*s%s \"%s\" %d.%d.%03d ", depth * 3, "", tname, root->lexinfo, root->filenr, root->linenr, root->offset); } else{ int i; for(i =0 ; i < depth; ++i){ fprintf(outfile, "%*s ", 1, "|"); } fprintf (outfile, "%s \"%s\" %d.%d.%03d ", tname, root->lexinfo, root->filenr, root->linenr, root->offset); } // dump_node (outfile, root, depth); fprintf (outfile, "\n"); for (child = root->first; child != NULL; child = child->next) { dump_astree_rec (outfile, child, depth + 1); } }
int getReturnType(astree* root) { int sym = root->symbol; switch(sym) { case TOK_NULL: return sym; break; case TOK_INTCON: return sym; break; case TOK_CHARCON: return sym; break; case TOK_BOOL: return sym; break; case TOK_IDENT: if(lookup(root->lexinfo)) { symbol* val = lookupSym(root->lexinfo); return getIdentReturn(val); } else { errprintf("%zu.%zu.%zu" " Variable being referenced is undefined\n",root->filenr, root->linenr,root->offset); return -1; } break; case '+': case '-': case '*': case '/': case '%': { int left = getReturnType(root->children[0]); int right = getReturnType(root->children[1]); if(right == left && right == TOK_INTCON) { return right; } else { errprintf("%zu.%zu.%zu Type check error: %s " "does not match %s\n" ,root->children[0]->filenr,root->children[0]->linenr, root->children[0]->offset,get_yytname(left) ,get_yytname(right)); return right; } break; } case TOK_NEWARRAY: return TOK_NEWARRAY; break; case TOK_NEWSTRING: return TOK_NEWSTRING; break; case TOK_CALL: checkCall(root); return getReturnType(root->children[0]); break; case TOK_POS: case TOK_NEG: return getReturnType(root->children[0]); break; case TOK_NEW: return getReturnType(root->children[0]); break; case TOK_TYPEID: return TOK_TYPEID; break; case '.': if(lookup(root->children[0]->lexinfo)) { symbol* tempSym = lookupSym(root->children[0]->lexinfo); string structType = tempSym->type_id; if(structType == "") { errprintf("%zu.%zu.%zu Referenced struct not defined\n", root->children[0]->filenr,root->children[0]->linenr, root->children[0]->offset); return -1; } if(lookup(&structType)) { symbol* structSym = lookupSym(&structType); symbol_table* tab = structSym->fields; auto fi = tab->find(root->children[1]->lexinfo); if(fi!=tab->cend()) { symbol* structField = fi->second; return getIdentReturn(structField); } else { errprintf("%zu.%zu.%zu Field not defined\n", root->children[1]->filenr,root->children[1]->linenr, root->children[1]->offset); } } } else { errprintf("%zu.%zu.%zu Referenced struct not defined\n", root->children[0]->filenr,root->children[0]->linenr, root->children[0]->offset); } return -1; break; case TOK_ORD: if(getReturnType(root->children[0])==TOK_CHARCON) { return TOK_INTCON; } else { errprintf("%zu.%zu.%zu Ord must be called on type char\n", root->children[0]->filenr,root->children[0]->linenr, root->children[0]->offset); } break; case TOK_CHR: if(getReturnType(root->children[0])==TOK_INTCON) { return TOK_CHARCON; } else { errprintf("%zu.%zu.%zu Chr must be called on type int\n", root->children[0]->filenr,root->children[0]->linenr, root->children[0]->offset); } break; } }
void genCode(astree* root, SymbolTable* table){ if (root == NULL) { return; } string currsym = get_yytname(root->symbol); if (currsym == "program") { for (size_t child = 0; child < root->children.size(); ++child) { string currsymbol = get_yytname(root->children[child]->symbol); if (currsymbol == "vardecl") { string child2 = get_yytname(root->children[child]->children[2]->symbol); string ident = root->children[child]->children[1]->lexinfo->c_str(); string declt = root->children[child]->children[0]->children[0]->children[0]->lexinfo->c_str(); string newtype = converter(declt); if(root->children[child]->children[0]->children.size() == 2){ declt = declt + "[]"; newtype = converter(declt); fprintf(oilFile, "%s__%s;\n", newtype.c_str(), ident.c_str()); } else { fprintf(oilFile, "%s__%s;\n", newtype.c_str(), ident.c_str()); } } if (currsymbol == "struct_") { genCode(root->children[child], table); } } fprintf(oilFile, "void __ocmain ()\n{\n"); for (size_t child = 0; child < root->children.size(); ++child) { string currsymbol = get_yytname(root->children[child]->symbol); if (currsymbol != "vardecl" && currsymbol != "struct_") { genCode(root->children[child], table); } } fprintf(oilFile, "}\n"); } if (currsym == "vardecl") { string ident = root->children[1]->lexinfo->c_str(); string dect = checker(root->children[1], table); if (root->children[0]->children.size() == 2) dect = dect + "[]"; dect = converter(dect); string child2 = get_yytname(root->children[2]->symbol); if (child2 == "constant") { fprintf(oilFile, "%s_%d_%s = __%s\n", dect.c_str(),table->numBack(), ident.c_str(), root->children[2]->children[0]->lexinfo->c_str()); } if (child2 == "variable") { fprintf(oilFile, "%s_%d_%s = _%d_%s\n", dect.c_str(),table->numBack(), ident.c_str(), table->numBack(), root->children[2]->children[0]->lexinfo->c_str()); } } if (currsym == "binop") { string op = root->children[1]->lexinfo->c_str(); if (op == "+" || op == "-" || op == "/" || op == "%" || op == "*") { int counter = icount++; string child0 = get_yytname(root->children[0]->symbol); string child2 = get_yytname(root->children[2]->symbol); if (child0 != "constant" && child0 != "constant") { genCode(root->children[0], table); fprintf(oilFile, "i%d = i%d ", counter, counter-1); } else if (child2 != "constant" && child2 != "constant") { genCode(root->children[2], table); fprintf(oilFile, "i%d = i%d ", counter, counter-1); } else { fprintf(oilFile, "i%d = ", counter); } if(child0 == "constant") { fprintf(oilFile, "%s ", root->children[0]->children[0]->lexinfo->c_str()); } if(child0 == "variable") { fprintf(oilFile, "_%d_%s ", table->numBack(), root->children[0]->children[0]->lexinfo->c_str()); } fprintf(oilFile, "%s ", root->children[1]->lexinfo->c_str()); if(child2 == "constant") { fprintf(oilFile, "%s;\n", root->children[2]->children[0]->lexinfo->c_str()); } if(child2 == "variable") { fprintf(oilFile, "_%d_%s;\n", table->numBack(), root->children[2]->children[0]->lexinfo->c_str()); } } if (op == ">" || op == "<" || op == ">=" || op == "<=" || op == "!=" || op == "==") { int counter = bcount++; string child0 = get_yytname(root->children[0]->symbol); string child2 = get_yytname(root->children[2]->symbol); if (child0 != "constant" && child0 != "constant") { genCode(root->children[0], table); fprintf(oilFile, "b%d = b%d ", counter, counter-1); } else if (child2 != "constant" && child2 != "constant") { genCode(root->children[2], table); fprintf(oilFile, "b%d = b%d ", counter, counter-1); } else { fprintf(oilFile, "b%d = ", counter); } if(child0 == "constant") { fprintf(oilFile, "%s ", root->children[0]->children[0]->lexinfo->c_str()); } if(child0 == "variable") { fprintf(oilFile, "_%d_%s ", table->numBack(), root->children[0]->children[0]->lexinfo->c_str()); } fprintf(oilFile, "%s ", root->children[1]->lexinfo->c_str()); if(child2 == "constant") { fprintf(oilFile, "%s;\n", root->children[2]->children[0]->lexinfo->c_str()); } if(child2 == "variable") { fprintf(oilFile, "_%d_%s;\n", table->numBack(), root->children[2]->children[0]->lexinfo->c_str()); } } } if (currsym == "while_") { int currb = bcount; int currcount = controlcount++; fprintf(oilFile, "while_%d:;\n", currcount); genCode(root->children[0], table); fprintf(oilFile, "if(!b%d) goto break_%d;\n", currb, currcount); genCode(root->children[1],table); fprintf(oilFile, "goto while_%d;\n", currcount); fprintf(oilFile, "break_%d:;\n", currcount); } if (currsym == "if_") { int currb = bcount; int currcount = controlcount++; genCode(root->children[0],table); fprintf(oilFile, "if(!b%d) goto else_%d;\n", currb, currcount); genCode(root->children[1],table); fprintf(oilFile, "goto fi_%d;\n", currcount); fprintf(oilFile, "else_%d:;\n", currcount); if(root->children.size() == 3) genCode(root->children[2],table); fprintf(oilFile, "fi_%d:;\n", currcount); } if (currsym == "block") { SymbolTable* currblock = root->blockpt; for(size_t child = 0; child < root->children.size(); ++child){ genCode(root->children[child], currblock); } } if (currsym == "struct_") { string structname; for (size_t child = 0; child < root->children.size(); ++child) { string currchild = get_yytname(root->children[child]->symbol); if (currchild == "TOK_IDENT") { structname = root->children[child]->lexinfo->c_str(); } } fprintf(oilFile, "struct %s{\n", structname.c_str()); for (size_t child = 0; child < root->children.size(); ++child) { string currchild = get_yytname(root->children[child]->symbol); if (currchild == "decl") { string ident = root->children[child]->children[1]->lexinfo->c_str(); string declt = root->children[child]->children[0]->children[0]->children[0]->lexinfo->c_str(); string newtype = converter(declt); if (root->children[child]->children[0]->children.size() == 2) { declt = declt + "[]"; newtype = converter(declt); fprintf(oilFile, " %s%s;\n", newtype.c_str(), ident.c_str()); } else { fprintf(oilFile, " %s%s;\n", newtype.c_str(), ident.c_str()); } } } fprintf(oilFile, "};\n"); } if (currsym == "decl") { string ident = root->children[1]->lexinfo->c_str(); string declt = root->children[0]->children[0]->children[0]->lexinfo->c_str(); string newtype = converter(declt); if (root->children[0]->children.size() == 2) { declt = declt + "[]"; newtype = converter(declt); fprintf(oilFile, "%s__%s;\n", newtype.c_str(), ident.c_str()); } else { fprintf(oilFile, "%s__%s;\n", newtype.c_str(), ident.c_str()); } } if (currsym == "function") { string funcname; string rettype; SymbolTable* currblock; astree* blockroot; for (size_t child = 0; child < root->children.size(); ++child) { string currchild = get_yytname(root->children[child]->symbol); if (currchild == "TOK_IDENT") { funcname = root->children[child]->lexinfo->c_str(); rettype = checker(root->children[child], table); int firstparen = rettype.find_first_of('(',0); rettype = rettype.substr(0,firstparen); } if (currchild == "block") { currblock = root->children[child]->blockpt; blockroot = root->children[child]; if (blockroot->children.size() == 0) return; } } fprintf(oilFile, "%s\n__%s(", converter(rettype).c_str(), funcname.c_str()); for (size_t child = 0; child < root->children.size(); ++child) { int counter = 0; string currchild = get_yytname(root->children[child]->symbol); if (currchild == "decl") { string ident = root->children[child]->children[1]->lexinfo->c_str(); string dectype = checker(root->children[child]->children[1], currblock); if (root->children[child]->children[0]->children.size() == 2) { dectype = dectype + "[]"; } dectype = converter(dectype); if (counter != 0) { fprintf(oilFile, ","); } fprintf(oilFile, "\n %s_%d_%s", dectype.c_str(), currblock->numBack(), ident.c_str()); } } fprintf(oilFile, ")\n"); genCode(blockroot, table); } }
string checker(astree* root, SymbolTable* table){ if(root == NULL) return NULL; string names = get_yytname(root->symbol); if(names == "TOK_INT" || names == "TOK_INTCON") return "int"; if(names == "TOK_CHAR" || names == "TOK_CHARCON") return "char"; if(names == "TOK_STRING" || names == "TOK_STRINGCON") return "string"; if(names == "TOK_BOOL" || names == "TOK_TRUE" || names == "TOK_FALSE") return "bool"; if(names == "TOK_NULL") return "null"; if(names == "TOK_IDENT") return table->lookup(root->lexinfo->c_str()); if(names == "constant") return checker(root->children[0], table); if(names == "type"){ if(root->children.size() == 2){ string type = checker(root->children[0],table); type = type + "[]"; return type; } return checker(root->children[0], table); } if(names == "basetype"){ string offSpr = get_yytname(root->children[0]->symbol); string ident = root->children[0]->lexinfo->c_str(); if(offSpr == "TOK_IDENT"){ if (strSym->lookup2(ident) != NULL) return ident; } return checker(root->children[0], table); } if(names == "variable") { if(root->children.size() == 1) return checker(root->children[0], table); if(root->children.size() == 2){ string offSpr2 = get_yytname(root->children[1]->symbol); SymbolTable* curnt; if(offSpr2 == "TOK_IDENT"){ string offSpr = checker(root->children[0],table); string ident = root->children[1]->lexinfo->c_str(); if(strSym->lookup2(offSpr) != NULL){ curnt = strSym->lookup2(offSpr); if (curnt == NULL){ errprintf("Not a variable of this struct!\n"); return ""; } return curnt->lookup(ident); } }else{ if(checker(root->children[1],table) == "int" && checker(root->children[0],table) == "string") return "char"; if(checker(root->children[1],table) == "int" && checker(root->children[0],table) == "int[]") return "int"; if(checker(root->children[1],table) == "int" && checker(root->children[0],table) == "bool[]") return "bool"; if(checker(root->children[1],table) == "int" && checker(root->children[0],table) == "char[]") return "char"; if(checker(root->children[1],table) == "int" && checker(root->children[0],table) == "struct[]") return "struct"; if(checker(root->children[1],table) == "int" && checker(root->children[0],table) == "string[]") return "string"; } } } if(names == "call"){ string funcoper = "("; string funcname; string funcops; size_t check = -1; int begin; int comcounter = 0; int firstparen; for(size_t child = 0; child < root->children.size(); ++child){ string currchild = get_yytname(root->children[child]->symbol); if(currchild != "TOK_IDENT"){ if (comcounter != 0) funcoper = funcoper + ","; string currop = checker(root->children[child], table); funcoper = funcoper + currop; comcounter++; } if(currchild == "TOK_IDENT") funcname = root->children[child]->lexinfo->c_str(); } funcoper = funcoper + ")"; funcops = table->lookup(funcname); begin = funcops.length() - funcoper.length(); if(funcops.find(funcoper) == check) errprintf("Incorrect arguments passed to function!\n"); firstparen = funcops.find_first_of('(', 0); return funcops.substr(0,firstparen); } if(names == "vardecl"){ string c0 = checker(root->children[0],table); string c1 = checker(root->children[2],table); if(c0 != c1) errprintf("Declaring incorrect type!\n"); return ""; } if(names == "program"){ for(size_t child = 0; child < root->children.size(); ++ child){ checker(root->children[child], table); } } if(names == "while_" || names == "if_"){ if(checker(root->children[0],table) != "bool") errprintf("Expression does not return a bool!\n"); checker(root->children[1], table); if(root->children[2] != NULL) checker(root->children[2], table); return ""; } if(names == "function"){ SymbolTable* currblock; astree* blockroot; string funcreturn; for(size_t child = 0; child < root->children.size(); ++child){ string currchild = get_yytname(root->children[child]->symbol); if(currchild == "type"){ funcreturn = checker(root->children[child], table); } if(currchild == "block"){ currblock = root->children[child]->blockpt; blockroot = root->children[child]; } } if(!searcher(blockroot, funcreturn, currblock)) errprintf("Incorrect return type!\n"); } if(names == "block"){ SymbolTable* currtable = root->blockpt; for(size_t child = 0; child < root->children.size(); ++child){ checker(root->children[child], currtable); } } if(names == "allocator_"){ if(root->children.size() < 3) return checker(root->children[1],table); else{ string bracket = get_yytname(root->children[3]->symbol); string result = checker(root->children[1],table); if(bracket == "'['"){ if(checker(root->children[2],table) == "int"){ result = result + "[]"; return result; }else errprintf("Need int in brackets!\n"); }else return result; } } if(names == "binop"){ string offSpr2 = get_yytname(root->children[1]->symbol); if(offSpr2 == "'+'" || offSpr2 == "'-'" || offSpr2 == "'*'" || offSpr2 == "'/'" || offSpr2 == "'%'"){ if(checker(root->children[0],table) == "int" && checker(root->children[0], table) == checker(root->children[2],table)) return "int"; else errprintf("One or more inputs is not of type int\n"); } if(offSpr2 == "TOK_LT" || offSpr2 == "TOK_LE" || offSpr2 == "TOK_GT" || offSpr2 == "TOK_GE"){ string c0 = checker(root->children[0], table); string c1 = checker(root->children[2], table); if((c0 == "int" || c0 == "char" || c0 == "bool") && c0 == c1 ) return "bool"; else errprintf("Comparison of different or incorrect types!\n"); } if(offSpr2 == "TOK_NE" || offSpr2 == "TOK_EQ"){ string c0 = checker(root->children[0], table); string c1 = checker(root->children[2], table); if(c0 == c1 || (c0 != "bool" && c0 != "int" && c0 != "char" && c1 == "null")) return "bool"; else errprintf("Comparison of different types!\n"); } if(offSpr2 == "'='"){ string c0 = checker(root->children[0], table); string c1 = checker(root->children[2], table); if(c0 == c1 || (c0 != "bool" && c0 != "int" && c0 != "char" && c1 == "null")) return c0; else errprintf("Trying to set variable to different type!\n"); } } if(names == "unop"){ string offSpr = get_yytname(root->children[0]->symbol); if(offSpr == "TOK_POS" || offSpr == "TOK_NEG"){ if(checker(root->children[0]->children[0], table) == "int") return "int"; else errprintf("Tried adding sign to non-int type!\n"); } if(offSpr == "'!'"){ if(checker(root->children[0]->children[0], table) == "bool") return "bool"; else errprintf("Tried negating a non-bool!\n"); } if(offSpr == "TOK_ORD"){ if(checker(root->children[0]->children[0], table) == "char") return "int"; else errprintf("Tried using ord on non-char type!\n"); } if(offSpr == "TOK_CHR"){ if(checker(root->children[0]->children[0], table) == "int") return "char"; else errprintf("Tried using chr on non-int type!\n"); } } return ""; }
void scan(astree* root, SymbolTable* sym){ if(root == NULL) return; for(size_t child = 0; child < root->children.size(); ++child){ const char* CurSym = get_yytname(root->children[child]->symbol); if(strcmp(CurSym, "vardecl") != 0 && strcmp(CurSym, "block") != 0 && strcmp(CurSym, "function") != 0 && strcmp(CurSym, "struct_") != 0) scan(root->children[child], sym); else if(strcmp(CurSym, "vardecl") == 0){ if(root->children[child]->children[0]->children.size() < 2){ sym->addSymbol(root->children[child]->children[1]->lexinfo->c_str(), root->children[child]->children[0]->children[0]->children[0]->lexinfo->c_str(), root->children[child]->children[1]->filenr, root->children[child]->children[1]->linenr, root->children[child]->children[1]->offset); }else{ string type = root->children[child]->children[0]->children[0]->children[0]->lexinfo->c_str(); type = type + "[]"; sym->addSymbol(root->children[child]->children[1]->lexinfo->c_str(), type, root->children[child]->children[1]->filenr, root->children[child]->children[1]->linenr, root->children[child]->children[1]->offset); } }else if (strcmp(CurSym, "struct_") == 0){ string tabs; SymbolTable* CurTabs; for(size_t childOther = 0; childOther < root->children[child]->children.size(); ++childOther){ string CurChild = get_yytname(root->children[child]->children[childOther]->symbol); if(CurChild == "TOK_IDENT"){ tabs = root->children[child]->children[childOther]->lexinfo->c_str(); strSym->addStruct(tabs); CurTabs = strSym->lookup2(tabs); } } for(size_t childOther = 0; childOther < root->children[child]->children.size(); ++childOther){ string CurChild = get_yytname(root->children[child]->children[childOther]->symbol); if(CurChild == "decl"){ CurTabs->addSymbol( root->children[child]->children[childOther]->children[1]->lexinfo->c_str(), root->children[child]->children[childOther]->children[0]->children[0]->children[0]->lexinfo->c_str(), root->children[child]->children[childOther]->children[1]->filenr, root->children[child]->children[childOther]->children[1]->linenr, root->children[child]->children[childOther]->children[1]->offset); } } }else if(strcmp(CurSym, "block") == 0){ scan(root->children[child], root->children[child]->blockpt = sym->enterBlock()); }else if(strcmp(CurSym, "function") == 0){ char ident[50]; char decl[100]; int blocknum; int numdecl = 0; int funfilenr = 0; int funlinenr = 0; int funoffset = 0; for(size_t childOther = 0; childOther < root->children[child]->children.size(); ++childOther){ const char* CurSymIn = get_yytname(root->children[child]->children[childOther]->symbol); if(strcmp(CurSymIn, "TOK_IDENT") == 0){ funfilenr = root->children[child]->children[childOther]->filenr; funlinenr = root->children[child]->children[childOther]->linenr; funoffset = root->children[child]->children[childOther]->offset; strcpy(ident, root->children[child]->children[childOther]->lexinfo->c_str()); } if(strcmp(CurSymIn, "type") == 0){ if(root->children[child]->children[childOther]->children.size() == 2){ strcpy(decl, root->children[child]->children[childOther]->children[0]->children[0]->lexinfo->c_str()); strcat(decl, "[]"); strcat(decl, "("); }else{ strcpy(decl, root->children[child]->children[childOther]->children[0]->children[0]->lexinfo->c_str()); strcat(decl, "("); } } if(strcmp(CurSymIn, "block") == 0) blocknum = childOther; } for(size_t childOther = 0; childOther < root->children[child]->children.size(); ++childOther){ if(strcmp(get_yytname(root->children[child]->children[childOther]->symbol), "decl") == 0){ if(numdecl != 0) strcat(decl, ","); if(root->children[child]->children[childOther]->children[0]->children.size() == 2){ strcat(decl,root->children[child]->children[childOther]->children[0]->children[0]->children[0]->lexinfo->c_str()); strcat(decl,"[]"); }else{ strcat(decl,root->children[child]->children[childOther]->children[0]->children[0]->children[0]->lexinfo->c_str()); } ++numdecl; } } strcat(decl, ")"); SymbolTable* FunSym = sym->enterFunction(ident, decl, funfilenr, funlinenr, funoffset); for(size_t childOther = 0; childOther < root->children[child]->children.size(); ++childOther){ if(strcmp(get_yytname(root->children[child]->children[childOther]->symbol), "decl") == 0){ if(root->children[child]->children[childOther]->children[0]->children.size() == 2){ string types = root->children[child]->children[childOther]->children[0]->children[0]->children[0]->lexinfo->c_str(); types = types + "[]"; FunSym->addSymbol(root->children[child]->children[childOther]->children[1]->lexinfo->c_str(), types, root->children[child]->children[childOther]->children[1]->filenr, root->children[child]->children[childOther]->children[1]->linenr,root->children[child]->children[childOther]->children[1]->offset); } else{ FunSym->addSymbol(root->children[child]->children[childOther]->children[1]->lexinfo->c_str(), root->children[child]->children[childOther]->children[0]->children[0]->children[0]->lexinfo->c_str(), root->children[child]->children[childOther]->children[1]->filenr, root->children[child]->children[childOther]->children[1]->linenr, root->children[child]->children[childOther]->children[1]->offset); } } } scan(root->children[child]->children[blocknum], root->children[child]->children[blocknum]->blockpt = FunSym); } } }
void print_tok(int symbol) { fprintf(yytok," %d %3d.%.3d %.3d %13s (%s)\n", filename_stack.last_filenr, scan_linenr, yyleng, symbol, get_yytname(symbol), yytext); }
static void dump_symbol (astree* node, int depth) { // Remove "TOK_" from token auto tname = get_yytname (node->symbol); if (strstr (tname, "TOK_") == tname) tname += 4; // Print current node info printf("the symbol is: %s\n the lexinfo is: %s\n", tname,node->lexinfo->c_str()); // Put node info into new symbol symbol* newSymbol = new symbol(); newSymbol->filenr = node->filenr; newSymbol->linenr = node->linenr; newSymbol->offset = node->offset; // If node is root, set blocknum to 0 switch (convert(tname)) { case ROOT: { // set blocknum to 0 newSymbol->blocknum = 0; /* auto newSymTable = new symbol_table(); symbol_entry entry(node->lexinfo, newSymbol); newSymTable->insert(entry); symbol_stack.push_back(newSymTable); */ } break; case VOID: { newSymbol->attributes[ATTR_void]=true; newSymbol->fields = nullptr; newSymbol->parameters = nullptr; newSymbol->blocknum = 0; auto newSymTable = symbol_stack.back(); if(newSymTable == nullptr) newSymTable = new symbol_table(); symbol_entry entry(node->lexinfo, newSymbol); newSymTable->insert(entry); symbol_stack.push_back(newSymTable); //type checking if it is the return value of function, error otherwise //check if children containes function or type_id //may only be used as the return type of a function. //It is an error to declare variables, parameters, //or fields of this type. //fprintf(stderr, "file number %ld:%ld:%ld:error: //PUT ERROR MESSAGE HERE ON TYPE CHECKING\n",newSymbol->filenr, //newSymbol->linenr,newSymbol->offset); } break; case NUL: { newSymbol->attributes[ATTR_null]=true; newSymbol->attributes[ATTR_const]=true; newSymbol->fields = nullptr; newSymbol->parameters = nullptr; newSymbol->blocknum = next_block; auto newSymTable = symbol_stack.back(); if(newSymTable == nullptr) newSymTable = new symbol_table(); symbol_entry entry(node->lexinfo, newSymbol); newSymTable->insert(entry); symbol_stack.push_back(newSymTable); //type check if it is a constant, and only if its a constant //null : has the single constant null. The syntax prevents it //from being used in a type declaration. } break; case ORD: { newSymbol->attributes[ATTR_vreg]=true; newSymbol->fields = nullptr; newSymbol->parameters = nullptr; newSymbol->blocknum = 0; auto newSymTable = symbol_stack.back(); if(newSymTable == nullptr) newSymTable = new symbol_table(); symbol_entry entry(node->lexinfo, newSymbol); newSymTable->insert(entry); symbol_stack.push_back(newSymTable); //type check if 'ord' char → int vreg } break; case CHR: { newSymbol->attributes[ATTR_vreg]=true; newSymbol->fields = nullptr; newSymbol->parameters = nullptr; newSymbol->blocknum = 0; auto newSymTable = symbol_stack.back(); if(newSymTable == nullptr) newSymTable = new symbol_table(); symbol_entry entry(node->lexinfo, newSymbol); newSymTable->insert(entry); symbol_stack.push_back(newSymTable); //type check if ‘chr’ int → char vreg } break; case ARRAY: { newSymbol->blocknum = next_block; newSymbol->attributes[ATTR_array]=true; newSymbol->fields = nullptr; newSymbol->parameters = nullptr; auto newSymTable = symbol_stack.back(); if(newSymTable == nullptr) newSymTable = new symbol_table(); symbol_entry entry(node->lexinfo, newSymbol); newSymTable->insert(entry); symbol_stack.push_back(newSymTable); //type check: //base[]: contains a collection of other elements, //all of which are of the same type, which may be either //primitive or reference types. Its base type may not be an array type. //This is the only polymorphic type. } break; case RETURN: { newSymbol->attributes[ATTR_vaddr]=true; newSymbol->fields = nullptr; newSymbol->parameters = nullptr; symbol* symbolFound = nullptr; symbolFound = traverse_block(*symbol_stack.back(), tname); // type check if ‘return’ compatible → auto newSymTable = symbol_stack.back(); if(newSymTable == nullptr) newSymTable = new symbol_table(); symbol_entry entry(node->lexinfo, newSymbol); newSymTable->insert(entry); symbol_stack.push_back(newSymTable); } break; case CALL: { newSymbol->attributes[ATTR_vreg] = true; newSymbol->fields = nullptr; newSymbol->parameters = nullptr; auto newSymTable = symbol_stack.back(); if(newSymTable == nullptr) newSymTable = new symbol_table(); symbol_entry entry(node->lexinfo, newSymbol); newSymTable->insert(entry); symbol_stack.push_back(newSymTable); } break; case BOOL: { newSymbol->blocknum = next_block; newSymbol->attributes[ATTR_bool]=true; newSymbol->attributes[ATTR_const]=true; newSymbol->fields = nullptr; newSymbol->parameters = nullptr; auto newSymTable = symbol_stack.back(); if(newSymTable == nullptr) newSymTable = new symbol_table(); symbol_entry entry(node->lexinfo, newSymbol); newSymTable->insert(entry); symbol_stack.push_back(newSymTable); //type check: bool : has constants false and true, and is an 8-bit byte. } break; case CHAR: { newSymbol->blocknum = next_block; newSymbol->attributes[ATTR_char]=true; newSymbol->attributes[ATTR_const]=true; newSymbol->fields = nullptr; newSymbol->parameters = nullptr; auto newSymTable = symbol_stack.back(); if(newSymTable == nullptr) newSymTable = new symbol_table(); symbol_entry entry(node->lexinfo, newSymbol); newSymTable->insert(entry); symbol_stack.push_back(newSymTable); //type check : //char: isan8-bitbyte. Valuesbetween0x00and0x7FareASCIIcharacters, and values between 0x80 and 0xFF are locale dependent. } break; case INT: { newSymbol->blocknum = next_block; newSymbol->attributes[ATTR_int]=true; newSymbol->attributes[ATTR_const]=true; newSymbol->fields = nullptr; newSymbol->parameters = nullptr; auto newSymTable = symbol_stack.back(); if(newSymTable == nullptr) newSymTable = new symbol_table(); symbol_entry entry(node->lexinfo, newSymbol); newSymTable->insert(entry); symbol_stack.push_back(newSymTable); //type check: is a signed two’s complement integer. } break; case STRING: { newSymbol->blocknum = next_block; newSymbol->attributes[ATTR_string]=true; newSymbol->attributes[ATTR_const]=true; newSymbol->fields = nullptr; newSymbol->parameters = nullptr; auto newSymTable = symbol_stack.back(); if(newSymTable == nullptr) newSymTable = new symbol_table(); symbol_entry entry(node->lexinfo, newSymbol); newSymTable->insert(entry); symbol_stack.push_back(newSymTable); //type check: string: is effectivly an array of characters // and has string constants associ- ated with it. Its size //is fixed when allocated. The length of the string con- tained in // the array varies up to the maximum allocated length, depending on //where the null plug (’\0’) is placed. Strings are stored in the same for- mat as in C. } break; case FIELD: { newSymbol->blocknum = next_block; newSymbol->attributes[ATTR_field]=true; newSymbol->attributes[ATTR_lval]=true; newSymbol->fields = nullptr; newSymbol->parameters = nullptr; symbol* symbolFound = nullptr; //type check: //Field names are identifiers which may only be //used immedi- ately following the dot (.) operator for field selection. symbolFound = traverse_block(*symbol_stack.back(), tname); if(symbolFound == nullptr){ //add to symbol table auto newSymTable = symbol_stack.back(); if(newSymTable == nullptr) newSymTable = new symbol_table(); symbol_entry entry(node->lexinfo, newSymbol); newSymTable->insert(entry); } else { //don't add but update if it's already there //error } } break; case VARDECL: { newSymbol->blocknum = next_block; newSymbol->attributes[ATTR_field]=true; newSymbol->attributes[ATTR_lval]=true; newSymbol->fields = nullptr; newSymbol->parameters = nullptr; symbol* symbolFound = nullptr; //Whenever you see a variable declaration, //look it up in the symbol table. Print a duplicate declaration //error message if it is in the symbol table at the top of the symbol // vector stack. symbolFound = traverse_block(*symbol_stack.back(), tname); if(symbolFound == nullptr){ //add to symbol table auto newSymTable = symbol_stack.back(); if(newSymTable == nullptr) newSymTable = new symbol_table(); symbol_entry entry(node->lexinfo, newSymbol); newSymTable->insert(entry); } else{ symbolFound = newSymbol; } } break; case IDENT: { newSymbol->blocknum = next_block; newSymbol->attributes[ATTR_field]=true; newSymbol->attributes[ATTR_lval]=true; newSymbol->fields = nullptr; newSymbol->parameters = nullptr; symbol* symbolFound = nullptr; //Whenever you see a variable declaration, //look it up in the symbol table. Print a duplicate declaration //error message if it is in the symbol table at the top of the symbol // vector stack. symbolFound = traverse_block(*symbol_stack.back(), tname); if(symbolFound == nullptr){ //add to symbol table auto newSymTable = symbol_stack.back(); if(newSymTable == nullptr) newSymTable = new symbol_table(); symbol_entry entry(node->lexinfo, newSymbol); newSymTable->insert(entry); } else{ symbolFound = newSymbol; } } break; case DECLID: { newSymbol->blocknum = next_block; newSymbol->attributes[ATTR_function]=true; newSymbol->fields = nullptr; newSymbol->parameters = nullptr; symbol* symbolFound = nullptr; printf("declid: test 0\n"); if(symbol_stack.back() != nullptr ) symbolFound = traverse_block(*symbol_stack.back(), tname); printf("declid: test 1\n"); if(symbolFound == nullptr){ //add to symbol table printf("declid: test 2\n"); auto newSymTable = symbol_stack.back(); if(newSymTable == nullptr) newSymTable = new symbol_table(); printf("declid: test 3\n"); symbol_entry entry(node->lexinfo, newSymbol); printf("declid: test 4\n"); newSymTable->insert(entry); printf("declid: test 5\n"); } else{ //not the same type //error printf("declid: test 6\n"); } } break; case FIELDS: { newSymbol->attributes[ATTR_typeid]=true; newSymbol->attributes[ATTR_struct] = true; newSymbol->blocknum = 0; symbol* symbolFound = nullptr; symbolFound = traverse_block(*symbol_stack.back(), tname); /* for (size_t child = 0; child < node->children.size(); ++child) { symbol* newChildSymbol = new symbol(); symbol_entry entry(node->lexinfo, newChildSymbol); newSymbol->fields = new symbol_table(); newSymbol->fields->insert(entry); } */ newSymbol->parameters = nullptr; if(symbolFound == nullptr){ //add to symbol table auto newSymTable = symbol_stack.back(); if(newSymTable == nullptr) newSymTable = new symbol_table(); symbol_entry entry(node->lexinfo, newSymbol); newSymTable->insert(entry); } else{ //don't add but update if it's already there //error } } break; case TYPEID: { newSymbol->attributes[ATTR_typeid]=true; newSymbol->attributes[ATTR_struct] = true; newSymbol->blocknum = 0; symbol* symbolFound = nullptr; symbolFound = traverse_block(*symbol_stack.back(), tname); /* for (size_t child = 0; child < node->children.size(); ++child) { symbol* newChildSymbol = new symbol(); symbol_entry entry(node->lexinfo, newChildSymbol); newSymbol->fields = new symbol_table(); newSymbol->fields->insert(entry); } */ newSymbol->parameters = nullptr; if(symbolFound == nullptr){ //add to symbol table auto newSymTable = symbol_stack.back(); if(newSymTable == nullptr) newSymTable = new symbol_table(); symbol_entry entry(node->lexinfo, newSymbol); newSymTable->insert(entry); } else{ //don't add but update if it's already there //error } } break; case PROTOTYPE: { newSymbol->attributes[ATTR_function]=true; newSymbol->blocknum = 0; symbol* symbolFound = nullptr; //type check in block 0 of stack if //there is a prototype for the function declared already symbolFound = traverse_block(*symbol_stack.back(), tname); /* for (size_t child = 0; child < node->children.size(); ++child) { symbol* newChildSymbol = new symbol(); auto tname = get_yytname (node->children[child]->symbol); if (strstr (tname, "TOK_") == tname) tname += 4; auto newSymParams = newSymbol->parameters; newSymParams->push_back(newChildSymbol); } */ if(symbolFound == nullptr){ //add to symbol table auto newSymTable = symbol_stack.back(); if(newSymTable == nullptr) newSymTable = new symbol_table(); printf("prototype test: 3\n"); symbol_entry entry(node->lexinfo, newSymbol); printf("prototype test: 4\n"); newSymTable->insert(entry); printf("prototype test: 5\n"); } else{ //don't add but update if it's already there //error } } break; case FUNCTION: { newSymbol->attributes[ATTR_function]=true; newSymbol->blocknum = 0; symbol* symbolFound = nullptr; //type check in block 0 of stack if //there is a prototype for the function declared already symbolFound = traverse_block(*symbol_stack.back(), tname); /* for (size_t child = 0; child < node->children.size(); ++child) { newSymbol->blocknum = 0; symbol* newChildSymbol = new symbol(); symbol_entry entry(node->lexinfo, newChildSymbol); newSymbol->fields = new symbol_table(); newSymbol->fields->insert(entry); } for (size_t child = 0; child < node->children.size(); ++child) { symbol* newChildSymbol = new symbol(); auto tname = get_yytname (node->children[child]->symbol); if (strstr (tname, "TOK_") == tname) tname += 4; auto newSymParams = newSymbol->parameters; newSymParams->push_back(newChildSymbol); } */ if(symbolFound == nullptr){ //add to symbol table auto newSymTable = symbol_stack.back(); if(newSymTable == nullptr) newSymTable = new symbol_table(); symbol_entry entry(node->lexinfo, newSymbol); newSymTable->insert(entry); } else{ //don't add but update if it's already there //error because function is already there } } break; case PARAMLIST: { newSymbol->attributes[ATTR_param]=true; newSymbol->blocknum = next_block; newSymbol->parameters = nullptr; /* for (size_t child = 0; child < node->children.size(); ++child) { symbol* newChildSymbol = new symbol(); symbol_entry entry(node->lexinfo, newChildSymbol); newSymbol->fields = new symbol_table(); newSymbol->fields->insert(entry); } */ //add to symbol table auto newSymTable = symbol_stack.back(); if(newSymTable == nullptr) newSymTable = new symbol_table(); symbol_entry entry(node->lexinfo, newSymbol); newSymTable->insert(entry); } break; default: printf("newSymbol wasn't anything accounted for \n"); } }
void visit(astree *node) { if (node == NULL) return; switch(node->symbol) { fprintf(oil_file, "%s\n", get_yytname(node->symbol)); } }