mirror of https://github.com/vitalif/openscad
Add a let() expression
parent
b984297e28
commit
ed3041c551
21
src/expr.cc
21
src/expr.cc
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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;
|
||||
|
|
11
src/parser.y
11
src/parser.y
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue