10static std::vector<Token>
tokenizeFile(
const std::filesystem::path &path)
12 std::ifstream file(path);
15 throw std::runtime_error(
"Could not open file " + path.string());
17 std::string source((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
24static std::vector<std::unique_ptr<AST::Statement>>
25resolveIncludes(std::vector<std::unique_ptr<AST::Statement>> &stmts,
const std::filesystem::path &baseDir);
27static std::vector<std::unique_ptr<AST::Statement>>
30 std::vector<std::unique_ptr<AST::Statement>> result;
32 for (
size_t i = 0; i < stmts.size(); ++i)
36 auto includePath = (baseDir / includeStmt->modulePath).lexically_normal();
38 Parser parser(tokens, includePath);
39 auto program = parser.
parse();
41 auto resolved =
resolveIncludes(program->statements, includePath.parent_path());
42 for (
auto &stmt : resolved)
44 result.push_back(std::move(stmt));
49 result.push_back(std::move(stmts[i]));
56static std::vector<std::unique_ptr<AST::Statement>>
57resolveIncludes(std::vector<std::unique_ptr<AST::Statement>> &stmts,
const std::filesystem::path &baseDir)
75 auto program = std::make_unique<Program>();
93 node->line = start.
line;
94 node->column = start.
column;
102 node->line = start.
line;
103 node->column = start.
column;
111 node->line = start.
line;
112 node->column = start.
column;
120 node->line = start.
line;
121 node->column = start.
column;
135 std::vector<FunctionDecl::Param> params;
143 params.push_back({paramName.
lexeme, std::move(type)});
148 std::unique_ptr<TypeNode> returnType =
nullptr;
165 auto node = std::make_unique<FunctionDecl>(name.
lexeme, std::move(params), std::move(returnType), std::move(body));
166 node->line = name.
line;
167 node->column = name.
column;
174 bool isPointer =
false;
181 std::vector<int> dims;
185 dims.push_back(std::stoi(size.
lexeme));
188 auto node = std::make_unique<TypeNode>(typeName.
lexeme, isPointer, dims);
189 node->line = start.
line;
190 node->column = start.
column;
197 std::unique_ptr<Expression> initializer =
nullptr;
203 auto node = std::make_unique<VarDecl>(name.
lexeme, std::move(initializer));
204 node->line = name.
line;
205 node->column = name.
column;
216 node->line = start.
line;
217 node->column = start.
column;
225 node->line = start.
line;
226 node->column = start.
column;
234 node->line = start.
line;
235 node->column = start.
column;
243 node->line = start.
line;
244 node->column = start.
column;
252 node->line = start.
line;
253 node->column = start.
column;
261 node->line = start.
line;
262 node->column = start.
column;
270 auto node = std::make_unique<BreakStmt>();
271 node->line = start.
line;
272 node->column = start.
column;
280 auto node = std::make_unique<ContinueStmt>();
281 node->line = start.
line;
282 node->column = start.
column;
294 auto node = std::make_unique<IncludeStmt>(pathToken.
lexeme);
295 node->line = start.
line;
296 node->column = start.
column;
304 node->line = start.
line;
305 node->column = start.
column;
313 blk->line = start.
line;
314 blk->column = start.
column;
326 std::unique_ptr<Statement> elseBranch =
nullptr;
331 return std::make_unique<IfStmt>(std::move(condition), std::move(thenBranch), std::move(elseBranch));
341 return std::make_unique<WhileStmt>(std::move(condition), std::move(body));
348 std::unique_ptr<Statement> initializer =
nullptr;
366 std::unique_ptr<Expression> condition =
nullptr;
373 std::unique_ptr<Expression> increment =
nullptr;
381 return std::make_unique<ForStmt>(std::move(initializer), std::move(condition), std::move(increment),
392 std::vector<CaseClause> cases;
393 std::vector<std::unique_ptr<Statement>> defaultStmts;
400 throw std::runtime_error(
"Unterminated switch statement.");
409 std::vector<std::unique_ptr<Statement>> stmts;
416 throw std::runtime_error(
"Unterminated case clause.");
420 cases.emplace_back(std::move(caseValue), std::move(stmts));
433 throw std::runtime_error(
"Unterminated default clause.");
441 throw std::runtime_error(
"Expected 'case' or 'default' in switch statement.");
446 return std::make_unique<SwitchStmt>(std::move(expr), std::move(cases), std::move(defaultStmts));
451 std::unique_ptr<Expression> value =
nullptr;
457 return std::make_unique<ReturnStmt>(std::move(value));
464 return std::make_unique<UnsafeBlockStmt>(
block());
469 std::vector<std::unique_ptr<Statement>> statements;
475 throw std::runtime_error(
"Unterminated block.");
480 return std::make_unique<BlockStmt>(std::move(statements));
487 return std::make_unique<PrintStmt>(std::move(expr));
495 auto node = std::make_unique<ImportStmt>(path.
lexeme);
496 node->line = path.
line;
497 node->column = path.
column;
503 auto node = std::make_unique<ExportStmt>(
declaration());
513 auto node = std::make_unique<ExpressionStmt>(std::move(expr));
514 node->line = start.
line;
515 node->column = start.
column;
532 auto node = std::make_unique<AssignmentExpr>(std::move(expr), std::move(value));
533 node->line = op.
line;
549 auto node = std::make_unique<BinaryExpr>(std::move(expr), BinaryOp::Or, std::move(right));
550 node->line = op.
line;
552 expr = std::move(node);
566 auto node = std::make_unique<BinaryExpr>(std::move(expr), BinaryOp::And, std::move(right));
567 node->line = op.
line;
569 expr = std::move(node);
583 BinaryOp binOp = (op.
lexeme ==
"==") ? BinaryOp::Equal : BinaryOp::NotEqual;
584 auto node = std::make_unique<BinaryExpr>(std::move(expr), binOp, std::move(right));
585 node->line = op.
line;
587 expr = std::move(node);
598 (
peek().lexeme ==
"<" ||
peek().lexeme ==
">" ||
peek().lexeme ==
"<=" ||
peek().lexeme ==
">="))
604 binOp = BinaryOp::LessThan;
605 else if (op.
lexeme ==
">")
606 binOp = BinaryOp::GreaterThan;
607 else if (op.
lexeme ==
"<=")
608 binOp = BinaryOp::LessEqual;
610 binOp = BinaryOp::GreaterEqual;
612 auto node = std::make_unique<BinaryExpr>(std::move(expr), binOp, std::move(right));
613 node->line = op.
line;
615 expr = std::move(node);
629 BinaryOp binOp = (op.
lexeme ==
"+") ? BinaryOp::Add : BinaryOp::Subtract;
630 auto node = std::make_unique<BinaryExpr>(std::move(expr), binOp, std::move(right));
631 node->line = op.
line;
633 expr = std::move(node);
646 auto right =
unary();
649 binOp = BinaryOp::Multiply;
650 else if (op.
lexeme ==
"/")
651 binOp = BinaryOp::Divide;
653 binOp = BinaryOp::Modulo;
655 auto node = std::make_unique<BinaryExpr>(std::move(expr), binOp, std::move(right));
656 node->line = op.
line;
658 expr = std::move(node);
669 auto right =
unary();
670 UnaryOp uOp = (op.
lexeme ==
"!") ? UnaryOp::Not : UnaryOp::Negate;
671 auto node = std::make_unique<UnaryExpr>(uOp, std::move(right));
672 node->line = op.
line;
679 auto right =
unary();
680 auto node = std::make_unique<UnaryExpr>(UnaryOp::AddressOf, std::move(right));
681 node->line = op.
line;
688 auto right =
unary();
689 auto node = std::make_unique<UnaryExpr>(UnaryOp::Dereference, std::move(right));
690 node->line = op.
line;
707 expr->line = op.
line;
714 expr->line = op.
line;
720 auto node = std::make_unique<PostfixExpr>(PostfixOp::Increment, std::move(expr));
721 node->line = op.
line;
723 expr = std::move(node);
728 auto node = std::make_unique<PostfixExpr>(PostfixOp::Decrement, std::move(expr));
729 node->line = op.
line;
731 expr = std::move(node);
738 auto node = std::make_unique<ArrayAccessExpr>(std::move(expr), std::move(index));
739 node->line = op.
line;
741 expr = std::move(node);
754 std::vector<std::unique_ptr<Expression>> arguments;
768 auto node = std::make_unique<CallExpr>(ident->name, std::move(arguments));
769 node->line = ident->line;
770 node->column = ident->column;
776 std::string methodName = field->fieldName;
777 size_t fline = field->line, fcol = field->column;
778 arguments.insert(arguments.begin(), std::move(field->object));
779 auto node = std::make_unique<CallExpr>(methodName, std::move(arguments));
785 throw std::runtime_error(
"Can only call named functions.");
793 auto node = std::make_unique<NumberExpr>(t.
lexeme);
801 auto node = std::make_unique<StringExpr>(t.
lexeme);
815 auto node = std::make_unique<IdentifierExpr>(identTok.
lexeme);
816 node->line = identTok.
line;
817 node->column = identTok.
column;
823 std::vector<std::unique_ptr<Expression>> elements;
832 auto node = std::make_unique<ArrayLiteralExpr>(std::move(elements));
833 node->line = start.
line;
834 node->column = start.
column;
840 auto node = std::make_unique<BooleanExpr>(
true);
848 auto node = std::make_unique<BooleanExpr>(
false);
856 auto node = std::make_unique<NullExpr>();
867 std::cerr <<
"Error: Expect expression at '" <<
peek().
lexeme <<
"'";
870 throw std::runtime_error(
"Expect expression.");
883 std::vector<StructField> fields;
889 throw std::runtime_error(
"Unterminated struct declaration.");
895 fields.emplace_back(fieldNameTok.
lexeme, std::move(type));
904 auto node = std::make_unique<StructDecl>(nameTok.
lexeme, std::move(fields));
905 node->line = start.
line;
906 node->column = start.
column;
917 std::vector<std::pair<std::string, std::unique_ptr<Expression>>> fields;
923 throw std::runtime_error(
"Unterminated struct instance.");
928 fields.emplace_back(fieldNameTok.
lexeme, std::move(value));
937 auto node = std::make_unique<StructInstanceExpr>(nameTok.
lexeme, std::move(fields));
938 node->line = nameTok.
line;
939 node->column = nameTok.
column;
948 auto node = std::make_unique<FieldAccessExpr>(std::move(
object), nameTok.
lexeme);
949 node->line = nameTok.
line;
950 node->column = nameTok.
column;
1007 std::cerr <<
"Error: " << message <<
" at '" <<
peek().
lexeme <<
"'";
1013 throw std::runtime_error(message);
1018 if (
check(type) &&
peek().lexeme == lexeme)
1028 if (
check(type) &&
peek().lexeme == lexeme)
1033 std::cerr <<
"Error: " << message <<
" at '" <<
peek().
lexeme <<
"'";
1040 throw std::runtime_error(message);
1050 throw std::runtime_error(message);
std::vector< Token > tokenize()
Parser(const std::vector< Token > &tokens)
std::unique_ptr< AST::Statement > returnStatement()
std::unique_ptr< AST::Expression > equality()
std::unique_ptr< AST::Expression > logicalAnd()
std::filesystem::path sourcePath
std::unique_ptr< AST::Expression > unary()
std::unique_ptr< AST::Expression > factor()
std::unique_ptr< AST::Statement > ifStatement()
Token consume(Phasor::TokenType type, std::string message)
std::unique_ptr< AST::StructDecl > structDecl()
std::unique_ptr< AST::Statement > whileStatement()
std::unique_ptr< AST::Statement > expressionStatement()
std::unique_ptr< AST::Expression > fieldAccess(std::unique_ptr< AST::Expression > object)
std::vector< Token > tokens
std::unique_ptr< AST::TypeNode > parseType()
std::unique_ptr< AST::Expression > expression()
std::unique_ptr< AST::Statement > declaration()
std::unique_ptr< AST::Statement > varDeclaration()
std::unique_ptr< AST::Expression > assignment()
std::string currentFunction
std::unique_ptr< AST::Program > parse()
std::unique_ptr< AST::Statement > importStatement()
std::unique_ptr< AST::BlockStmt > block()
std::unique_ptr< AST::Statement > unsafeStatement()
bool check(Phasor::TokenType type)
std::unique_ptr< AST::Statement > functionDeclaration()
std::unique_ptr< AST::Statement > exportStatement()
std::unique_ptr< AST::Statement > switchStatement()
std::unique_ptr< AST::Expression > comparison()
std::unique_ptr< AST::Expression > finishCall(std::unique_ptr< AST::Expression > callee)
std::unique_ptr< AST::Expression > logicalOr()
std::unique_ptr< AST::Statement > forStatement()
std::unique_ptr< AST::StructInstanceExpr > structInstance()
std::unique_ptr< AST::Statement > printStatement()
std::unique_ptr< AST::Statement > statement()
bool match(Phasor::TokenType type)
std::unique_ptr< AST::Expression > primary()
std::unique_ptr< AST::Expression > term()
std::optional< Error > lastError
Token expect(Phasor::TokenType type, const std::string &message)
std::unique_ptr< AST::Expression > call()
UnaryOp
Unary operator types.
BinaryOp
Binary operator types.
The Phasor Programming Language and Runtime.
static std::vector< std::unique_ptr< AST::Statement > > resolveIncludes(std::vector< std::unique_ptr< AST::Statement > > &stmts, const std::filesystem::path &baseDir)
TokenType
Token types for the lexer.
static std::vector< std::unique_ptr< AST::Statement > > resolveIncludesInternal(std::vector< std::unique_ptr< AST::Statement > > &stmts, const std::filesystem::path &baseDir)
static std::vector< Token > tokenizeFile(const std::filesystem::path &path)
Field Access Expression Node.
Identifier Expression Node.