Since hashtables are a hassle with strings and complex datastructures like the table they are an arraylist for now. Also implement rawEquals for numerals and values to make table.get work
143 lines
3.3 KiB
Zig
143 lines
3.3 KiB
Zig
const std = @import("std");
|
|
const parser = @import("parser.zig");
|
|
const types = @import("types.zig");
|
|
|
|
pub fn interpret(root: parser.ChunkNode, allocator: std.mem.Allocator) !void
|
|
{
|
|
var _ENV = types.Table { .entries= std.ArrayList(types.TableEntry).init(allocator) };
|
|
try walkChunk(root, &_ENV, allocator);
|
|
}
|
|
|
|
fn walkChunk(node: parser.ChunkNode, environment: *types.Table, allocator: std.mem.Allocator) !void
|
|
{
|
|
try walkBlock(node.block, environment, allocator);
|
|
}
|
|
|
|
fn walkBlock(node: parser.BlockNode, environment: *types.Table, allocator: std.mem.Allocator) !void
|
|
{
|
|
for(node.stats.items) |stat|
|
|
{
|
|
try walkStat(stat, environment, allocator);
|
|
}
|
|
if(node.retstat != null)
|
|
{
|
|
try walkRetstat(node.retstat.?, environment, allocator);
|
|
}
|
|
}
|
|
|
|
fn walkStat(node: parser.StatNode, environment: *types.Table, allocator: std.mem.Allocator) !void
|
|
{
|
|
switch(node)
|
|
{
|
|
.Assignment => |assignmentNode|
|
|
{
|
|
return try walkAssignmentNode(assignmentNode, environment, allocator);
|
|
},
|
|
else =>
|
|
{
|
|
std.debug.print("{any}\n", .{node});
|
|
return error.NotImplemented;
|
|
}
|
|
}
|
|
}
|
|
|
|
fn walkRetstat(node: parser.RetstatNode, environment: *types.Table, allocator: std.mem.Allocator) !void
|
|
{
|
|
_ = node;
|
|
_ = environment;
|
|
_ = allocator;
|
|
return error.NotImplemented;
|
|
}
|
|
|
|
fn walkAssignmentNode(node: parser.AssignmentNode, environment: *types.Table, allocator: std.mem.Allocator) !void
|
|
{
|
|
const results = try walkExplist(node.rhs, environment, allocator);
|
|
var i: usize = 0;
|
|
_ = results;
|
|
_ = i;
|
|
for(node.lhs.vars.items) |variable|
|
|
{
|
|
switch(variable)
|
|
{
|
|
.Indexed => |indexedNode|
|
|
{
|
|
_ = indexedNode;
|
|
return error.NotImplemented;
|
|
},
|
|
else => return error.NotImplemented,
|
|
}
|
|
}
|
|
}
|
|
|
|
fn walkExplist(node: parser.ExplistNode, environment: *types.Table, allocator: std.mem.Allocator) ![]types.Value
|
|
{
|
|
var results = std.ArrayList(types.Value).init(allocator);
|
|
for(node.exps.items) |exp|
|
|
{
|
|
try results.append(try walkExp(exp, environment, allocator, false));
|
|
}
|
|
return results.toOwnedSlice();
|
|
}
|
|
|
|
fn walkExp(node: parser.ExpNode, environment: *types.Table, allocator: std.mem.Allocator, isVariadicFunction: bool) !types.Value
|
|
{
|
|
switch(node)
|
|
{
|
|
.Nil => return types.Value.Nil,
|
|
.False => return types.Value { .Bool = false },
|
|
.True => return types.Value { .Bool = true },
|
|
.Numeral => |numeral| return types.Value { .Numeral = numeral },
|
|
.LiteralString => |string| return types.Value { .String = string },
|
|
.Varargs =>
|
|
{
|
|
if(isVariadicFunction)
|
|
{
|
|
return error.NotImplemented;
|
|
}
|
|
else
|
|
{
|
|
return error.UseVarargsOutsideVariadicFunction;
|
|
}
|
|
},
|
|
.Suffixexp => |suffixExp|
|
|
{
|
|
return walkSuffixexp(suffixExp.*, environment, allocator);
|
|
},
|
|
else =>
|
|
{
|
|
std.debug.print("{}\n", .{node});
|
|
return error.NotImplemented;
|
|
}
|
|
}
|
|
return error.NotImplemented;
|
|
}
|
|
|
|
fn walkSuffixexp(node: parser.SuffixexpNode, environment: *types.Table, allocator: std.mem.Allocator) !types.Value
|
|
{
|
|
_ = allocator;
|
|
switch(node)
|
|
{
|
|
.Normal => |normal|
|
|
{
|
|
switch(normal.firstPart)
|
|
{
|
|
.Name => |name|
|
|
{
|
|
std.debug.print("name: {s}\n", .{name});
|
|
std.debug.print("val: {!}\n", .{environment.get(types.Value { .String = name })});
|
|
},
|
|
else =>
|
|
{
|
|
std.debug.print("{}\n", .{normal.firstPart});
|
|
}
|
|
}
|
|
return error.NotImplemented;
|
|
},
|
|
else =>
|
|
{
|
|
std.debug.print("{}\n", .{node});
|
|
return error.NotImplemented;
|
|
}
|
|
}
|
|
}
|