Make Local Declarations Explicit #38

Merged
kayomn merged 2 commits from kym-explicit-local-declarations into main 2023-08-26 01:14:02 +02:00
4 changed files with 56 additions and 11 deletions
Showing only changes of commit 83fa162ba8 - Show all commits

View File

@ -1,5 +1,5 @@
i = 0 var i = 0
while i < 5: while i < 5:
@print("hello, world") @print("hello, world")

View File

@ -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);

View File

@ -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()},
} }

View File

@ -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;