Compound assigments

This commit is contained in:
Robert Bendun 2022-06-06 04:22:59 +02:00
parent 91eaa0ceea
commit d16f6de53c
3 changed files with 28 additions and 2 deletions

View File

@ -1,6 +1,6 @@
{ {
"returncode": 0, "returncode": 0,
"stdout": "1\n2\n6\n24\n120\n720\n5040\n40320\n362880\n3628800\n", "stdout": "1\n2\n6\n24\n120\n720\n5040\n40320\n362880\n3628800\n1\n2\n6\n24\n120\n720\n5040\n40320\n362880\n3628800\n",
"stderr": "", "stderr": "",
"flags": [] "flags": []
} }

View File

@ -5,5 +5,11 @@ var for = [ start stop iteration |
]; ];
var factorial = [n | if (n <= 1) [1] [n * (factorial (n-1))]]; var factorial = [n | if (n <= 1) [1] [n * (factorial (n-1))]];
for 1 10 [i | say (factorial i)]; for 1 10 [i | say (factorial i)];
var factorial_iterative = [n |
var x = 1;
for 1 n [i|x *= i];
x
];
for 1 10 [i | say (factorial_iterative i)];

View File

@ -490,6 +490,7 @@ Result<Value> Interpreter::eval(Ast &&ast)
return *v = Try(eval(std::move(rhs))); return *v = Try(eval(std::move(rhs)));
} }
if (ast.token.source == "and" || ast.token.source == "or") { if (ast.token.source == "and" || ast.token.source == "or") {
auto lhs = std::move(ast.arguments.front()); auto lhs = std::move(ast.arguments.front());
auto rhs = std::move(ast.arguments.back()); auto rhs = std::move(ast.arguments.back());
@ -504,6 +505,25 @@ Result<Value> Interpreter::eval(Ast &&ast)
auto op = operators.find(std::string(ast.token.source)); auto op = operators.find(std::string(ast.token.source));
if (op == operators.end()) { if (op == operators.end()) {
if (ast.token.source.ends_with('=')) {
auto op = operators.find(std::string(ast.token.source.substr(0, ast.token.source.size()-1)));
if (op == operators.end()) {
return Error {
.details = errors::Undefined_Operator { .op = ast.token.source },
.location = ast.token.location
};
}
auto lhs = std::move(ast.arguments.front());
auto rhs = std::move(ast.arguments.back());
assert(lhs.type == Ast::Type::Literal && lhs.token.type == Token::Type::Symbol,
"Currently LHS of assigment must be an identifier"); // TODO(assert)
Value *v = env->find(std::string(lhs.token.source));
assert(v, "Cannot resolve variable: "s + std::string(lhs.token.source)); // TODO(assert)
return *v = Try(op->second(*this, { *v, Try(eval(std::move(rhs))) }));
}
return Error { return Error {
.details = errors::Undefined_Operator { .op = ast.token.source }, .details = errors::Undefined_Operator { .op = ast.token.source },
.location = ast.token.location .location = ast.token.location