void Parser::Function(NodePtr node) { Expect(Token::Func); Expect(Token::Ident); auto name = Last(); auto fun = NewNode(Node::Function); fun->Add(name); Expect(Token::OpenParan); auto args = NewNode(Node::None); fun->Add(args); if (Try(Token::Ident)) { args->Add(Consume()); while (Try(Token::Comma)) { Consume(); args->Add(Expect(Token::Ident)); } } Expect(Token::CloseParan); Block(fun); node->Add(fun); }
void Parser::AddBlock(NodePtr node) { // TODO: this doesnt make sense with our brace parsing auto block = NewNode(Node::Block); Block(block); node->Add(block); }
void Parser::For(NodePtr block) { if (!Try(Token::For)) return; Consume(); auto f = NewNode(Node::For); if (!Expression()) { CreateError("For what?"); return; } if (Try(Token::In)) { Consume(); f->Add(Pop()); if (!Expression()) { CreateError("For each in what?"); return; } f->Add(Pop()); } else { Expect(Token::Semi); f->Add(Pop()); if (!Expression()) { CreateError("When does the for statement stop?"); return; } f->Add(Pop()); Expect(Token::Semi); if (!Expression()) { CreateError("What happens when a for statement ends?"); return; } f->Add(Pop()); } Expect(Token::NewLine); AddBlock(f); block->Add(f); }
void Parser::While(NodePtr block) { auto w = NewNode(Consume()); if (!Expression()) { CreateError("While what?"); return; } w->Add(Pop()); block->Add(w); }
void Parser::IfCondition(NodePtr block) { if (!Try(Token::If)) return; Consume(); Expect(Token::OpenParan); // get the test expression if (!Expression()) { CreateError("If what?"); return; } NodePtr condition = Pop(); Expect(Token::CloseParan); // get the true-clause NodePtr trueClause = NewNode(Node::Block); Block(trueClause); // make the conditional node in AST NodePtr cond = NewNode(Node::Conditional); cond->Add(condition); cond->Add(trueClause); // if there's an else, add it as well if (Try(Token::Else)) { Consume(); NodePtr falseClause = NewNode(Node::Block); Block(falseClause); cond->Add(falseClause); } block->Add(cond); }
void Parser::Block(NodePtr node) { if (!Try(Token::OpenBrace)) return; Consume(); auto block = NewNode(Node::Block); Push(block); while (Statement(block)) { if (Try(Token::CloseBrace)) { Consume(); break; } } Pop(); node->Add(block); }
bool Parser::Statement(NodePtr block) { switch (Current().type) { case Token::OpenBrace: { Block(block); return true; } case Token::Assert: { Consume(); if (!Expression()) { Fail(Lexer::CreateErrorMessage(Current(), "Assert needs an expression to test")); return false; } auto ass = NewNode(Consume()); ass->Add(Pop()); Push(ass); Expect(Token::Semi); goto finis; } case Token::Return: case Token::Yield: { auto ret = NewNode(Consume()); if (Expression()) ret->Add(Pop()); block->Add(ret); Expect(Token::Semi); goto finis; } case Token::While: { While(block); return true; } case Token::For: { For(block); return true; } case Token::If: { IfCondition(block); return true; } case Token::Func: { Function(block); return true; } } if (!Expression()) return false; // a block does not require a semicolon? //Expect(Token::Semi); block->Add(Pop()); finis: return true; }