SmartPointer<Entity> Parser::expOp(Tokenizer &tokenizer) { SmartPointer<Entity> entity = primary(tokenizer); while (true) { if (tokenizer.consume(TokenType::EXP_TOKEN)) entity = new BinaryOp(Operator::EXP_OP, entity, primary(tokenizer)); else break; } return entity; }
SmartPointer<FunctionCall> Parser::functionCall(Tokenizer &tokenizer) { ParseScope scope(tokenizer.getScanner()); string name = tokenizer.match(TokenType::ID_TOKEN).getValue(); SmartPointer<Entity> arg1 = quotedExpr(tokenizer); SmartPointer<Entity> arg2; // Special case if (String::toUpper(name) == "ATAN" && tokenizer.consume(TokenType::DIV_TOKEN)) arg2 = quotedExpr(tokenizer); return scope.set(new FunctionCall(name, arg1, arg2)); }
SmartPointer<Block> Parser::block(Tokenizer &tokenizer) { ParseScope scope(tokenizer.getScanner()); // Deleted bool deleted = false; if (tokenizer.consume(TokenType::DIV_TOKEN)) deleted = true; // Line number int line = -1; if (tokenizer.isID("N")) { tokenizer.advance(); Token num = tokenizer.match(TokenType::NUMBER_TOKEN); line = String::parseU32(num.getValue()); } // Children std::vector<SmartPointer<Entity> > children; // O-Code if (tokenizer.isID("O")) children.push_back(ocode(tokenizer)); while (tokenizer.hasMore()) { switch (tokenizer.getType()) { case TokenType::EOL_TOKEN: break; // End of block case TokenType::COMMENT_TOKEN: case TokenType::PAREN_COMMENT_TOKEN: children.push_back(comment(tokenizer)); break; case TokenType::POUND_TOKEN: children.push_back(assign(tokenizer)); break; default: if (!tokenizer.isType(TokenType::ID_TOKEN)) THROWS("Expected word or assignment, found " << tokenizer.getType()); children.push_back(word(tokenizer)); break; } if (tokenizer.getType() == TokenType::EOL_TOKEN) { tokenizer.advance(); break; } } return scope.set(new Block(deleted, line, children)); }
SmartPointer<Entity> Parser::reference(Tokenizer &tokenizer) { ParseScope scope(tokenizer.getScanner()); tokenizer.match(TokenType::POUND_TOKEN); if (tokenizer.consume(TokenType::OANGLE_TOKEN)) { string id = tokenizer.match(TokenType::ID_TOKEN).getValue(); tokenizer.match(TokenType::CANGLE_TOKEN); return scope.set(new NamedReference(id)); } else return scope.set(new Reference(numberRefOrExpr(tokenizer))); }