Add a let() expression

master
Oskar Linde 2014-04-16 17:11:01 +02:00
parent b984297e28
commit ed3041c551
4 changed files with 34 additions and 1 deletions

View File

@ -170,6 +170,16 @@ Value Expression::evaluate(const Context *context) const
EvalContext c(context, this->call_arguments);
return context->evaluate_function(this->call_funcname, &c);
}
if (this->type == "l") { // let expression
EvalContext let_context(context, this->call_arguments);
Context c(context);
for (int i = 0; i < let_context.numArgs(); i++) {
// NOTE: iteratively evaluated list of arguments
c.set_variable(let_context.getArgName(i), let_context.getArgValue(i, &c));
}
return this->children[0]->evaluate(&c);
}
abort();
}
@ -229,6 +239,17 @@ std::string Expression::toString() const
}
stream << ")";
}
else if (this->type == "l") {
stream << "let(";
for (size_t i=0; i < this->call_arguments.size(); i++) {
const Assignment &arg = this->call_arguments[i];
if (i > 0) stream << ", ";
if (!arg.first.empty()) stream << arg.first << " = ";
stream << *arg.second;
}
stream << ") ";
stream << *this->children[0];
}
else {
assert(false && "Illegal expression type");
}

View File

@ -219,7 +219,7 @@ Highlighter::Highlighter(QTextDocument *parent)
{
tokentypes["operator"] << "=" << "!" << "&&" << "||" << "+" << "-" << "*" << "/" << "%" << "!" << "#" << ";";
tokentypes["math"] << "abs" << "sign" << "acos" << "asin" << "atan" << "atan2" << "sin" << "cos" << "floor" << "round" << "ceil" << "ln" << "log" << "lookup" << "min" << "max" << "pow" << "sqrt" << "exp" << "rands";
tokentypes["keyword"] << "module" << "function" << "for" << "intersection_for" << "if" << "assign" << "echo"<< "search" << "str";
tokentypes["keyword"] << "module" << "function" << "for" << "intersection_for" << "if" << "assign" << "echo"<< "search" << "str" << "let";
tokentypes["transform"] << "scale" << "translate" << "rotate" << "multmatrix" << "color" << "projection" << "hull" << "resize" << "mirror" << "minkowski";
tokentypes["csgop"] << "union" << "intersection" << "difference" << "render";
tokentypes["prim3d"] << "cube" << "cylinder" << "sphere" << "polyhedron";

View File

@ -142,6 +142,7 @@ use[ \t\r\n>]*"<" { BEGIN(cond_use); }
"function" return TOK_FUNCTION;
"if" return TOK_IF;
"else" return TOK_ELSE;
"let" return TOK_LET;
"true" return TOK_TRUE;
"false" return TOK_FALSE;

View File

@ -84,6 +84,7 @@ std::string parser_source_path;
%token TOK_FUNCTION
%token TOK_IF
%token TOK_ELSE
%token TOK_LET
%token <text> TOK_ID
%token <text> TOK_STRING
@ -96,6 +97,8 @@ std::string parser_source_path;
%token LE GE EQ NE AND OR
%right LET
%right '?' ':'
%left OR
@ -324,6 +327,14 @@ expr:
{
$$ = new Expression(Value($1));
}
| TOK_LET '(' arguments_call ')' expr %prec LET
{
$$ = new Expression();
$$->type = "l";
$$->call_arguments = *$3;
delete $3;
$$->children.push_back($5);
}
| '[' expr ':' expr ']'
{
$$ = new Expression();