Skip to content

Commit

Permalink
Builtin: Add len & puts Functions
Browse files Browse the repository at this point in the history
  • Loading branch information
kamva9697 committed Dec 30, 2023
1 parent caa1cee commit 03f293f
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 13 deletions.
63 changes: 63 additions & 0 deletions src/builtins.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
const Object = @import("object.zig").Object;
const evaluator = @import("evaluator.zig");
const Environment = @import("environment.zig").Environment;

pub fn len(alloc: Allocator, args: []*Object) !*Object {
if (args.len != 1) {
return try evaluator.newError(alloc, "Wrong number of arguments: {d}", .{args.len});
}
return switch (args[0].ty) {
.String => {
const str = args[0].cast(.String);
const length = try Object.create(Object.Integer, alloc, Object.Integer{ .value = @intCast(str.value.len) });
return length.toObject();
},
else => try evaluator.newError(
alloc,
"Argument to 'len' not supported got: {any}",
.{args[0].ty},
),
};
}

fn puts(alloc: Allocator, args: []*Object) !*Object {
var BufIn = std.ArrayList(u8).init(alloc);
defer BufIn.deinit();
const writer = BufIn.writer();
for (args) |arg| {
try arg.Inspect(alloc, writer);
}
const str = try Object.create(
Object.String,
alloc,
Object.String{ .value = try BufIn.toOwnedSliceSentinel(0) },
);

return str.toObject();
}

pub fn builtins(str: []const u8) ?*const Object {
if (std.mem.eql(u8, "len", str)) {
const builtin = &Object.Builtin{
._fn = len,
};
return &builtin.base;
}
if (std.mem.eql(u8, "puts", str)) {
const builtin = &Object.Builtin{
._fn = puts,
};
return &builtin.base;
}
return null;
}

// pub const builtins = std.ComptimeStringMap(Object.Builtin, .{
// .{
// "len", Object.Builtin{
// ._fn = len,
// },
// },
// });
33 changes: 27 additions & 6 deletions src/evaluator.zig
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const ObjectType = Object.ObjectType;
const Allocator = std.mem.Allocator;
const Math = std.math;
const Environment = @import("environment.zig").Environment;
const Builtins = @import("builtins.zig");

pub const TRUE_VALUE = &Object.Boolean{ .value = true };
pub const FALSE_VALUE = &Object.Boolean{ .value = false };
Expand Down Expand Up @@ -132,10 +133,22 @@ pub fn eval(
}

pub fn applyFunction(alloc: Allocator, fnObj: *Object, args: []*Object) !*Object {
const function = fnObj.cast(.Function);
const extendedEnv = try extendedEnvFunction(alloc, fnObj, args);
const evaluated = (try eval(alloc, function.body.toNode(), extendedEnv)).?;
return unwrapReturnValue(evaluated);
return switch (fnObj.ty) {
.Function => {
const function = fnObj.cast(.Function);
const extendedEnv = try extendedEnvFunction(alloc, fnObj, args);
const evaluated = (try eval(alloc, function.body.toNode(), extendedEnv)).?;
return unwrapReturnValue(evaluated);
},
.Builtin => {
const function = fnObj.cast(.Builtin);
const resObj = function._fn(alloc, args);
return resObj;
},
else => {
return newError(alloc, "not a function: {any}", .{fnObj.ty});
},
};
}

pub fn extendedEnvFunction(alloc: Allocator, func: *Object, args: []*Object) !*Environment {
Expand Down Expand Up @@ -174,8 +187,16 @@ pub fn evalExpressions(

pub fn evalIdentifier(alloc: Allocator, node: *Ast.Node, env: *Environment) !*Object {
const identNode = node.cast(.Identifier);
const val = env.get(identNode.value) orelse
newError(alloc, "Identifier not found: {s}", .{identNode.value});
// const val = env.get(identNode.value) orelse {
// return Builtins.builtins.get(identNode.value) orelse
// newError(alloc, "Identifier not found: {s}", .{identNode.value});
// };

const val = env.get(identNode.value) orelse {
const builtPtr = Builtins.builtins(identNode.value) orelse
try newError(alloc, "Identifier not found: {s}", .{identNode.value});
return @constCast(builtPtr);
};

return val;
}
Expand Down
26 changes: 19 additions & 7 deletions src/object.zig
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
const ast = @import("ast.zig");
const Lexer = @import("lexer.zig").Lexer;
const token = @import("token.zig");
const TokenType = token.TokenType;
const Token = token.Token;
const Node = ast.Node;
const Operator = ast.Operator;
const mem = std.mem;
const testing = std.testing;
const Environment = @import("environment.zig").Environment;

pub const Object = struct {
ty: ObjectType,

pub const BuiltinFunction = *const fn (Allocator, args: []*Object) anyerror!*Object;
pub const ObjectType = enum {
Integer,
Boolean,
Expand All @@ -22,6 +17,7 @@ pub const Object = struct {
Function,
Error,
String,
Builtin,

pub inline fn Type(comptime ty: ObjectType) type {
return switch (ty) {
Expand All @@ -32,6 +28,7 @@ pub const Object = struct {
.Function => Function,
.String => String,
.Error => Error,
.Builtin => Builtin,
};
}
pub inline fn toString(ty: ObjectType) []const u8 {
Expand All @@ -43,6 +40,7 @@ pub const Object = struct {
.Function => "Function",
.String => "String",
.Error => "Error",
.Builtin => "Builtin",
};
}
};
Expand Down Expand Up @@ -78,6 +76,9 @@ pub const Object = struct {
const str = cast(self, .String);
try writer.print("{s}", .{str.value});
},
.Builtin => {
try writer.print("Builtin Fn", .{});
},
.Function => {
const func = cast(self, .Function);

Expand All @@ -88,7 +89,6 @@ pub const Object = struct {
}
try writer.writeAll("fn");
try writer.writeAll("(");
// const joinedParms = try std.mem.join(alloc, ", ", params.items);
try writer.print("{any}", .{params.items});
try writer.writeAll(") {\n");
try (func.body.toNode()).toString(writer);
Expand All @@ -100,6 +100,17 @@ pub const Object = struct {
},
}
}

pub const Builtin = struct {
pub const Self = @This();
base: Object = .{ .ty = .Builtin },
_fn: BuiltinFunction,

pub inline fn toObject(self: *Self) *Object {
return &self.base;
}
};

pub const String = struct {
pub const Self = @This();
base: Object = .{ .ty = .String },
Expand Down Expand Up @@ -140,6 +151,7 @@ pub const Object = struct {
return &self.base;
}
};

pub const Null = struct {
pub const Self = @This();
base: Object = .{ .ty = .Null },
Expand Down

0 comments on commit 03f293f

Please sign in to comment.