예제 #1
0
Structure Evaluator::evalProgram(const ASTNode& node) {
  Structure ret;
  assert(node.kind() == NodeKind::program);
  for (const auto& exp : node.children()) {
    ret = eval(exp);
  }
  return ret;
}
예제 #2
0
std::vector<Structure> Evaluator::evalParameters(const ASTNode& node) {
  if (node.kind() == NodeKind::optionalParameterList) {
    auto children = node.children();
    if (children.size() == 0) {
      return std::vector<Structure>();
    }
    assert(children.size() == 1);
    return evalParameters(children[0]);
  }

  assert(node.kind() == NodeKind::parameterList);
  std::vector<Structure> ret;
  for (const auto& child : node.children()) {
    ret.push_back(eval(child));
  }
  return ret;
}
예제 #3
0
Structure Evaluator::evalLiteral(const ASTNode& node) {
  assert(node.kind() == NodeKind::literal);
  auto children = node.children();
  assert(children.size() == 1);
  const auto& child = children[0];
  switch (child.kind()) {
    case NodeKind::integer:
      return Structure(child.integer());
    case NodeKind::floatingPoint:
      return Structure(child.floatingPoint());
    default:
      assert(child.kind() == NodeKind::string);
      return Structure(child.string());
  }
}
예제 #4
0
Structure Evaluator::evalLetExpression(const ASTNode& node) {
  assert(node.kind() == NodeKind::expression);
  const auto children = node.children();
  assert(children.size() == 2);
  assert(children[0].kind() == NodeKind::identifier &&
         children[0].string() == "let");
  assert(children[1].kind() == NodeKind::optionalParameterList);
  const auto parameterList = children[1].children()[0];
  const auto id_with_value = parameterList.children();
  assert(id_with_value.size() == 2);
  const auto& id = id_with_value[0];
  assert(id.kind() == NodeKind::identifier);
  m_symbols[id.string()] = eval(id_with_value[1]);
  return Structure(true);
}
예제 #5
0
Structure Evaluator::evalIfExpression(const ASTNode& node) {
  assert(node.kind() == NodeKind::expression);
  const auto children = node.children();
  assert(children.size() == 2);
  assert(children[0].kind() == NodeKind::identifier &&
         children[0].string() == "if");
  assert(children[1].kind() == NodeKind::optionalParameterList);
  const auto parameters = children[1].children()[0].children();
  assert(parameters.size() == 3);
  const auto condition = this->eval(parameters[0]);
  if (condition) {
    return this->eval(parameters[1]);
  } else {
    return this->eval(parameters[2]);
  }
}
예제 #6
0
Structure Evaluator::evalLambdaExpression(const ASTNode& node) {
  assert(node.kind() == NodeKind::expression);
  const auto& children = node.children();
  assert(children.size() == 2);
  assert(children[0].kind() == NodeKind::identifier &&
         children[0].string() == "lambda");
  assert(children[1].kind() == NodeKind::optionalParameterList);
  const auto& parameterList = children[1].children()[0].children();
  return Structure(static_cast<Structure::Function>(
    [this, parameterList]
    (const ASTNode& node, std::vector<Structure> params) {
      SymbolTable symbols = m_symbols.augment(dictOfParams(parameterList, params));
      Evaluator e(symbols);
      const auto& body = parameterList[parameterList.size()-1];
      return e.eval(body);
    }
  ));
}
예제 #7
0
Structure Evaluator::evalCondExpression(const ASTNode& node) {
  assert(node.kind() == NodeKind::expression);
  const auto children = node.children();
  assert(children.size() == 2);
  assert(children[0].kind() == NodeKind::identifier &&
         children[0].string() == "cond");
  assert(children[1].kind() == NodeKind::optionalParameterList);
  const auto parameters = children[1].children()[0].children();
  if (parameters.size() % 2 != 0) {
    throw RuntimeError(children[1], "cond must take an even number of parameters (pairs of condition and expression)");
  }
  for (size_t i=0; i<parameters.size(); i+=2) {
    const auto condition = this->eval(parameters[i]);
    if (condition) {
      return this->eval(parameters[i+1]);
    }
  }
  throw RuntimeError(children[1], "`cond` expression did not return a value (no condition evaluated to true)");
}
예제 #8
0
Structure Evaluator::evalExpression(const ASTNode& node) {
  assert(node.kind() == NodeKind::expression);
  const auto& children = node.children();
  assert(children.size() == 2);
  if (children[0].kind() == NodeKind::identifier) {
    if (children[0].string() == "lambda") {
      return this->evalLambdaExpression(node);
    } else if (children[0].string() == "let") {
      return this->evalLetExpression(node);
    } else if (children[0].string() == "if") {
      return this->evalIfExpression(node);
    } else if (children[0].string() == "cond") {
      return this->evalCondExpression(node);
    }
  }

  Structure fn = eval(children[0]);
  std::vector<Structure> params = evalParameters(children[1]);
  return fn(node, params);
}