void Pass1::accept_extern_decl(ParseNode *node) { std::list<ParseNode *>::iterator i = node->children.begin(); assert((*i)->token == KEYWORD_EXTERN); ++i; // i -> prototype-type assert((*i)->token == RULE_PROTOTYPE_D_TYPE); assert((*i)->children.size() == 1); ParseNode *typeident = (*i)->children.front(); assert(typeident->token == CTokenEnums::TOKEN_IDENT); Size size = get_exact_size(typeident->text); if(size.scalar == 0) { throw ParseError(std::string("Externals must have exact size - given: ") + typeident->text, node->lineNum, node->fileNum, __LINE__ ); } ++i; // go to first extern for(;;) { ///std::cout << size.exact_size_string() << " - " << (*i)->text << std::endl; bool ok = add_extern((*i)->text, size); if(!ok) { throw ParseError("Name already exists - " + (*i)->text, node->lineNum, node->fileNum, __LINE__ ); } ++i; assert(i != node->children.end()); if((*i)->token != ',') break; ++i; // skip comma } }
/********************************************//** * Name: * parse_line * * Params: * *comp - A pointer to a compiler. * * Description: * This function will parse the lines. * it will is the standard libraries strtok() function * to break the line in to tokens for further processing. * * Return: * 1 There was a problem parsing the line. * 0 The line was parsed successfully. * ***********************************************/ int parse_line(Compiler *comp) { //Create local copy of line so strtok() doesn't destroy the original. char *symbol = NULL; char *locLine = (char *) malloc(sizeof(char) * MAX_LINE_LEN); strcpy(locLine, comp->line); char *token = strtok(locLine, " \r\t\n"); //Check if the line is empty, if it is stop the processing. if (token == NULL) return 0; //Check if the line is a comment, if it is stop the processing. if (strstr(token, ";") != NULL) return 0; //Check if optional label exists, if it does set symbol parameter, and get next token. if ((strstr(token, ":")) != NULL) { symbol = token; CUT_LAST_CHAR(symbol); token = strtok(NULL, " \r\t\n"); } //Check if the line is .entry if (strstr(comp->line, ".entry") != NULL) { token = strtok(NULL, " \r\t\n"); add_entry(comp, token); if (symbol != NULL) add_symbol(comp, symbol, DATA); return 0; } //Check if the line is .extern if (strstr(comp->line, ".extern") != NULL) { token = strtok(NULL, " \r\t\n"); add_extern(comp, token); if (symbol != NULL) add_symbol(comp, symbol, DATA); return 0; } //Check if the line is .data if (strstr(comp->line, ".data") != NULL) { if (symbol != NULL) add_symbol(comp, symbol, DATA); token = strtok(NULL, " \r\t\n"); add_data(comp, atoi(token)); return 0; } //Check if the line is .string if (strstr(comp->line, ".string") != NULL) { if (symbol != NULL) add_symbol(comp, symbol, DATA); token = strtok(NULL, " \r\t\n"); if (is_valid_string(token)) add_string(comp, token); else add_error(comp, comp->fileName, comp->lineIdx, "Missing \"\n"); return 0; } //if we got here the the line is code, if it has an optional symbol add it to symbol table. if (symbol != NULL) add_symbol(comp, symbol, CODE); //Add code to the compiler and check if the addition was successful. if (!add_code(comp, token, strtok(NULL, " \r\t\n"), strtok(NULL, ","))) { //Update the codeLen and dataLen fields comp->codeLen = comp->IC; comp->dataLen = comp->DC; free(locLine); return 0; } add_error(comp, comp->fileName, comp->lineIdx, "Incorrect line definition."); return 1; }