Skip to content

Commit

Permalink
Fix up enum refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
bgk- committed Feb 27, 2024
1 parent c471e29 commit 48d4382
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 30 deletions.
10 changes: 10 additions & 0 deletions docs/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,16 @@ const fib = |n| {
}
```

## Return Void

If you want to return out of a function early you have to specify `return void` and not just `return` like most langauges.

```topi
const early = || {
if (true) return void
}
```

### Enums

Enums are pretty standard
Expand Down
4 changes: 2 additions & 2 deletions src/bytecode.zig
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,8 @@ pub const Bytecode = struct {
}
},
.prong => {
const index = std.mem.readVarInt(u16, instructions[i..(i + 2)], .little);
i += 2;
const index = std.mem.readVarInt(u32, instructions[i..(i + 4)], .little);
i += 4;
writer.print("{d: >8}", .{index});
const count = instructions[i];
i += 1;
Expand Down
2 changes: 1 addition & 1 deletion src/compiler.test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ test "Functions" {
},
},
.{
.input = "|| { 5 + 10 return }",
.input = "|| { 5 + 10 return void }",
.instructions = [_]u8{
@intFromEnum(OpCode.closure),
2 + cl,
Expand Down
8 changes: 6 additions & 2 deletions src/parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ pub const Parser = struct {
fn returnStatement(self: *Parser) Error!Statement {
const start_token = self.current_token;
self.next();
if (self.currentIsOneOf(&[_]TokenType{ .eof, .right_brace })) {
if (self.currentIs(.void)) {
return .{
.token = start_token,
.type = .return_void,
Expand Down Expand Up @@ -518,7 +518,8 @@ pub const Parser = struct {
// if no braces used will parse a single statement into a list
fn block(self: *Parser) Error![]const Statement {
var list = std.ArrayList(Statement).init(self.allocator);
if (!self.currentIs(.left_brace)) {
const has_brace = self.currentIs(.left_brace);
if (!has_brace) {
try list.append(try self.statement());
return try list.toOwnedSlice();
}
Expand All @@ -527,6 +528,9 @@ pub const Parser = struct {
try list.append(try self.statement());
self.next();
}
if (has_brace and self.currentIs(.eof)) {
return self.fail("Missing closing brace", self.current_token, .{});
}
return try list.toOwnedSlice();
}

Expand Down
3 changes: 3 additions & 0 deletions src/token.zig
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ pub const TokenType = enum {
@"switch",
true,
@"var",
void,
@"while",

bough,
Expand Down Expand Up @@ -113,6 +114,7 @@ pub const Keywords = std.ComptimeStringMap(TokenType, .{
.{ "switch", .@"switch" },
.{ "true", .true },
.{ "var", .@"var" },
.{ "void", .void },
.{ "while", .@"while" },
});

Expand Down Expand Up @@ -181,6 +183,7 @@ pub fn toString(token_type: TokenType) []const u8 {
.@"switch" => "switch",
.true => "true",
.@"var" => "var",
.void => "void",
.@"while" => "while",

.bough => "bough",
Expand Down
23 changes: 10 additions & 13 deletions src/values.zig
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,11 @@ pub const Value = union(Type) {
pub fn destroy(allocator: std.mem.Allocator, obj: *Obj) void {
switch (obj.data) {
.string => |s| allocator.free(s),
.@"enum" => {},
.@"enum" => |e| {
allocator.free(e.name);
for (e.values) |val| allocator.free(val);
allocator.free(e.values);
},
.list => |l| l.deinit(),
.map => obj.data.map.deinit(),
.set => obj.data.set.deinit(),
Expand Down Expand Up @@ -323,7 +327,7 @@ pub const Value = union(Type) {
},
.enum_value => {
const index = try reader.readByte();
return .{ .enum_value = .{ .index = index, .base = undefined }};
return .{ .enum_value = .{ .index = index, .base = undefined } };
},
.obj => {
const data_type: Obj.DataType = @enumFromInt(try reader.readByte());
Expand Down Expand Up @@ -404,15 +408,7 @@ pub const Value = union(Type) {
try reader.readNoEof(name_buf);
const values_length = try reader.readByte();
const obj = try allocator.create(Value.Obj);
obj.* = .{
.data = .{
.@"enum" = .{
.allocator = allocator,
.name = name_buf,
.values = try allocator.alloc([]const u8, values_length)
}
}
};
obj.* = .{ .data = .{ .@"enum" = .{ .allocator = allocator, .name = name_buf, .values = try allocator.alloc([]const u8, values_length) } } };
for (0..values_length) |i| {
const value_name_length = try reader.readByte();
const value_name_buf = try allocator.alloc(u8, value_name_length);
Expand All @@ -434,7 +430,7 @@ pub const Value = union(Type) {
.bool => |b| writer.print("{}", .{b}),
.nil => writer.print("nil", .{}),
.visit => |v| writer.print("{d}", .{v}),
.enum_value => |e| writer.print("{s}.{s}", .{e.base.name, e.base.values[e.index]}),
.enum_value => |e| writer.print("{s}.{s}", .{ e.base.name, e.base.values[e.index] }),
.obj => |o| {
switch (o.data) {
.string => |s| writer.print("{s}", .{s}),
Expand Down Expand Up @@ -495,7 +491,7 @@ pub const Value = union(Type) {
},
.@"enum" => |e| {
writer.print("{s}{{", .{e.name});
for(e.values, 0..) |val, i| {
for (e.values, 0..) |val, i| {
writer.print("{s}", .{val});
if (i != e.values.len - 1)
writer.print(", ", .{});
Expand Down Expand Up @@ -575,6 +571,7 @@ pub const Value = union(Type) {
.bool => |bl| bl == b.bool,
.nil => b == .nil,
.visit => |v| v == b.visit,
.enum_value => |e| e.base == b.enum_value.base and e.index == b.enum_value.index,
.obj => |o| {
const b_data = b.obj.data;
if (@intFromEnum(o.data) != @intFromEnum(b_data))
Expand Down
19 changes: 10 additions & 9 deletions src/vm.test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -806,23 +806,24 @@ test "Enums" {
\\ Night
\\ }
\\
\\ switch (5) {
\\ 0..4: print(TimeOfDay.Night),
\\ 5..11: print(TimeOfDay.Morning),
\\ 12..16: print(TimeOfDay.Afternoon),
\\ 16..21: print(TimeOfDay.Evening),
\\ 22..24: print(TimeOfDay.Night),
\\ else: print(TimeOfDay.Morning)
\\ const timeOfDay = |hour| {
\\ switch (hour) {
\\ 0..4: return TimeOfDay.Night,
\\ 5..11: return TimeOfDay.Morning,
\\ 12..16: return TimeOfDay.Afternoon,
\\ 16..21: return TimeOfDay.Evening,
\\ 22..24: return TimeOfDay.Night,
\\ }
\\ }
\\
\\ print(timeOfDay(5))
\\
;
;

var mod = Module.create(allocator);
defer mod.deinit();
defer mod.entry.source_loaded = false;
var vm = try initTestVm(input, &mod, true);
var vm = try initTestVm(input, &mod, false);
defer vm.deinit();
defer vm.bytecode.free(testing.allocator);
try vm.interpret();
Expand Down
8 changes: 5 additions & 3 deletions src/vm.zig
Original file line number Diff line number Diff line change
Expand Up @@ -713,13 +713,15 @@ pub const Vm = struct {
return self.fail("Can only query instance fields by string name, not {s}", .{@tagName(index)});
if (index.obj.data != .string)
return self.fail("Can only query instance fields by string name, not {s}", .{@tagName(index.obj.data)});
var found = false;
std.debug.print("\n", .{});
for (e.values, 0..) |name, i| {
if (std.mem.eql(u8, name, index.obj.data.string)) {
try self.push(.{ .enum_value = .{ .index = @intCast(i), .base = &e }});
continue;
try self.push(.{ .enum_value = .{ .index = @intCast(i), .base = &e } });
found = true;
}
}
return self.fail("Unknown value \"{s}\" on enum {s}", .{ index.obj.data.string, e.name });
if (!found) return self.fail("Unknown value \"{s}\" on enum {s}", .{ index.obj.data.string, e.name });
},
else => return self.fail("Unknown target type {s} to index. Only lists, maps, sets, or instances can be indexed.", .{@tagName(target)}),
},
Expand Down

0 comments on commit 48d4382

Please sign in to comment.