bool ValueProcessor::validateValue(TokenList::const_iterator &i, TokenList::const_iterator &end, const ValueScope &scope, bool defaultVal) const { const Token *reference; Value *v; const BooleanValue trueVal(true); bool ret; if (i == end) return false; reference = &(*i); v = processStatement(i, end, scope, defaultVal); if (v == NULL) { throw new ParseException(*reference, "condition", reference->line, reference->column, reference->source); } ret = (*v == trueVal); delete v; return ret; }
Value *ValueProcessor::processSubstatement(TokenList::const_iterator &i, TokenList::const_iterator &end, const ValueScope &scope, bool defaultVal) const { Value *ret; TokenList::const_iterator i2 = i; if (i == end || (*i).type != Token::PAREN_OPEN) return NULL; i2++; ret = processStatement(i2, end, scope, defaultVal); if (ret == NULL) return NULL; ret->setLocation(*i); skipWhitespace(i2, end); if (i2 == end || (*i2).type != Token::PAREN_CLOSED) { delete ret; return NULL; } i2++; i = i2; return ret; }
Value *ValueProcessor::processStatement(const TokenList &tokens, const ValueScope &scope) const { TokenList::const_iterator i = tokens.begin(); TokenList::const_iterator end = tokens.end(); Value *ret = processStatement(i, end, scope); if (i != end) return NULL; return ret; }
bool ValueProcessor::processArguments(TokenList::const_iterator &i, TokenList::const_iterator &end, const ValueScope &scope, vector<const Value *> &arguments) const { Value *argument; if (i == end) return false; if ((*i).type != Token::PAREN_CLOSED) { argument = processStatement(i, end, scope); if (argument != NULL) arguments.push_back(argument); else { arguments.push_back(new StringValue(*i, false)); i++; } } while (i != end && ((*i) == "," || (*i) == ";")) { i++; argument = processStatement(i, end, scope); if (argument != NULL) { arguments.push_back(argument); } else if ((*i).type != Token::PAREN_CLOSED) { arguments.push_back(new StringValue(*i, false)); i++; } } if (i == end) throw new ParseException("end of value", ")", 0, 0, ""); if ((*i).type != Token::PAREN_CLOSED) throw new ParseException(*i, ")", (*i).line, (*i).column, (*i).source); i++; return true; }
void processFunction(SymbolTable *table, Node *ptr) { int stIndex, i; char *functionName; Node *p; int width = 0; functionName = ptr->son->son->next->token.tokenValue; flag_returned = 0; stIndex = lookup(table, functionName); SymbolTable *nextTable = table->rows[stIndex].table; // parameters if (ptr->son->son->next->next->son) { for (p = ptr->son->son->next->next->son; p; p = p->next) { if (p->token.tokenNumber == PARAM_DCL) { processDeclaration(nextTable, p->son); // todo } else { icg_error(9); } } } for (p = ptr->son->next->son->son; p; p = p->next) { if (p->token.tokenNumber == DCL) { processDeclaration(nextTable, p->son); // todo } else { icg_error(3); } } emitProc(functionName, nextTable->offset - 1, nextTable->base, 2); // 지역변수 for (i = 0; i < nextTable->count; i++) { emitSym("sym", nextTable->base, nextTable->rows[i].offset, nextTable->rows[i].width); } // Run Statement for (p = ptr->son; p; p = p->next) { if (p->token.tokenNumber == COMPOUND_ST) { processStatement(nextTable, p); } } if (!flag_returned) { emit0("ret"); } emit0("end"); }
Value *ValueProcessor::processConstant(TokenList::const_iterator &i, TokenList::const_iterator &end, const ValueScope &scope, bool defaultVal) const { Token token; Value *ret; const TokenList *var; TokenList variable; bool hasQuotes; std::string str; if (i == end) return NULL; token = *i; switch (token.type) { case Token::HASH: i++; // generate color from hex value return new Color(token); case Token::NUMBER: case Token::PERCENTAGE: case Token::DIMENSION: i++; return new NumberValue(token); case Token::ATKEYWORD: if ((var = scope.getVariable(token)) != NULL) { variable = *var; ret = processStatement(variable, scope); if (ret != NULL) { i++; //ret->setLocation(token); return ret; } } return NULL; case Token::STRING: i++; hasQuotes = token.stringHasQuotes(); interpolate(token, scope); token.removeQuotes(); return new StringValue(token, hasQuotes); case Token::URL: i++; interpolate(token, scope); str = token.getUrlString(); return new UrlValue(token, str); case Token::IDENTIFIER: i++; if (i != end && (*i).type == Token::PAREN_OPEN) { if (token == "default") { i++; if ((*i).type != Token::PAREN_CLOSED) { throw new ParseException(*i, ")", (*i).line, (*i).column, (*i).source); } return new BooleanValue(token, defaultVal); } else if (functionExists(token.c_str())) { i++; ret = processFunction(token, i, end, scope); if (ret == NULL) { i--; i--; return NULL; } else return ret; } else { i--; return NULL; } } else if (token.compare("true") == 0) { return new BooleanValue(token, true); } else if ((ret = processUnit(token)) != NULL) { return ret; } else if ((ret = Color::fromName(token)) != NULL) { return ret; } else { return new StringValue(token, false); } case Token::PAREN_OPEN: return processSubstatement(i, end, scope, defaultVal); default: break; } if ((var = processDeepVariable(i, end, scope)) != NULL) { variable = *var; ret = processStatement(variable, scope); if (ret != NULL) { //ret->setLocation(token); } return ret; } if (token == "%") { i++; if (i != end && (*i).type == Token::PAREN_OPEN) { i++; if ((ret = processFunction(token, i, end, scope)) != NULL) return ret; i--; } i--; } if ((ret = processEscape(i, end, scope)) != NULL) { return ret; } else if ((ret = processNegative(i, end, scope)) != NULL) { return ret; } return NULL; }
void ValueProcessor::processValue(TokenList &value, const ValueScope &scope) const { TokenList::iterator i; TokenList newvalue; Value *v; const TokenList *var; TokenList variable; const TokenList *oldvalue = &value; TokenList::const_iterator i2, itmp, end; if (!needsProcessing(value)) { // interpolate strings for (i = value.begin(); i != value.end(); i++) { if ((*i).type == Token::STRING) interpolate((*i), scope); } return; } end = oldvalue->end(); for (i2 = oldvalue->begin(); i2 != end;) { try { itmp = i2; v = processStatement(itmp, end, scope); i2 = itmp; } catch (ValueException*) { v = NULL; } // add spaces between values if (v != NULL || i2 != end) { if (newvalue.size() == 0 || !needsSpace(newvalue.back(), false) || (v == NULL && !needsSpace(*i2, true))) { } else { newvalue.push_back(Token::BUILTIN_SPACE); } } if (v != NULL) { var = v->getTokens(); newvalue.insert( newvalue.end(), var->begin(), var->end()); var = NULL; delete v; } else if (i2 != end) { // variable containing a non-value. if ((*i2).type == Token::ATKEYWORD && (var = scope.getVariable(*i2)) != NULL) { variable = *var; processValue(variable, scope); newvalue.insert(newvalue.end(), variable.begin(), variable.end()); i2++; // deep variable } else if ((var = processDeepVariable(i2, end, scope)) != NULL) { variable = *var; processValue(variable, scope); newvalue.insert(newvalue.end(), variable.begin(), variable.end()); } else if ((*i2).type == Token::IDENTIFIER) { newvalue.push_back(*i2); i2++; if (i2 != end && (*i2).type == Token::PAREN_OPEN) { newvalue.push_back(*i2); i2++; } } else { newvalue.push_back(*i2); i2++; } } } value = newvalue; return; }
void processStatement(SymbolTable *table, Node *ptr) { Node *p; char label1[LABEL_SIZE]={0}, label2[LABEL_SIZE]={0}; switch(ptr->token.tokenNumber) { case COMPOUND_ST: p = ptr->son->next; p = p->son; while (p) { processStatement(table, p); p = p->next; } break; case EXP_ST: if (ptr->son != NULL) { processOperator(table, ptr->son); } break; case RETURN_ST: if (ptr->son != NULL) { p = ptr->son; if (p->noderep == NONTERM) { processOperator(table, p); } else { rv_emit(table, p); } emit0("retv"); } else emit0("ret"); flag_returned=1; break; case IF_ST: genLabel(label1); processCondition(table, ptr->son); emitJump("fjp", label1); processStatement(table, ptr->son->next); emitLabel(label1); break; case IF_ELSE_ST: genLabel(label1); genLabel(label2); processCondition(table, ptr->son); emitJump("fjp", label1); processStatement(table, ptr->son->next); emitJump("ujp", label2); emitLabel(label1); processStatement(table, ptr->son->next->next); emitLabel(label2); break; case WHILE_ST: genLabel(label1); genLabel(label2); emitLabel(label1); processCondition(table, ptr->son); emitJump("fjp", label2); processStatement(table, ptr->son->next); emitJump("ujp", label1); emitLabel(label2); break; default: fprintf(file, "not yet implemented.\n"); break; } }