ExprPtr Parser::expressionRest(ExprPtr lhs, int minpred, bool se) { while(firstExpressionRest[token]) { Token op = token; int pred = operatorPrecedence[op]; if(pred < minpred) break; next(false); ExprPtr rhs(primaryExpression(se)); while(firstExpressionRest[token]) { Token op2 = token; int pred2 = operatorPrecedence[op2]; if(pred2 <= pred) break; rhs = expressionRest(rhs, pred2, se); } lhs = inScope(new BinExpr(lhs, rhs, op)); } return lhs; }
inline Frame* FrameTree::scopedChild(const AtomicString& name, TreeScope* scope) const { if (!scope) return nullptr; for (Frame* child = firstChild(); child; child = child->tree().nextSibling()) { if (child->tree().uniqueName() == name && inScope(*child, *scope)) return child; } return nullptr; }
ExprPtr Parser::statements() { unique_ptr<SeqExpr> seq(inScope(new SeqExpr())); do { #if 0 // TODO. Disabled until we know how to handle return if (test(TReturn)) { seq->expressions.push_back(ExprPtr(inScope( new ReturnExpr(expression(true))))); break; // Return must be the last statement in a statement list } #endif statement(*seq); } while(test(TSemicolon)); return ExprPtr(seq.release()); }
inline unsigned FrameTree::scopedChildCount(TreeScope* scope) const { if (!scope) return 0; unsigned scopedCount = 0; for (Frame* result = firstChild(); result; result = result->tree().nextSibling()) { if (inScope(*result, *scope)) scopedCount++; } return scopedCount; }
inline Frame* FrameTree::scopedChild(unsigned index, TreeScope* scope) const { if (!scope) return nullptr; unsigned scopedIndex = 0; for (Frame* result = firstChild(); result; result = result->tree().nextSibling()) { if (inScope(*result, *scope)) { if (scopedIndex == index) return result; scopedIndex++; } } return nullptr; }
ExprPtr Parser::controlSeqExpression(bool se) { if(test(TIf)) { auto ifExpr = enterScope<IfExpr>(new IfExpr); ifExpr->cond = expression(false); enterScope(new Scope); ifExpr->trueCase = exitScope<Expr>(controlSeqExpression(se)); exitScope<IfExpr>(ExprPtr()); ExprPtr ret = ifExpr; if(test(TElse)) { enterScope(new Scope); auto falseCase = exitScope<Expr>(controlSeqExpression(se)); ret = inScope(new IfElseExpr(ifExpr, falseCase)); } return ret; } /* TODO else if (Test(Token.While)) { var whileExpr = EnterScopeT<WhileExpr>(); whileExpr.Cond = Expression(false); whileExpr.Body = ControlSeqExpression(se); ExitScopeT<WhileExpr>(null); return whileExpr; }*/ else if(token == TLBrace) { return block(se); } assert(false); return ExprPtr(); }
ScopeSignaller(QObject * target, F && slot, QObject * parent = 0) : QObject(parent) { connect(this, &ScopeSignaller::inScope, target, std::forward<F>(slot)); inScope(true); }
~ScopeSignaller() { inScope(false); }
ExprPtr Parser::primaryExpression(bool se) { ExprPtr ret; /* TODO if(test(TMinus)) { return inScope(new UnaryExpr(PrimaryExpression(se), Token.Minus)); }*/ if(token == TCase) { ret = patternMatch(se); } else if (token == TIdent || token == TTypeIdent) { string const& name = nextIdent(se); auto varDecl = resolveLocal(currentScope, name); if(varDecl) ret = inScope(new VarRef(varDecl)); else ret = inScope(new NamedRef(name)); } else if(token == TConstNum) { if(tokenStr.find('.') != string::npos) ret = inScope(new FConstExpr(tokenNum(se))); else ret = inScope(new ConstExpr(tokenNum(se))); } else if(test(TLParen)) { ret = expression(false); expect(TRParen); } else if (firstControlSeq[token]) { ret = controlSeqExpression(se); } else { throw CompileError(CEParseError, currentLine); } while(true) { switch(token) { case TLParen: { next(false); auto call = inScope(new CallExpr()); call->func = ret; ret = call; if(token != TRParen) { do { ExprPtr const& param = expression(false); call->parameters.push_back(param); } while(test(TComma)); } expect(TRParen, se); break; } /* case Token.Dot: { Next(false); var name = ExpectIdent(se); ret = InScope(new SlotRef(ret, name)); break; }*/ default: return ret; } } }