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); EvalContext c(context, this->call_arguments);
return context->evaluate_function(this->call_funcname, &c); 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(); abort();
} }
@ -229,6 +239,17 @@ std::string Expression::toString() const
} }
stream << ")"; 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 { else {
assert(false && "Illegal expression type"); assert(false && "Illegal expression type");
} }

View File

@ -219,7 +219,7 @@ Highlighter::Highlighter(QTextDocument *parent)
{ {
tokentypes["operator"] << "=" << "!" << "&&" << "||" << "+" << "-" << "*" << "/" << "%" << "!" << "#" << ";"; 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["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["transform"] << "scale" << "translate" << "rotate" << "multmatrix" << "color" << "projection" << "hull" << "resize" << "mirror" << "minkowski";
tokentypes["csgop"] << "union" << "intersection" << "difference" << "render"; tokentypes["csgop"] << "union" << "intersection" << "difference" << "render";
tokentypes["prim3d"] << "cube" << "cylinder" << "sphere" << "polyhedron"; tokentypes["prim3d"] << "cube" << "cylinder" << "sphere" << "polyhedron";

View File

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

View File

@ -84,6 +84,7 @@ std::string parser_source_path;
%token TOK_FUNCTION %token TOK_FUNCTION
%token TOK_IF %token TOK_IF
%token TOK_ELSE %token TOK_ELSE
%token TOK_LET
%token <text> TOK_ID %token <text> TOK_ID
%token <text> TOK_STRING %token <text> TOK_STRING
@ -96,6 +97,8 @@ std::string parser_source_path;
%token LE GE EQ NE AND OR %token LE GE EQ NE AND OR
%right LET
%right '?' ':' %right '?' ':'
%left OR %left OR
@ -324,6 +327,14 @@ expr:
{ {
$$ = new Expression(Value($1)); $$ = 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 ']' | '[' expr ':' expr ']'
{ {
$$ = new Expression(); $$ = new Expression();