예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
파일: ucode.c 프로젝트: wan2land/mini-c
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");
}
예제 #6
0
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;
}
예제 #7
0
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;
}
예제 #8
0
파일: ucode.c 프로젝트: wan2land/mini-c
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;
    }
}