Skip to content

Commit 09ef821

Browse files
committed
Add assignment
1 parent 7eb58b8 commit 09ef821

File tree

4 files changed

+50
-9
lines changed

4 files changed

+50
-9
lines changed

docs/grammar.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ $$
55
\begin{cases}
66
\text{exit}([\text{Expr}]); \\
77
\text{let}\space\text{ident} = [\text{Expr}]; \\
8+
\text{ident} = \text{[Expr]}; \\
89
\text{if} ([\text{Expr}])[\text{Scope}]\text{[IfPred]}\\
910
[\text{Scope}]
1011
\end{cases} \\

src/generation.hpp

+19-2
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,20 @@ class Generator {
188188
gen.m_output << " ;; /let\n";
189189
}
190190

191+
void operator()(const NodeStmtAssign* stmt_assign) const
192+
{
193+
const auto it = std::ranges::find_if(gen.m_vars, [&](const Var& var) {
194+
return var.name == stmt_assign->ident.value.value();
195+
});
196+
if (it == gen.m_vars.end()) {
197+
std::cerr << "Undeclared identifier: " << stmt_assign->ident.value.value() << std::endl;
198+
exit(EXIT_FAILURE);
199+
}
200+
gen.gen_expr(stmt_assign->expr);
201+
gen.pop("rax");
202+
gen.m_output << " mov [rsp + " << (gen.m_stack_size - it->stack_loc - 1) * 8 << "], rax\n";
203+
}
204+
191205
void operator()(const NodeScope* scope) const
192206
{
193207
gen.m_output << " ;; scope\n";
@@ -204,13 +218,16 @@ class Generator {
204218
gen.m_output << " test rax, rax\n";
205219
gen.m_output << " jz " << label << "\n";
206220
gen.gen_scope(stmt_if->scope);
207-
gen.m_output << " jmp " << label << "\n";
208-
gen.m_output << label << ":\n";
209221
if (stmt_if->pred.has_value()) {
210222
const std::string end_label = gen.create_label();
223+
gen.m_output << " jmp " << end_label << "\n";
224+
gen.m_output << label << ":\n";
211225
gen.gen_if_pred(stmt_if->pred.value(), end_label);
212226
gen.m_output << end_label << ":\n";
213227
}
228+
else {
229+
gen.m_output << label << ":\n";
230+
}
214231
gen.m_output << " ;; /if\n";
215232
}
216233
};

src/parser.hpp

+22-1
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,13 @@ struct NodeStmtIf {
8989
std::optional<NodeIfPred*> pred;
9090
};
9191

92+
struct NodeStmtAssign {
93+
Token ident;
94+
NodeExpr* expr {};
95+
};
96+
9297
struct NodeStmt {
93-
std::variant<NodeStmtExit*, NodeStmtLet*, NodeScope*, NodeStmtIf*> var;
98+
std::variant<NodeStmtExit*, NodeStmtLet*, NodeScope*, NodeStmtIf*, NodeStmtAssign*> var;
9499
};
95100

96101
struct NodeProg {
@@ -279,6 +284,22 @@ class Parser {
279284
stmt->var = stmt_let;
280285
return stmt;
281286
}
287+
if (peek().has_value() && peek().value().type == TokenType::ident && peek(1).has_value()
288+
&& peek(1).value().type == TokenType::eq) {
289+
const auto assign = m_allocator.alloc<NodeStmtAssign>();
290+
assign->ident = consume();
291+
consume();
292+
if (const auto expr = parse_expr()) {
293+
assign->expr = expr.value();
294+
}
295+
else {
296+
std::cerr << "Expected expression" << std::endl;
297+
exit(EXIT_FAILURE);
298+
}
299+
try_consume(TokenType::semi, "Expected `;`");
300+
auto stmt = m_allocator.emplace<NodeStmt>(assign);
301+
return stmt;
302+
}
282303
if (peek().has_value() && peek().value().type == TokenType::open_curly) {
283304
if (auto scope = parse_scope()) {
284305
auto stmt = m_allocator.emplace<NodeStmt>(scope.value());

test.hy

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
let y = (10 - 2 * 3) / 2;
2-
let x = 1; // first
2+
let x = 7; // first
33
// first
4-
if (1) {
5-
exit(69);
6-
} elif (1) {
7-
exit(68);
4+
if (0) {
5+
x = 1;
6+
} elif (0) {
7+
x = 2;
88
} else {
9-
exit(67);
9+
x = 3;
1010
}
1111

12+
exit(x);
13+
1214
/*
1315
exit(4);
1416
*/

0 commit comments

Comments
 (0)