Phasor 3.1.1
Stack VM based Programming Language
Loading...
Searching...
No Matches
Parser.cpp
Go to the documentation of this file.
1#include "Parser.hpp"
2#include <iostream>
3
4namespace pulsar
5{
6
7Parser::Parser(const std::vector<Token> &tokens) : tokens(tokens)
8{
9}
10
11std::unique_ptr<Program> Parser::parse()
12{
13 auto program = std::make_unique<Program>();
14 while (!isAtEnd())
15 {
16 program->statements.push_back(declaration());
17 }
18 return program;
19}
20
21std::unique_ptr<Statement> Parser::declaration()
22{
23 if (check(Phasor::TokenType::Keyword) && peek().lexeme == "func")
24 {
25 advance();
26 return functionDeclaration();
27 }
28 if (check(Phasor::TokenType::Keyword) && peek().lexeme == "let")
29 {
30 advance();
31 return varDeclaration();
32 }
33 return statement();
34}
35
36std::unique_ptr<Statement> Parser::functionDeclaration()
37{
38 Token name = consume(Phasor::TokenType::Identifier, "Expect function name.");
39 consume(Phasor::TokenType::Symbol, "(", "Expect '(' after function name.");
40 std::vector<FunctionDecl::Param> params;
41 if (!check(Phasor::TokenType::Symbol) || peek().lexeme != ")")
42 {
43 do
44 {
45 Token paramName = consume(Phasor::TokenType::Identifier, "Expect parameter name.");
46 consume(Phasor::TokenType::Symbol, ":", "Expect ':' after parameter name.");
47 auto type = parseType();
48 params.push_back({paramName.lexeme, std::move(type)});
49 } while (match(Phasor::TokenType::Symbol, ","));
50 }
51 consume(Phasor::TokenType::Symbol, ")", "Expect ')' after parameters.");
52
53 std::unique_ptr<TypeNode> returnType = nullptr;
54 if (match(Phasor::TokenType::Symbol, "->"))
55 {
56 returnType = parseType();
57 }
58
59 consume(Phasor::TokenType::Symbol, "{", "Expect '{' before function body.");
60
61 // Track function context for better error messages
62 std::string previousFunction = currentFunction;
63 currentFunction = name.lexeme;
64
65 auto body = block();
66
67 // Restore previous function context
68 currentFunction = previousFunction;
69
70 return std::make_unique<FunctionDecl>(name.lexeme, std::move(params), std::move(returnType), std::move(body));
71}
72
73std::unique_ptr<TypeNode> Parser::parseType()
74{
75 bool isPointer = false;
76 if (match(Phasor::TokenType::Symbol, "*"))
77 {
78 isPointer = true;
79 }
80 Token typeName = consume(Phasor::TokenType::Identifier, "Expect type name.");
81
82 std::vector<int> dims;
83 while (match(Phasor::TokenType::Symbol, "["))
84 {
85 Token size = consume(Phasor::TokenType::Number, "Expect array size in type declaration.");
86 dims.push_back(std::stoi(size.lexeme));
87 consume(Phasor::TokenType::Symbol, "]", "Expect ']' after array size.");
88 }
89 return std::make_unique<TypeNode>(typeName.lexeme, isPointer, dims);
90}
91
92std::unique_ptr<Statement> Parser::varDeclaration()
93{
94 Token name = consume(Phasor::TokenType::Identifier, "Expect variable name.");
95 consume(Phasor::TokenType::Symbol, "=", "Expect '=' after variable name.");
96 std::unique_ptr<Expression> initializer = nullptr;
97 initializer = expression();
98 return std::make_unique<VarDecl>(name.lexeme, std::move(initializer));
99}
100
101std::unique_ptr<Statement> Parser::statement()
102{
103 if (check(Phasor::TokenType::Keyword) && peek().lexeme == "print")
104 {
105 advance();
106 return printStatement();
107 }
108 if (check(Phasor::TokenType::Keyword) && peek().lexeme == "if")
109 {
110 advance();
111 return ifStatement();
112 }
113 if (check(Phasor::TokenType::Keyword) && peek().lexeme == "while")
114 {
115 advance();
116 return whileStatement();
117 }
118 if (check(Phasor::TokenType::Keyword) && peek().lexeme == "return")
119 {
120 advance();
121 return returnStatement();
122 }
123 if (check(Phasor::TokenType::Keyword) && peek().lexeme == "break")
124 {
125 advance();
126 return std::make_unique<BreakStmt>();
127 }
128 if (check(Phasor::TokenType::Keyword) && peek().lexeme == "continue")
129 {
130 advance();
131 return std::make_unique<ContinueStmt>();
132 }
133 if (check(Phasor::TokenType::Symbol) && peek().lexeme == "{")
134 {
135 advance();
136 auto blk = block();
137 return blk;
138 }
139 return expressionStatement();
140}
141
142std::unique_ptr<Statement> Parser::ifStatement()
143{
144 consume(Phasor::TokenType::Symbol, "(", "Expect '(' after 'if'.");
145 auto condition = expression();
146 consume(Phasor::TokenType::Symbol, ")", "Expect ')' after if condition.");
147 auto thenBranch = statement();
148 std::unique_ptr<Statement> elseBranch = nullptr;
149 if (match(Phasor::TokenType::Keyword, "else"))
150 {
151 elseBranch = statement();
152 }
153 return std::make_unique<IfStmt>(std::move(condition), std::move(thenBranch), std::move(elseBranch));
154}
155
156std::unique_ptr<Statement> Parser::whileStatement()
157{
158 consume(Phasor::TokenType::Symbol, "(", "Expect '(' after 'while'.");
159 auto condition = expression();
160 consume(Phasor::TokenType::Symbol, ")", "Expect ')' after while condition.");
161 auto body = statement();
162 return std::make_unique<WhileStmt>(std::move(condition), std::move(body));
163}
164
165std::unique_ptr<Statement> Parser::forStatement()
166{
167 consume(Phasor::TokenType::Symbol, "(", "Expect '(' after 'for'.");
168
169 std::unique_ptr<Statement> initializer = nullptr;
170 if (check(Phasor::TokenType::Keyword) && peek().lexeme == "let")
171 {
172 advance();
173 initializer = varDeclaration();
174 }
175 else
176 {
177 initializer = expressionStatement();
178 }
179
180 std::unique_ptr<Expression> condition = nullptr;
181 condition = expression();
182
183 std::unique_ptr<Expression> increment = nullptr;
184 if (!check(Phasor::TokenType::Symbol) || peek().lexeme != ")")
185 {
186 increment = expression();
187 }
188 consume(Phasor::TokenType::Symbol, ")", "Expect ')' after for clauses.");
189
190 auto body = statement();
191 return std::make_unique<ForStmt>(std::move(initializer), std::move(condition), std::move(increment),
192 std::move(body));
193}
194
195std::unique_ptr<Statement> Parser::switchStatement()
196{
197 consume(Phasor::TokenType::Symbol, "(", "Expect '(' after 'switch'.");
198 auto expr = expression();
199 consume(Phasor::TokenType::Symbol, ")", "Expect ')' after switch expression.");
200 consume(Phasor::TokenType::Symbol, "{", "Expect '{' after switch.");
201
202 std::vector<CaseClause> cases;
203 std::vector<std::unique_ptr<Statement>> defaultStmts;
204
205 while (!check(Phasor::TokenType::Symbol) || peek().lexeme != "}")
206 {
207 if (isAtEnd())
208 throw std::runtime_error("Unterminated switch statement.");
209
210 if (check(Phasor::TokenType::Keyword) && peek().lexeme == "case")
211 {
212 advance();
213 auto caseValue = expression();
214 consume(Phasor::TokenType::Symbol, ":", "Expect ':' after case value.");
215
216 std::vector<std::unique_ptr<Statement>> stmts;
217 while ((!check(Phasor::TokenType::Keyword) || (peek().lexeme != "case" && peek().lexeme != "default")) &&
218 (!check(Phasor::TokenType::Symbol) || peek().lexeme != "}"))
219 {
220 if (isAtEnd())
221 throw std::runtime_error("Unterminated case clause.");
222 stmts.push_back(declaration());
223 }
224 cases.emplace_back(std::move(caseValue), std::move(stmts));
225 }
226 else if (check(Phasor::TokenType::Keyword) && peek().lexeme == "default")
227 {
228 advance();
229 consume(Phasor::TokenType::Symbol, ":", "Expect ':' after default.");
230
231 while ((!check(Phasor::TokenType::Keyword) || (peek().lexeme != "case" && peek().lexeme != "default")) &&
232 (!check(Phasor::TokenType::Symbol) || peek().lexeme != "}"))
233 {
234 if (isAtEnd())
235 throw std::runtime_error("Unterminated default clause.");
236 defaultStmts.push_back(declaration());
237 }
238 }
239 else
240 {
241 throw std::runtime_error("Expected 'case' or 'default' in switch statement.");
242 }
243 }
244
245 consume(Phasor::TokenType::Symbol, "}", "Expect '}' after switch body.");
246 return std::make_unique<SwitchStmt>(std::move(expr), std::move(cases), std::move(defaultStmts));
247}
248
249std::unique_ptr<Statement> Parser::returnStatement()
250{
251 std::unique_ptr<Expression> value = nullptr;
252 value = expression();
253 return std::make_unique<ReturnStmt>(std::move(value));
254}
255
256std::unique_ptr<BlockStmt> Parser::block()
257{
258 std::vector<std::unique_ptr<Statement>> statements;
259 while (!check(Phasor::TokenType::Symbol) || peek().lexeme != "}")
260 {
261 if (isAtEnd())
262 throw std::runtime_error("Unterminated block.");
263 statements.push_back(declaration());
264 }
265 consume(Phasor::TokenType::Symbol, "}", "Expect '}' after block.");
266 return std::make_unique<BlockStmt>(std::move(statements));
267}
268
269std::unique_ptr<Statement> Parser::printStatement()
270{
271 auto expr = expression();
272 return std::make_unique<PrintStmt>(std::move(expr));
273}
274
275std::unique_ptr<Statement> Parser::expressionStatement()
276{
277 auto expr = expression();
278 return std::make_unique<ExpressionStmt>(std::move(expr));
279}
280
281std::unique_ptr<Expression> Parser::expression()
282{
283 return assignment();
284}
285
286std::unique_ptr<Expression> Parser::assignment()
287{
288 auto expr = logicalOr();
289
290 if (match(Phasor::TokenType::Symbol, "="))
291 {
292 auto value = assignment();
293 return std::make_unique<AssignmentExpr>(std::move(expr), std::move(value));
294 }
295
296 return expr;
297}
298
299std::unique_ptr<Expression> Parser::logicalOr()
300{
301 auto expr = logicalAnd();
302
303 while (check(Phasor::TokenType::Symbol) && peek().lexeme == "||")
304 {
305 advance();
306 auto right = logicalAnd();
307 expr = std::make_unique<BinaryExpr>(std::move(expr), BinaryOp::Or, std::move(right));
308 }
309
310 return expr;
311}
312
313std::unique_ptr<Expression> Parser::logicalAnd()
314{
315 auto expr = equality();
316
317 while (check(Phasor::TokenType::Symbol) && peek().lexeme == "&&")
318 {
319 advance();
320 auto right = equality();
321 expr = std::make_unique<BinaryExpr>(std::move(expr), BinaryOp::And, std::move(right));
322 }
323
324 return expr;
325}
326
327std::unique_ptr<Expression> Parser::equality()
328{
329 auto expr = comparison();
330
331 while (check(Phasor::TokenType::Symbol) && (peek().lexeme == "==" || peek().lexeme == "!="))
332 {
333 Token op = advance();
334 auto right = comparison();
335 BinaryOp binOp = (op.lexeme == "==") ? BinaryOp::Equal : BinaryOp::NotEqual;
336 expr = std::make_unique<BinaryExpr>(std::move(expr), binOp, std::move(right));
337 }
338
339 return expr;
340}
341
342std::unique_ptr<Expression> Parser::comparison()
343{
344 auto expr = term();
345
346 while (check(Phasor::TokenType::Symbol) &&
347 (peek().lexeme == "<" || peek().lexeme == ">" || peek().lexeme == "<=" || peek().lexeme == ">="))
348 {
349 Token op = advance();
350 auto right = term();
351 BinaryOp binOp;
352 if (op.lexeme == "<")
353 binOp = BinaryOp::LessThan;
354 else if (op.lexeme == ">")
355 binOp = BinaryOp::GreaterThan;
356 else if (op.lexeme == "<=")
357 binOp = BinaryOp::LessEqual;
358 else
359 binOp = BinaryOp::GreaterEqual;
360
361 expr = std::make_unique<BinaryExpr>(std::move(expr), binOp, std::move(right));
362 }
363
364 return expr;
365}
366
367std::unique_ptr<Expression> Parser::term()
368{
369 auto expr = factor();
370
371 while (check(Phasor::TokenType::Symbol) && (peek().lexeme == "+" || peek().lexeme == "-"))
372 {
373 Token op = advance();
374 auto right = factor();
375 BinaryOp binOp = (op.lexeme == "+") ? BinaryOp::Add : BinaryOp::Subtract;
376 expr = std::make_unique<BinaryExpr>(std::move(expr), binOp, std::move(right));
377 }
378
379 return expr;
380}
381
382std::unique_ptr<Expression> Parser::factor()
383{
384 auto expr = unary();
385
386 while (check(Phasor::TokenType::Symbol) && (peek().lexeme == "*" || peek().lexeme == "/" || peek().lexeme == "%"))
387 {
388 Token op = advance();
389 auto right = unary();
390 BinaryOp binOp;
391 if (op.lexeme == "*")
392 binOp = BinaryOp::Multiply;
393 else if (op.lexeme == "/")
394 binOp = BinaryOp::Divide;
395 else
396 binOp = BinaryOp::Modulo;
397
398 expr = std::make_unique<BinaryExpr>(std::move(expr), binOp, std::move(right));
399 }
400
401 return expr;
402}
403
404std::unique_ptr<Expression> Parser::unary()
405{
406 if (check(Phasor::TokenType::Symbol) && (peek().lexeme == "!" || peek().lexeme == "-"))
407 {
408 Token op = advance();
409 auto right = unary();
410 UnaryOp uOp = (op.lexeme == "!") ? UnaryOp::Not : UnaryOp::Negate;
411 return std::make_unique<UnaryExpr>(uOp, std::move(right));
412 }
413 if (check(Phasor::TokenType::Symbol) && peek().lexeme == "&")
414 {
415 advance();
416 auto right = unary();
417 return std::make_unique<UnaryExpr>(UnaryOp::AddressOf, std::move(right));
418 }
419 if (check(Phasor::TokenType::Symbol) && peek().lexeme == "*")
420 {
421 advance();
422 auto right = unary();
423 return std::make_unique<UnaryExpr>(UnaryOp::Dereference, std::move(right));
424 }
425 return call();
426}
427
428std::unique_ptr<Expression> Parser::call()
429{
430 auto expr = primary();
431
432 while (true)
433 {
434 if (match(Phasor::TokenType::Symbol, "("))
435 {
436 expr = finishCall(std::move(expr));
437 }
438 else if (match(Phasor::TokenType::Symbol, "++"))
439 {
440 expr = std::make_unique<PostfixExpr>(PostfixOp::Increment, std::move(expr));
441 }
442 else if (match(Phasor::TokenType::Symbol, "--"))
443 {
444 expr = std::make_unique<PostfixExpr>(PostfixOp::Decrement, std::move(expr));
445 }
446 else
447 {
448 break;
449 }
450 }
451
452 return expr;
453}
454
455std::unique_ptr<Expression> Parser::finishCall(std::unique_ptr<Expression> callee)
456{
457 std::vector<std::unique_ptr<Expression>> arguments;
458 if (!check(Phasor::TokenType::Symbol) || peek().lexeme != ")")
459 {
460 do
461 {
462 arguments.push_back(expression());
463 } while (match(Phasor::TokenType::Symbol, ","));
464 }
465 consume(Phasor::TokenType::Symbol, ")", "Expect ')' after arguments.");
466
467 // For now, we only support direct function calls by name, or calls on field access which are
468 // rewritten to pass the object as the first argument.
469 if (auto ident = dynamic_cast<IdentifierExpr *>(callee.get()))
470 {
471 return std::make_unique<CallExpr>(ident->name, std::move(arguments));
472 }
473 else if (auto field = dynamic_cast<FieldAccessExpr *>(callee.get()))
474 {
475 // Transform obj.method(args) -> method(obj, args)
476 std::string methodName = field->fieldName;
477 arguments.insert(arguments.begin(), std::move(field->object));
478 return std::make_unique<CallExpr>(methodName, std::move(arguments));
479 }
480
481 throw std::runtime_error("Can only call named functions.");
482}
483
484std::unique_ptr<Expression> Parser::primary()
485{
486 if (match(Phasor::TokenType::Number))
487 {
488 return std::make_unique<NumberExpr>(previous().lexeme);
489 }
490 if (match(Phasor::TokenType::String))
491 {
492 return std::make_unique<StringExpr>(previous().lexeme);
493 }
495 {
496 Token identTok = peek();
497 advance();
498 return std::make_unique<IdentifierExpr>(identTok.lexeme);
499 }
500 if (match(Phasor::TokenType::Keyword, "true"))
501 {
502 return std::make_unique<BooleanExpr>(true);
503 }
504 if (match(Phasor::TokenType::Keyword, "false"))
505 {
506 return std::make_unique<BooleanExpr>(false);
507 }
508 if (match(Phasor::TokenType::Keyword, "null"))
509 {
510 return std::make_unique<NullExpr>();
511 }
512 if (match(Phasor::TokenType::Symbol, "("))
513 {
514 auto expr = expression();
515 consume(Phasor::TokenType::Symbol, ")", "Expect ')' after expression.");
516 return expr;
517 }
518 std::cerr << "Error: Expect expression at '" << peek().lexeme << "'";
519 std::cerr << " (line " << peek().line << ", column " << peek().column << ")\n";
520 throw std::runtime_error("Expect expression.");
521}
522
523Token Parser::peek()
524{
525 return tokens[current];
526}
527
528Token Parser::peekNext()
529{
530 if (current + 1 >= static_cast<int>(tokens.size()))
531 {
532 return tokens[current];
533 }
534 return tokens[current + 1];
535}
536
537Token Parser::previous()
538{
539 return tokens[current - 1];
540}
541
542Token Parser::advance()
543{
544 if (!isAtEnd())
545 current++;
546 return previous();
547}
548
549bool Parser::isAtEnd()
550{
551 return peek().type == Phasor::TokenType::EndOfFile;
552}
553
554bool Parser::check(TokenType type)
555{
556 if (isAtEnd())
557 return false;
558 return peek().type == type;
559}
560
561bool Parser::match(TokenType type)
562{
563 if (check(type))
564 {
565 advance();
566 return true;
567 }
568 return false;
569}
570
571Token Parser::consume(TokenType type, std::string message)
572{
573 if (check(type))
574 return advance();
575
576 std::cerr << "Error: " << message << " at '" << peek().lexeme << "'";
577 std::cerr << " (line " << peek().line << ", column " << peek().column << ")";
578 if (!currentFunction.empty())
579 std::cerr << " [in function '" << currentFunction << "']";
580 std::cerr << "\n";
581
582 throw std::runtime_error(message);
583}
584
585bool Parser::match(TokenType type, std::string lexeme)
586{
587 if (check(type) && peek().lexeme == lexeme)
588 {
589 advance();
590 return true;
591 }
592 return false;
593}
594
595Token Parser::consume(TokenType type, std::string lexeme, std::string message)
596{
597 if (check(type) && peek().lexeme == lexeme)
598 {
599 return advance();
600 }
601
602 std::cerr << "Error: " << message << " at '" << peek().lexeme << "'";
603 std::cerr << " (line " << peek().line << ", column " << peek().column << ")";
604 if (!currentFunction.empty())
605 std::cerr << " [in function '" << currentFunction << "']";
606 std::cerr << "\n";
607
608 throw std::runtime_error(message);
609}
610
611Token Parser::expect(TokenType type, const std::string &message)
612{
613 if (check(type))
614 {
615 return advance();
616 }
617 throw std::runtime_error(message);
618}
619} // namespace pulsar
Parser(const std::vector< Token > &tokens)
UnaryOp
Unary operator types.
Definition AST.hpp:159
BinaryOp
Binary operator types.
Definition AST.hpp:168
The Pulsar Scripting Language.
Definition Compiler.cpp:13