-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathparser.cpp
119 lines (92 loc) · 2.33 KB
/
parser.cpp
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
#include "parser.hpp"
using namespace ast;
Context Parser::parse()
{
_context.setRoot(expression());
return std::move(_context);
}
Expr* Parser::expression()
{
if (_lexer.peek() == Token::Let)
{
return letExpr();
}
else if (_lexer.peek() == Token::Fun)
{
return funExpr();
}
else
{
Expr* expr = simpleExpr();
if (_lexer.accept(Token::Lparen))
{
// Function call: f(e1, e2, ...)
std::vector<Expr*> arguments;
if (_lexer.peek() != Token::Rparen)
{
arguments = expressionList();
}
_lexer.expect(Token::Rparen);
return Call::create(_context, expr, arguments);
}
else
{
// Just a simple expression
return expr;
}
}
}
// let name = value in body
Let* Parser::letExpr()
{
_lexer.expect(Token::Let);
std::string name = _lexer.expect(Token::Ident).lexeme;
_lexer.expect(Token::Equals);
Expr* value = expression();
_lexer.expect(Token::In);
Expr* body = expression();
return Let::create(_context, name, value, body);
}
// fun x, y, ... -> body
Fun* Parser::funExpr()
{
_lexer.expect(Token::Fun);
// Always at least one parameter
std::vector<std::string> parameters;
parameters.push_back(_lexer.expect(Token::Ident).lexeme);
// And maybe more, separated by commas
while (_lexer.accept(Token::Comma))
{
parameters.push_back(_lexer.expect(Token::Ident).lexeme);
}
_lexer.expect(Token::Arrow);
Expr* body = expression();
return Fun::create(_context, parameters, body);
}
// identifier or parenthesized expression
Expr* Parser::simpleExpr()
{
if (_lexer.peek() == Token::Ident)
{
std::string name = _lexer.expect(Token::Ident).lexeme;
return Var::create(_context, name);
}
else // parenthesized expression
{
_lexer.expect(Token::Lparen);
Expr* expr = expression();
_lexer.expect(Token::Rparen);
return expr;
}
}
// One or more expression separated by commas
std::vector<Expr*> Parser::expressionList()
{
std::vector<Expr*> result;
result.push_back(expression());
while (_lexer.accept(Token::Comma))
{
result.push_back(expression());
}
return result;
}