Skip to content

Commit 6291b4c

Browse files
committed
Very basic stack-allocated primitive variables.
1 parent aa59111 commit 6291b4c

File tree

8 files changed

+76
-38
lines changed

8 files changed

+76
-38
lines changed

ir/emit.cc

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,10 @@ void HandleParseTreeNodeBuiltinLiteral(ParseNodeIndex index,
6363
context.current_function().append<jasmin::Push>(ModuleId::Builtin());
6464
}
6565

66-
void HandleParseTreeNodeScopeStart(ParseNodeIndex index, EmitContext& context) {
67-
// TODO: This is the wrong place to do stack allocations.
66+
void HandleParseTreeNodeScopeStart(ParseNodeIndex, EmitContext&) {}
67+
68+
void HandleParseTreeNodeFunctionStart(ParseNodeIndex index,
69+
EmitContext& context) {
6870
context.current_function().append<jasmin::StackAllocate>(
6971
context.current_storage().size().value());
7072
}
@@ -134,9 +136,18 @@ Iteration HandleParseTreeNodeIdentifier(ParseNodeIndex index,
134136
auto [decl_id_index, decl_index] = context.declarator.at(index);
135137
// TODO: The declarator that this identifier is mapped to may be a constant we
136138
// can look up, but it may not be the right one!
139+
//
140+
// TODO: We should know a priori if it's a constant or not.
137141
if (auto const* constant = context.constants.mapped_range(decl_index)) {
138142
context.Push(constant->second);
139143
return Iteration::Continue;
144+
} else if (auto offset = context.current_storage().try_offset(decl_index)) {
145+
context.current_function().append<jasmin::StackOffset>(offset->value());
146+
auto qt_iter = context.statement_qualified_type.find(decl_index);
147+
NTH_REQUIRE((v.debug), qt_iter != context.statement_qualified_type.end());
148+
context.current_function().append<jasmin::Load>(
149+
type::Contour(qt_iter->second.type()).byte_width().value());
150+
return Iteration::Continue;
140151
} else {
141152
context.queue.emplace(context.queue.front()).range =
142153
context.tree.subtree_range(decl_index);

ir/function.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ using InstructionSet = jasmin::MakeInstructionSet<
154154
TypeKind, jasmin::Equal<type::Type::Kind>, Rotate, ConstructOpaqueType,
155155
ConstructPointerType, ConstructBufferPointerType, ConstructFunctionType,
156156
ConstructParametersType, jasmin::Swap, RegisterForeignFunction,
157-
InvokeForeignFunction, jasmin::Not, NoOp, Store, jasmin::StackAllocate,
158-
jasmin::StackOffset>;
157+
InvokeForeignFunction, jasmin::Not, NoOp, Store, jasmin::Load,
158+
jasmin::StackAllocate, jasmin::StackOffset>;
159159
using IrFunction = jasmin::Function<InstructionSet>;
160160

161161
std::deque<std::pair<type::FunctionType, IrFunction>>& ForeignFunctions();

ir/ir.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,9 @@ bool HandleParseTreeNodeScopeStart(ParseNodeIndex index, IrContext& context,
556556
return false;
557557
}
558558

559+
void HandleParseTreeNodeFunctionStart(ParseNodeIndex index, IrContext& context,
560+
diag::DiagnosticConsumer& diag) {}
561+
559562
void HandleParseTreeNodeBeginIfStatementTrueBranch(ParseNodeIndex index,
560563
IrContext& context,
561564
diag::DiagnosticConsumer&) {

ir/local_storage.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ struct LocalStorage {
1818
width_ += contour.byte_width();
1919
}
2020

21+
std::optional<type::ByteWidth> try_offset(ParseNodeIndex node) const {
22+
auto iter = locations_.find(node);
23+
if (iter == locations_.end()) { return std::nullopt; }
24+
return iter->second;
25+
}
26+
2127
type::ByteWidth offset(ParseNodeIndex node) const {
2228
auto iter = locations_.find(node);
2329
NTH_REQUIRE((v.debug), iter != locations_.end());

ir/module.proto

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ message InstructionProto {
3131
NOT = 20;
3232
NOOP = 21;
3333
STORE = 22;
34-
STACK_ALLOCATE = 23;
35-
STACK_OFFSET = 24;
34+
LOAD = 23;
35+
STACK_ALLOCATE = 24;
36+
STACK_OFFSET = 25;
3637
}
3738
OpCode op_code = 1;
3839
repeated uint64 content = 2;

parse/node.xmacro.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ IC_XMACRO_PARSE_NODE(ColonEqual)
4747
IC_XMACRO_PARSE_NODE(ColonColon)
4848
IC_XMACRO_PARSE_NODE(Colon)
4949
IC_XMACRO_PARSE_NODE(ScopeStart)
50+
IC_XMACRO_PARSE_NODE(FunctionStart)
5051
IC_XMACRO_PARSE_NODE(BeginIfStatementTrueBranch)
5152
IC_XMACRO_PARSE_NODE(InfixOperator)
5253
IC_XMACRO_PARSE_NODE(InvocationArgumentStart)

parse/parser.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,13 @@ void Parser::HandleNewlines(ParseTree& tree) {
173173
}
174174

175175
void Parser::HandleModule(ParseTree& tree) {
176-
ExpandState(State::Kind::StatementSequence);
176+
tree.append_leaf(ParseNode::Kind::FunctionStart, Token::Invalid());
177+
ExpandState(State{
178+
.kind = State::Kind::StatementSequence,
179+
.ambient_precedence = Precedence::Loosest(),
180+
.token = *iterator_,
181+
.subtree_start = tree.size(),
182+
});
177183
}
178184

179185
void Parser::HandleStatement(ParseTree& tree) {

parse/parser_test.cc

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ inline constexpr auto Pointer = nth::debug::MakeProperty<"pointer">(
4242
inline constexpr auto Statement = nth::debug::MakeProperty<"statement">(
4343
[](auto const &value) { return value.kind == ParseNode::Kind::Statement; });
4444

45+
inline constexpr auto FunctionStart =
46+
nth::debug::MakeProperty<"function-start">([](auto const &value) {
47+
return value.kind == ParseNode::Kind::FunctionStart;
48+
});
49+
4550
inline constexpr auto ScopeStart =
4651
nth::debug::MakeProperty<"scope-start">([](auto const &value) {
4752
return value.kind == ParseNode::Kind::ScopeStart;
@@ -99,7 +104,7 @@ NTH_TEST("parser/empty", std::string_view content) {
99104
diag::NullConsumer d;
100105
TokenBuffer buffer = lex::Lex(content, d);
101106
auto tree = Parse(buffer, d).parse_tree;
102-
NTH_EXPECT(tree.nodes() >>= ElementsAreSequentially());
107+
NTH_EXPECT(tree.nodes() >>= ElementsAreSequentially(FunctionStart()));
103108
}
104109

105110
NTH_INVOKE_TEST("parser/empty") {
@@ -114,7 +119,7 @@ NTH_TEST("parser/declaration/integer") {
114119
TokenBuffer buffer = lex::Lex("let x ::= 3", d);
115120
auto tree = Parse(buffer, d).parse_tree;
116121
NTH_EXPECT(tree.nodes() >>= ElementsAreSequentially(
117-
ScopeStart(), Let(),
122+
FunctionStart(), ScopeStart(), Let(),
118123
DeclaredIdentifier() and IdentifierToken("x"),
119124
ColonColonEqual(), HasToken(HasImmediateIntegerValue(3)),
120125
HasSubtreeSize(5), HasSubtreeSize(6)));
@@ -125,7 +130,7 @@ NTH_TEST("parser/declaration/bool") {
125130
TokenBuffer buffer = lex::Lex("let x := true", d);
126131
auto tree = Parse(buffer, d).parse_tree;
127132
NTH_EXPECT(tree.nodes() >>= ElementsAreSequentially(
128-
ScopeStart(), Let(),
133+
FunctionStart(), ScopeStart(), Let(),
129134
DeclaredIdentifier() and IdentifierToken("x"), ColonEqual(),
130135
HasToken(HasBooleanValue(true)), HasSubtreeSize(5),
131136
HasSubtreeSize(6)));
@@ -136,7 +141,7 @@ NTH_TEST("parser/comment") {
136141
TokenBuffer buffer = lex::Lex("let x ::= true // comment!", d);
137142
auto tree = Parse(buffer, d).parse_tree;
138143
NTH_EXPECT(tree.nodes() >>= ElementsAreSequentially(
139-
ScopeStart(), Let(),
144+
FunctionStart(), ScopeStart(), Let(),
140145
DeclaredIdentifier() and IdentifierToken("x"),
141146
ColonColonEqual(), HasToken(HasBooleanValue(true)),
142147
HasSubtreeSize(5), HasSubtreeSize(6)));
@@ -151,7 +156,7 @@ NTH_TEST("parser/multiple-declarations-with-newlines") {
151156
d);
152157
auto tree = Parse(buffer, d).parse_tree;
153158
NTH_EXPECT(tree.nodes() >>= ElementsAreSequentially(
154-
ScopeStart(), Let(),
159+
FunctionStart(), ScopeStart(), Let(),
155160
DeclaredIdentifier() and IdentifierToken("x"),
156161
ColonColonEqual(), HasToken(HasImmediateIntegerValue(3)),
157162
HasSubtreeSize(5), Var(),
@@ -165,7 +170,7 @@ NTH_TEST("parser/operator-precedence/plus-times") {
165170
TokenBuffer buffer = lex::Lex(R"(x + y * z)", d);
166171
auto tree = Parse(buffer, d).parse_tree;
167172
NTH_EXPECT(tree.nodes() >>= ElementsAreSequentially(
168-
ScopeStart(), IdentifierToken("x"),
173+
FunctionStart(), ScopeStart(), IdentifierToken("x"),
169174
InfixOperator(Token::Kind::Plus), IdentifierToken("y"),
170175
InfixOperator(Token::Kind::Star), IdentifierToken("z"),
171176
ExpressionPrecedenceGroup() and HasSubtreeSize(4),
@@ -178,7 +183,7 @@ NTH_TEST("parser/operator-precedence/times-plus") {
178183
TokenBuffer buffer = lex::Lex(R"(x * y + z)", d);
179184
auto tree = Parse(buffer, d).parse_tree;
180185
NTH_EXPECT(tree.nodes() >>= ElementsAreSequentially(
181-
ScopeStart(), IdentifierToken("x"),
186+
FunctionStart(), ScopeStart(), IdentifierToken("x"),
182187
InfixOperator(Token::Kind::Star), IdentifierToken("y"),
183188
ExpressionPrecedenceGroup() and HasSubtreeSize(4),
184189
InfixOperator(Token::Kind::Plus), IdentifierToken("z"),
@@ -191,7 +196,7 @@ NTH_TEST("parser/operator-precedence/plus-plus") {
191196
TokenBuffer buffer = lex::Lex(R"(x + y + z)", d);
192197
auto tree = Parse(buffer, d).parse_tree;
193198
NTH_EXPECT(tree.nodes() >>= ElementsAreSequentially(
194-
ScopeStart(), IdentifierToken("x"),
199+
FunctionStart(), ScopeStart(), IdentifierToken("x"),
195200
InfixOperator(Token::Kind::Plus), IdentifierToken("y"),
196201
InfixOperator(Token::Kind::Plus), IdentifierToken("z"),
197202
ExpressionPrecedenceGroup() and HasSubtreeSize(6),
@@ -204,7 +209,7 @@ NTH_TEST("parser/access/basic") {
204209
auto tree = Parse(buffer, d).parse_tree;
205210
NTH_EXPECT(
206211
tree.nodes() >>= ElementsAreSequentially(
207-
ScopeStart(), IdentifierToken("a"),
212+
FunctionStart(), ScopeStart(), IdentifierToken("a"),
208213
MemberExpression() and IdentifierToken("b") and HasSubtreeSize(2),
209214
Statement() and HasSubtreeSize(3), HasSubtreeSize(4)));
210215
}
@@ -215,7 +220,7 @@ NTH_TEST("parser/access/nested") {
215220
auto tree = Parse(buffer, d).parse_tree;
216221
NTH_EXPECT(
217222
tree.nodes() >>= ElementsAreSequentially(
218-
ScopeStart(), IdentifierToken("a"),
223+
FunctionStart(), ScopeStart(), IdentifierToken("a"),
219224
MemberExpression() and IdentifierToken("b") and HasSubtreeSize(2),
220225
MemberExpression() and IdentifierToken("c") and HasSubtreeSize(3),
221226
Statement() and HasSubtreeSize(4), HasSubtreeSize(5)));
@@ -227,7 +232,7 @@ NTH_TEST("parser/access/precedence") {
227232
auto tree = Parse(buffer, d).parse_tree;
228233
NTH_EXPECT(
229234
tree.nodes() >>= ElementsAreSequentially(
230-
ScopeStart(), IdentifierToken("a"),
235+
FunctionStart(), ScopeStart(), IdentifierToken("a"),
231236
MemberExpression() and IdentifierToken("b") and HasSubtreeSize(2),
232237
InfixOperator(Token::Kind::Star), IdentifierToken("c"),
233238
MemberExpression() and IdentifierToken("d") and HasSubtreeSize(2),
@@ -240,7 +245,8 @@ NTH_TEST("parser/invoke/empty") {
240245
TokenBuffer buffer = lex::Lex(R"(f())", d);
241246
auto tree = Parse(buffer, d).parse_tree;
242247
NTH_EXPECT(tree.nodes() >>= ElementsAreSequentially(
243-
ScopeStart(), IdentifierToken("f"), InvocationArgumentStart(),
248+
FunctionStart(), ScopeStart(), IdentifierToken("f"),
249+
InvocationArgumentStart(),
244250
CallExpression() and HasSubtreeSize(3),
245251
Statement() and HasSubtreeSize(4), HasSubtreeSize(5)));
246252
}
@@ -251,7 +257,7 @@ NTH_TEST("parser/invoke/empty-member-call") {
251257
auto tree = Parse(buffer, d).parse_tree;
252258
NTH_EXPECT(
253259
tree.nodes() >>= ElementsAreSequentially(
254-
ScopeStart(), IdentifierToken("a"),
260+
FunctionStart(), ScopeStart(), IdentifierToken("a"),
255261
MemberExpression() and IdentifierToken("b") and HasSubtreeSize(2),
256262
InvocationArgumentStart(), CallExpression() and HasSubtreeSize(4),
257263
Statement() and HasSubtreeSize(5), HasSubtreeSize(6)));
@@ -263,7 +269,7 @@ NTH_TEST("parser/invoke/double-call") {
263269
auto tree = Parse(buffer, d).parse_tree;
264270
NTH_EXPECT(
265271
tree.nodes() >>= ElementsAreSequentially(
266-
ScopeStart(), IdentifierToken("a"),
272+
FunctionStart(), ScopeStart(), IdentifierToken("a"),
267273
IdentifierToken("b") and MemberExpression() and HasSubtreeSize(2),
268274
InvocationArgumentStart(), CallExpression() and HasSubtreeSize(4),
269275
InvocationArgumentStart(), CallExpression() and HasSubtreeSize(6),
@@ -275,8 +281,9 @@ NTH_TEST("parser/invoke/one-positional") {
275281
TokenBuffer buffer = lex::Lex(R"(a(b))", d);
276282
auto tree = Parse(buffer, d).parse_tree;
277283
NTH_EXPECT(tree.nodes() >>= ElementsAreSequentially(
278-
ScopeStart(), IdentifierToken("a"), InvocationArgumentStart(),
279-
IdentifierToken("b"), CallExpression() and HasSubtreeSize(4),
284+
FunctionStart(), ScopeStart(), IdentifierToken("a"),
285+
InvocationArgumentStart(), IdentifierToken("b"),
286+
CallExpression() and HasSubtreeSize(4),
280287
Statement() and HasSubtreeSize(5), HasSubtreeSize(6)));
281288
}
282289

@@ -288,8 +295,9 @@ NTH_TEST("parser/invoke/one-positional-newline") {
288295
d);
289296
auto tree = Parse(buffer, d).parse_tree;
290297
NTH_EXPECT(tree.nodes() >>= ElementsAreSequentially(
291-
ScopeStart(), IdentifierToken("a"), InvocationArgumentStart(),
292-
IdentifierToken("b"), CallExpression() and HasSubtreeSize(4),
298+
FunctionStart(), ScopeStart(), IdentifierToken("a"),
299+
InvocationArgumentStart(), IdentifierToken("b"),
300+
CallExpression() and HasSubtreeSize(4),
293301
Statement() and HasSubtreeSize(5), HasSubtreeSize(6)));
294302
}
295303

@@ -298,9 +306,10 @@ NTH_TEST("parser/invoke/multiple-positional") {
298306
TokenBuffer buffer = lex::Lex(R"(a(b, c, d))", d);
299307
auto tree = Parse(buffer, d).parse_tree;
300308
NTH_EXPECT(tree.nodes() >>= ElementsAreSequentially(
301-
ScopeStart(), IdentifierToken("a"), InvocationArgumentStart(),
302-
IdentifierToken("b"), IdentifierToken("c"),
303-
IdentifierToken("d"), CallExpression() and HasSubtreeSize(6),
309+
FunctionStart(), ScopeStart(), IdentifierToken("a"),
310+
InvocationArgumentStart(), IdentifierToken("b"),
311+
IdentifierToken("c"), IdentifierToken("d"),
312+
CallExpression() and HasSubtreeSize(6),
304313
Statement() and HasSubtreeSize(7), HasSubtreeSize(8)));
305314
}
306315

@@ -312,9 +321,10 @@ NTH_TEST("parser/invoke/multiple-positional-newline") {
312321
d);
313322
auto tree = Parse(buffer, d).parse_tree;
314323
NTH_EXPECT(tree.nodes() >>= ElementsAreSequentially(
315-
ScopeStart(), IdentifierToken("a"), InvocationArgumentStart(),
316-
IdentifierToken("b"), IdentifierToken("c"),
317-
IdentifierToken("d"), CallExpression() and HasSubtreeSize(6),
324+
FunctionStart(), ScopeStart(), IdentifierToken("a"),
325+
InvocationArgumentStart(), IdentifierToken("b"),
326+
IdentifierToken("c"), IdentifierToken("d"),
327+
CallExpression() and HasSubtreeSize(6),
318328
Statement() and HasSubtreeSize(7), HasSubtreeSize(8)));
319329
}
320330

@@ -323,7 +333,7 @@ NTH_TEST("parser/invoke/access-call") {
323333
TokenBuffer buffer = lex::Lex(R"(a.b(c.d))", d);
324334
auto tree = Parse(buffer, d).parse_tree;
325335
NTH_EXPECT(tree.nodes() >>= ElementsAreSequentially(
326-
ScopeStart(), IdentifierToken("a"),
336+
FunctionStart(), ScopeStart(), IdentifierToken("a"),
327337
MemberExpression() and HasSubtreeSize(2),
328338
InvocationArgumentStart(), IdentifierToken("c"),
329339
MemberExpression() and HasSubtreeSize(2),
@@ -336,7 +346,7 @@ NTH_TEST("parser/invoke/pointer") {
336346
TokenBuffer buffer = lex::Lex(R"(*a)", d);
337347
auto tree = Parse(buffer, d).parse_tree;
338348
NTH_EXPECT(tree.nodes() >>= ElementsAreSequentially(
339-
ScopeStart(), IdentifierToken("a"),
349+
FunctionStart(), ScopeStart(), IdentifierToken("a"),
340350
Pointer() and HasSubtreeSize(2),
341351
Statement() and HasSubtreeSize(3), HasSubtreeSize(4)));
342352
}
@@ -346,7 +356,7 @@ NTH_TEST("parser/invoke/pointer-access") {
346356
TokenBuffer buffer = lex::Lex(R"(*a.b)", d);
347357
auto tree = Parse(buffer, d).parse_tree;
348358
NTH_EXPECT(tree.nodes() >>= ElementsAreSequentially(
349-
ScopeStart(), IdentifierToken("a"),
359+
FunctionStart(), ScopeStart(), IdentifierToken("a"),
350360
MemberExpression() and HasSubtreeSize(2),
351361
Pointer() and HasSubtreeSize(3),
352362
Statement() and HasSubtreeSize(4), HasSubtreeSize(5)));
@@ -357,7 +367,7 @@ NTH_TEST("parser/invoke/pointer-function") {
357367
TokenBuffer buffer = lex::Lex(R"(*a -> b)", d);
358368
auto tree = Parse(buffer, d).parse_tree;
359369
NTH_EXPECT(tree.nodes() >>= ElementsAreSequentially(
360-
ScopeStart(), IdentifierToken("a"),
370+
FunctionStart(), ScopeStart(), IdentifierToken("a"),
361371
Pointer() and HasSubtreeSize(2),
362372
InfixOperator(Token::Kind::MinusGreater), IdentifierToken("b"),
363373
ExpressionPrecedenceGroup() and HasSubtreeSize(5),
@@ -369,7 +379,7 @@ NTH_TEST("parser/invoke/buffer-pointer") {
369379
TokenBuffer buffer = lex::Lex(R"([*]a)", d);
370380
auto tree = Parse(buffer, d).parse_tree;
371381
NTH_EXPECT(tree.nodes() >>= ElementsAreSequentially(
372-
ScopeStart(), IdentifierToken("a"),
382+
FunctionStart(), ScopeStart(), IdentifierToken("a"),
373383
BufferPointer() and HasSubtreeSize(2),
374384
Statement() and HasSubtreeSize(3), HasSubtreeSize(4)));
375385
}
@@ -379,7 +389,7 @@ NTH_TEST("parser/invoke/buffer-pointer-access") {
379389
TokenBuffer buffer = lex::Lex(R"([*]a.b)", d);
380390
auto tree = Parse(buffer, d).parse_tree;
381391
NTH_EXPECT(tree.nodes() >>= ElementsAreSequentially(
382-
ScopeStart(), IdentifierToken("a"),
392+
FunctionStart(), ScopeStart(), IdentifierToken("a"),
383393
MemberExpression() and HasSubtreeSize(2),
384394
BufferPointer() and HasSubtreeSize(3),
385395
Statement() and HasSubtreeSize(4), HasSubtreeSize(5)));
@@ -390,7 +400,7 @@ NTH_TEST("parser/invoke/buffer-pointer-function") {
390400
TokenBuffer buffer = lex::Lex(R"([*]a -> b)", d);
391401
auto tree = Parse(buffer, d).parse_tree;
392402
NTH_EXPECT(tree.nodes() >>= ElementsAreSequentially(
393-
ScopeStart(), IdentifierToken("a"),
403+
FunctionStart(), ScopeStart(), IdentifierToken("a"),
394404
BufferPointer() and HasSubtreeSize(2),
395405
InfixOperator(Token::Kind::MinusGreater), IdentifierToken("b"),
396406
ExpressionPrecedenceGroup() and HasSubtreeSize(5),

0 commit comments

Comments
 (0)