1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#include "cps/Parser.h"
#include "cps/FunctionAST.h"
using namespace cps;
std::vector<std::pair<std::string, std::string>> Parser::ParsePrototypeArgs() {
std::vector<std::pair<std::string, std::string>> Args;
if (CurTok != '(') return Args;
getNextToken();
while (CurTok != ')') {
if (CurTok == -1000 || CurTok == -1001) getNextToken();
if (CurTok != tok_identifier) {
fprintf(stderr, "Error: Expected argument name\n");
return Args;
}
std::string Name = Lex.IdentifierStr;
getNextToken();
if (CurTok != tok_colon) {
fprintf(stderr, "Error: Expected ':' after argument name\n");
return Args;
}
getNextToken();
std::string Type = "INTEGER";
if (CurTok == tok_integer_kw) {
getNextToken();
} else if (CurTok == tok_identifier) {
Type = Lex.IdentifierStr;
getNextToken();
} else {
fprintf(stderr, "Error: Expected type (e.g. INTEGER) for argument '%s'\n", Name.c_str());
return Args;
}
Args.push_back({Name, Type});
if (CurTok == ')') break;
if (CurTok != ',') {
fprintf(stderr, "Error: Expected ',' or ')'\n");
return Args;
}
getNextToken();
}
getNextToken();
return Args;
}
std::unique_ptr<StmtAST> Parser::ParseFunction() {
getNextToken();
std::string Name = Lex.IdentifierStr;
getNextToken();
auto Args = ParsePrototypeArgs();
std::string RetType = "INTEGER";
if (CurTok == tok_returns) {
getNextToken();
getNextToken();
}
auto Proto = std::make_unique<PrototypeAST>(Name, std::move(Args), RetType);
std::vector<std::unique_ptr<StmtAST>> Body;
while (CurTok != tok_endfunction && CurTok != tok_eof) {
auto Stmt = ParseStatement();
if (Stmt) Body.push_back(std::move(Stmt));
else if (CurTok != tok_eof && CurTok != tok_endfunction) getNextToken();
}
getNextToken();
return std::make_unique<FunctionDefAST>(std::move(Proto), std::move(Body));
}
std::unique_ptr<StmtAST> Parser::ParseProcedure() {
getNextToken();
std::string Name = Lex.IdentifierStr;
getNextToken();
auto Args = ParsePrototypeArgs();
auto Proto = std::make_unique<PrototypeAST>(Name, std::move(Args), "VOID");
std::vector<std::unique_ptr<StmtAST>> Body;
while (CurTok != tok_endprocedure && CurTok != tok_eof) {
auto Stmt = ParseStatement();
if (Stmt) Body.push_back(std::move(Stmt));
else if (CurTok != tok_eof && CurTok != tok_endprocedure) getNextToken();
}
getNextToken();
return std::make_unique<FunctionDefAST>(std::move(Proto), std::move(Body));
}
std::unique_ptr<StmtAST> Parser::ParseCallStmt() {
getNextToken();
std::string Callee = Lex.IdentifierStr;
getNextToken();
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok == '(') {
getNextToken();
while (CurTok != ')') {
auto Arg = ParseExpression();
if (Arg) Args.push_back(std::move(Arg));
if (CurTok == ')') break;
if (CurTok != ',') {
fprintf(stderr, "Error: Expected ',' or ')' in call\n");
return nullptr;
}
getNextToken();
}
getNextToken();
}
return std::make_unique<CallStmtAST>(Callee, std::move(Args));
}
std::unique_ptr<StmtAST> Parser::ParseReturnStmt() {
getNextToken();
std::unique_ptr<ExprAST> Expr = nullptr;
if (CurTok != tok_endif && CurTok != tok_else && CurTok != tok_endfunction && CurTok != tok_endprocedure) {
Expr = ParseExpression();
}
return std::make_unique<ReturnStmtAST>(std::move(Expr));
}
|