Make Local Declarations Explicit #38
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
i = 0
|
var i = 0
|
||||||
|
|
||||||
while i < 5:
|
while i < 5:
|
||||||
@print("hello, world")
|
@print("hello, world")
|
||||||
|
|
|
@ -213,16 +213,11 @@ pub const RuntimeEnv = struct {
|
||||||
.local_set => |local_set| {
|
.local_set => |local_set| {
|
||||||
try self.compile_expression(chunk, local_set.value_expression.*);
|
try self.compile_expression(chunk, local_set.value_expression.*);
|
||||||
|
|
||||||
if (self.resolve_local(local_set.identifier)) |index| {
|
try chunk.opcodes.push_one(.{
|
||||||
try chunk.opcodes.push_one(.{.local_set = index});
|
.local_set = self.resolve_local(local_set.identifier) orelse {
|
||||||
} else {
|
return chunk.env.raise(error.BadSyntax, "undefined local");
|
||||||
if (self.local_identifiers_count == self.local_identifiers_buffer.len) {
|
},
|
||||||
return chunk.env.raise(error.BadSyntax, "chunks may have a maximum of 255 locals");
|
});
|
||||||
}
|
|
||||||
|
|
||||||
self.local_identifiers_buffer[self.local_identifiers_count] = local_set.identifier;
|
|
||||||
self.local_identifiers_count += 1;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
.field_get => |field_get| {
|
.field_get => |field_get| {
|
||||||
|
@ -271,6 +266,17 @@ pub const RuntimeEnv = struct {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
.local_var => |local_var| {
|
||||||
|
try self.compile_expression(chunk, local_var.assigned_expression);
|
||||||
|
|
||||||
|
if (self.local_identifiers_count == self.local_identifiers_buffer.len) {
|
||||||
|
return chunk.env.raise(error.BadSyntax, "chunks may have a maximum of 255 locals");
|
||||||
|
}
|
||||||
|
|
||||||
|
self.local_identifiers_buffer[self.local_identifiers_count] = local_var.identifier;
|
||||||
|
self.local_identifiers_count += 1;
|
||||||
|
},
|
||||||
|
|
||||||
.block => |block| {
|
.block => |block| {
|
||||||
for (block.values) |block_statement| {
|
for (block.values) |block_statement| {
|
||||||
try self.compile_statement(chunk, block_statement);
|
try self.compile_statement(chunk, block_statement);
|
||||||
|
|
|
@ -139,6 +139,11 @@ pub const ParseError = error {
|
||||||
pub const Statement = union (enum) {
|
pub const Statement = union (enum) {
|
||||||
@"return": ?Expression,
|
@"return": ?Expression,
|
||||||
|
|
||||||
|
local_var: struct {
|
||||||
|
identifier: []const coral.io.Byte,
|
||||||
|
assigned_expression: Expression,
|
||||||
|
},
|
||||||
|
|
||||||
@"if": struct {
|
@"if": struct {
|
||||||
condition_expression: Expression,
|
condition_expression: Expression,
|
||||||
block_statements: List,
|
block_statements: List,
|
||||||
|
@ -650,6 +655,30 @@ pub const Tree = struct {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
.keyword_var => {
|
||||||
|
self.tokenizer.skip_newlines();
|
||||||
|
|
||||||
|
const identifier = switch (self.tokenizer.token) {
|
||||||
|
.identifier => |identifier| identifier,
|
||||||
|
else => return self.report("expected identifier after `var` declaration statement"),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.tokenizer.skip_newlines();
|
||||||
|
|
||||||
|
if (self.tokenizer.token != .symbol_equals) {
|
||||||
|
return self.report("expected `=` after declaration identifier");
|
||||||
|
}
|
||||||
|
|
||||||
|
self.tokenizer.skip_newlines();
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.local_var = .{
|
||||||
|
.assigned_expression = try self.parse_expression(),
|
||||||
|
.identifier = identifier,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
.keyword_if => return self.parse_branch(),
|
.keyword_if => return self.parse_branch(),
|
||||||
else => return .{.expression = try self.parse_expression()},
|
else => return .{.expression = try self.parse_expression()},
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ pub const Token = union(enum) {
|
||||||
keyword_while,
|
keyword_while,
|
||||||
keyword_else,
|
keyword_else,
|
||||||
keyword_elif,
|
keyword_elif,
|
||||||
|
keyword_var,
|
||||||
|
|
||||||
pub fn text(self: Token) []const coral.io.Byte {
|
pub fn text(self: Token) []const coral.io.Byte {
|
||||||
return switch (self) {
|
return switch (self) {
|
||||||
|
@ -91,6 +92,7 @@ pub const Token = union(enum) {
|
||||||
.keyword_while => "while",
|
.keyword_while => "while",
|
||||||
.keyword_elif => "elif",
|
.keyword_elif => "elif",
|
||||||
.keyword_else => "else",
|
.keyword_else => "else",
|
||||||
|
.keyword_var => "var",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -261,6 +263,14 @@ pub const Tokenizer = struct {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'v' => {
|
||||||
|
if (coral.io.ends_with(identifier, "ar")) {
|
||||||
|
self.token = .keyword_var;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
'w' => {
|
'w' => {
|
||||||
if (coral.io.ends_with(identifier, "hile")) {
|
if (coral.io.ends_with(identifier, "hile")) {
|
||||||
self.token = .keyword_while;
|
self.token = .keyword_while;
|
||||||
|
|
Loading…
Reference in New Issue