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