luaaaaah/src/treewalker.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;
}
}
}