const std = @import("std"); /// An object, which is either a pair or and atom. Objects are stored in a big /// contiguous arraylist. const Object = union(enum) { /// A pair or list. A list `(1 2 3)` is equivalent to `(1 . (2 . (3 . ())))` pair: Pair, /// An integer number. TODO: Other kinds of numbers. number: i64, /// A symbol, such as `+`, `foo`, or `the-word-recursion-has-many-meanings`. /// TODO: Interning. symbol: []const u8, /// Represented as `()`. nil, /// An index with which to refer to an Object in the storage array. const Handle = enum(u32) { _ }; }; /// Represented as `(car . cdr)`. const Pair = struct { car: Object.Handle, cdr: Object.Handle, }; /// A scope or environment in which bindings may be looked up. const Environment = struct { bindings: std.StringHashMap(Object.Handle), parent: ?*Environment = null, }; /// The overall interpreter that holds all objects. const Machine = struct { objects: std.ArrayList(Object), root_env: Environment, fn init(allocator: std.mem.Allocator) Machine { const result: Machine = .{ .objects = .{}, .root_env = .{ .bindings = .init(allocator) }, }; // TODO: add basic math fns to root environment. return result; } };