Evaluation support variable resolution

This commit is contained in:
Robert Bendun 2022-05-17 02:49:21 +02:00
parent 5d51d1672f
commit e7cb2de198

View File

@ -69,7 +69,17 @@ Result<Value> Interpreter::eval(Ast &&ast)
{ {
switch (ast.type) { switch (ast.type) {
case Ast::Type::Literal: case Ast::Type::Literal:
return Value::from(ast.token); switch (ast.token.type) {
case Token::Type::Symbol:
{
auto const value = env().find(std::string(ast.token.source));
assert(value, "Missing variable error is not implemented yet");
return *value;
}
default:
return Value::from(ast.token);
}
case Ast::Type::Binary: case Ast::Type::Binary:
{ {
@ -100,21 +110,23 @@ Result<Value> Interpreter::eval(Ast &&ast)
case Ast::Type::Call: case Ast::Type::Call:
{ {
auto location = ast.arguments.front().location;
Value func = Try(eval(std::move(ast.arguments.front()))); Value func = Try(eval(std::move(ast.arguments.front())));
if (func.type != Value::Type::Symbol)
return errors::not_callable(std::move(location), func.type);
if (auto body = env().find(func.s); body) { std::vector<Value> values;
std::vector<Value> values; values.reserve(ast.arguments.size());
values.reserve(ast.arguments.size()); for (auto& a : std::span(ast.arguments).subspan(1)) {
for (auto& a : std::span(ast.arguments).subspan(1)) { values.push_back(Try(eval(std::move(a))));
values.push_back(Try(eval(std::move(a))));
}
return (*body)(std::move(values));
} else {
return errors::function_not_defined(func);
} }
return std::move(func)(std::move(values));
}
case Ast::Type::Variable_Declaration:
{
assert(ast.arguments.size() == 2, "Only simple assigments are supported now");
assert(ast.arguments.front().type == Ast::Type::Literal, "Only names are supported as LHS arguments now");
assert(ast.arguments.front().token.type == Token::Type::Symbol, "Only names are supported as LHS arguments now");
env().force_define(std::string(ast.arguments.front().token.source), Try(eval(std::move(ast.arguments.back()))));
return Value{};
} }
default: default: