Skip to content

Commit

Permalink
Allow primitives to have methods. Add string len(), charAt().
Browse files Browse the repository at this point in the history
  • Loading branch information
fubark committed Dec 18, 2022
1 parent 5af2ffe commit db3824a
Show file tree
Hide file tree
Showing 10 changed files with 321 additions and 256 deletions.
129 changes: 90 additions & 39 deletions src/bindings.zig
Original file line number Diff line number Diff line change
Expand Up @@ -37,28 +37,52 @@ pub fn bindCore(self: *cy.VM) !void {
@setCold(true);
forceSectionDep();

// Init compile time builtins.
const resize = try self.ensureMethodSymKey("resize");
var id = try self.addStruct("List");
self.iteratorObjSym = try self.ensureMethodSymKey("iterator");
self.nextObjSym = try self.ensureMethodSymKey("next");
self.pairIteratorObjSym = try self.ensureMethodSymKey("pairIterator");
self.nextPairObjSym = try self.ensureMethodSymKey("nextPair");
const add = try self.ensureMethodSymKey("add");
const insert = try self.ensureMethodSymKey("insert");
const remove = try self.ensureMethodSymKey("remove");
const sort = try self.ensureMethodSymKey("sort");
const size = try self.ensureMethodSymKey("size");
const len = try self.ensureMethodSymKey("len");
const charAt = try self.ensureMethodSymKey("charAt");

// Init compile time builtins.

// Primitive types.
var id = try self.addStruct("none");
std.debug.assert(id == cy.NoneT);
id = try self.addStruct("boolean");
std.debug.assert(id == cy.BooleanT);
id = try self.addStruct("error");
std.debug.assert(id == cy.ErrorT);
id = try self.addStruct("conststring");
std.debug.assert(id == cy.ConstStringT);
try self.addMethodSym(cy.ConstStringT, len, cy.SymbolEntry.initNativeFunc1(constStringLen));
try self.addMethodSym(cy.ConstStringT, charAt, cy.SymbolEntry.initNativeFunc1(constStringCharAt));
id = try self.addStruct("tag");
std.debug.assert(id == cy.UserTagT);
id = try self.addStruct("tagliteral");
std.debug.assert(id == cy.UserTagLiteralT);
id = try self.addStruct("integer");
std.debug.assert(id == cy.IntegerT);
id = try self.addStruct("number");
std.debug.assert(id == cy.NumberT);

id = try self.addStruct("List");
std.debug.assert(id == cy.ListS);
try self.addMethodSym(cy.ListS, resize, cy.SymbolEntry.initNativeFunc1(listResize));
self.iteratorObjSym = try self.ensureMethodSymKey("iterator");
try self.addMethodSym(cy.ListS, self.iteratorObjSym, cy.SymbolEntry.initNativeFunc1(listIterator));
self.nextObjSym = try self.ensureMethodSymKey("next");
try self.addMethodSym(cy.ListS, self.nextObjSym, cy.SymbolEntry.initNativeFunc1(listNext));
self.pairIteratorObjSym = try self.ensureMethodSymKey("pairIterator");
try self.addMethodSym(cy.ListS, self.pairIteratorObjSym, cy.SymbolEntry.initNativeFunc1(listIterator));
self.nextPairObjSym = try self.ensureMethodSymKey("nextPair");
try self.addMethodSym(cy.ListS, self.nextPairObjSym, cy.SymbolEntry.initNativeFunc2(listNextPair));
const add = try self.ensureMethodSymKey("add");
try self.addMethodSym(cy.ListS, add, cy.SymbolEntry.initNativeFunc1(listAdd));
const insert = try self.ensureMethodSymKey("insert");
try self.addMethodSym(cy.ListS, insert, cy.SymbolEntry.initNativeFunc1(listInsert));
const remove = try self.ensureMethodSymKey("remove");
try self.addMethodSym(cy.ListS, remove, cy.SymbolEntry.initNativeFunc1(listRemove));
const sort = try self.ensureMethodSymKey("sort");
try self.addMethodSym(cy.ListS, sort, cy.SymbolEntry.initNativeFunc1(listSort));
const size = try self.ensureMethodSymKey("size");
try self.addMethodSym(cy.ListS, size, cy.SymbolEntry.initNativeFunc1(listSize));

id = try self.addStruct("Map");
Expand All @@ -78,6 +102,8 @@ pub fn bindCore(self: *cy.VM) !void {

id = try self.addStruct("String");
std.debug.assert(id == cy.StringS);
try self.addMethodSym(cy.StringS, len, cy.SymbolEntry.initNativeFunc1(stringLen));
try self.addMethodSym(cy.StringS, charAt, cy.SymbolEntry.initNativeFunc1(stringCharAt));

id = try self.addStruct("Fiber");
std.debug.assert(id == cy.FiberS);
Expand Down Expand Up @@ -273,7 +299,7 @@ export fn cRelease(val: Value) void {

export fn toCStr(val: Value, len: *u32) [*:0]const u8 {
if (val.isPointer()) {
const obj = stdx.ptrCastAlign(*cy.HeapObject, val.asPointer().?);
const obj = stdx.ptrAlignCast(*cy.HeapObject, val.asPointer().?);
const dupe = std.cstr.addNullByte(gvm.alloc, obj.string.ptr[0..obj.string.len]) catch stdx.fatal();
len.* = @intCast(u32, obj.string.len);
return dupe.ptr;
Expand Down Expand Up @@ -675,8 +701,8 @@ pub fn coreNumber(vm: *cy.UserVM, args: [*]const Value, nargs: u8) Value {
return Value.initF64(1);
} else {
switch (val.getTag()) {
cy.TagUserTag => return Value.initF64(@intToFloat(f64, val.val & @as(u64, 0xFF))),
cy.TagUserTagLiteral => return Value.initF64(@intToFloat(f64, val.val & @as(u64, 0xFF))),
cy.UserTagT => return Value.initF64(@intToFloat(f64, val.val & @as(u64, 0xFF))),
cy.UserTagLiteralT => return Value.initF64(@intToFloat(f64, val.val & @as(u64, 0xFF))),
else => return Value.initF64(1),
}
}
Expand Down Expand Up @@ -766,7 +792,7 @@ fn fromCyonValue(self: *cy.UserVM, val: cy.DecodeValueIR) !Value {
var iter = dmap.iterator();

const mapVal = try gvm.allocEmptyMap();
const map = stdx.ptrCastAlign(*cy.HeapObject, mapVal.asPointer().?);
const map = stdx.ptrAlignCast(*cy.HeapObject, mapVal.asPointer().?);
while (iter.next()) |entry| {
const child = try fromCyonValue(self, dmap.getValue(entry.key_ptr.*));
const key = try self.allocString(entry.key_ptr.*);
Expand All @@ -785,7 +811,7 @@ fn fromCyonValue(self: *cy.UserVM, val: cy.DecodeValueIR) !Value {
}

fn stdMapPut(_: *cy.UserVM, obj: *cy.HeapObject, key: Value, value: Value) void {
const map = stdx.ptrCastAlign(*cy.MapInner, &obj.map.inner);
const map = stdx.ptrAlignCast(*cy.MapInner, &obj.map.inner);
map.put(gvm.alloc, gvm, key, value) catch stdx.fatal();
}

Expand All @@ -795,8 +821,8 @@ fn listSort(_: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8) Val
stdx.panic("Args mismatch");
}

const obj = stdx.ptrCastAlign(*cy.HeapObject, ptr);
const list = stdx.ptrCastAlign(*cy.List(Value), &obj.list.list);
const obj = stdx.ptrAlignCast(*cy.HeapObject, ptr);
const list = stdx.ptrAlignCast(*cy.List(Value), &obj.list.list);
const LessContext = struct {
lessFn: Value,
};
Expand Down Expand Up @@ -827,8 +853,8 @@ fn listSort(_: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8) Val
fn listRemove(_: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8) Value {
_ = nargs;
const index = @floatToInt(usize, args[0].toF64());
const list = stdx.ptrCastAlign(*cy.HeapObject, ptr);
const inner = stdx.ptrCastAlign(*cy.List(Value), &list.list.list);
const list = stdx.ptrAlignCast(*cy.HeapObject, ptr);
const inner = stdx.ptrAlignCast(*cy.List(Value), &list.list.list);
inner.remove(index);
vm_.releaseObject(gvm, list);
return Value.None;
Expand All @@ -838,8 +864,8 @@ fn listInsert(_: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8) V
_ = nargs;
const index = @floatToInt(usize, args[0].toF64());
const value = args[1];
const list = stdx.ptrCastAlign(*cy.HeapObject, ptr);
const inner = stdx.ptrCastAlign(*cy.List(Value), &list.list.list);
const list = stdx.ptrAlignCast(*cy.HeapObject, ptr);
const inner = stdx.ptrAlignCast(*cy.List(Value), &list.list.list);
if (inner.len == inner.buf.len) {
inner.growTotalCapacity(gvm.alloc, inner.len + 1) catch stdx.fatal();
}
Expand All @@ -852,8 +878,8 @@ fn listAdd(vm: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8) Val
if (nargs == 0) {
stdx.panic("Args mismatch");
}
const list = stdx.ptrCastAlign(*cy.HeapObject, ptr);
const inner = stdx.ptrCastAlign(*cy.List(Value), &list.list.list);
const list = stdx.ptrAlignCast(*cy.HeapObject, ptr);
const inner = stdx.ptrAlignCast(*cy.List(Value), &list.list.list);
if (inner.len == inner.buf.len) {
inner.growTotalCapacity(gvm.alloc, inner.len + 1) catch stdx.fatal();
}
Expand All @@ -866,7 +892,7 @@ fn listAdd(vm: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8) Val
fn listNextPair(_: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8) cy.ValuePair {
_ = args;
_ = nargs;
const list = stdx.ptrCastAlign(*cy.HeapObject, ptr);
const list = stdx.ptrAlignCast(*cy.HeapObject, ptr);
if (list.list.nextIterIdx < list.list.list.len) {
defer list.list.nextIterIdx += 1;
const val = list.list.list.ptr[list.list.nextIterIdx];
Expand All @@ -884,7 +910,7 @@ fn listNextPair(_: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8)
fn listNext(_: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8) Value {
_ = args;
_ = nargs;
const list = stdx.ptrCastAlign(*cy.HeapObject, ptr);
const list = stdx.ptrAlignCast(*cy.HeapObject, ptr);
if (list.list.nextIterIdx < list.list.list.len) {
defer list.list.nextIterIdx += 1;
const val = list.list.list.ptr[list.list.nextIterIdx];
Expand All @@ -896,7 +922,7 @@ fn listNext(_: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8) Val
fn listIterator(_: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8) Value {
_ = args;
_ = nargs;
const list = stdx.ptrCastAlign(*cy.HeapObject, ptr);
const list = stdx.ptrAlignCast(*cy.HeapObject, ptr);
gvm.retainObject(list);
list.list.nextIterIdx = 0;
return Value.initPtr(ptr);
Expand All @@ -906,8 +932,8 @@ fn listResize(_: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8) V
if (nargs == 0) {
stdx.panic("Args mismatch");
}
const list = stdx.ptrCastAlign(*cy.HeapObject, ptr);
const inner = stdx.ptrCastAlign(*cy.List(Value), &list.list.list);
const list = stdx.ptrAlignCast(*cy.HeapObject, ptr);
const inner = stdx.ptrAlignCast(*cy.List(Value), &list.list.list);
const size = @floatToInt(u32, args[0].toF64());
inner.resize(gvm.alloc, size) catch stdx.fatal();
vm_.releaseObject(gvm, list);
Expand All @@ -917,7 +943,7 @@ fn listResize(_: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8) V
fn mapIterator(vm: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8) linksection(Section) Value {
_ = nargs;
_ = args;
const obj = stdx.ptrCastAlign(*cy.HeapObject, ptr);
const obj = stdx.ptrAlignCast(*cy.HeapObject, ptr);
vm.retainObject(obj);
obj.map.inner.extra = 0;
return Value.initPtr(ptr);
Expand All @@ -926,7 +952,7 @@ fn mapIterator(vm: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8)
fn mapNextPair(_: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8) linksection(Section) cy.ValuePair {
_ = args;
_ = nargs;
const obj = stdx.ptrCastAlign(*cy.HeapObject, ptr);
const obj = stdx.ptrAlignCast(*cy.HeapObject, ptr);
const map = @ptrCast(*cy.ValueMap, &obj.map.inner);
if (map.next()) |entry| {
gvm.retain(entry.key);
Expand All @@ -944,7 +970,7 @@ fn mapNextPair(_: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8)
fn mapNext(_: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8) linksection(Section) Value {
_ = args;
_ = nargs;
const obj = stdx.ptrCastAlign(*cy.HeapObject, ptr);
const obj = stdx.ptrAlignCast(*cy.HeapObject, ptr);
const map = @ptrCast(*cy.ValueMap, &obj.map.inner);
if (map.next()) |entry| {
gvm.retain(entry.value);
Expand All @@ -955,8 +981,8 @@ fn mapNext(_: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8) link
fn mapSize(_: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8) Value {
_ = nargs;
_ = args;
const obj = stdx.ptrCastAlign(*cy.HeapObject, ptr);
const inner = stdx.ptrCastAlign(*cy.MapInner, &obj.map.inner);
const obj = stdx.ptrAlignCast(*cy.HeapObject, ptr);
const inner = stdx.ptrAlignCast(*cy.MapInner, &obj.map.inner);
vm_.releaseObject(gvm, obj);
return Value.initF64(@intToFloat(f64, inner.size));
}
Expand All @@ -965,8 +991,8 @@ fn mapRemove(_: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8) Va
if (nargs == 0) {
stdx.panic("Args mismatch");
}
const obj = stdx.ptrCastAlign(*cy.HeapObject, ptr);
const inner = stdx.ptrCastAlign(*cy.MapInner, &obj.map.inner);
const obj = stdx.ptrAlignCast(*cy.HeapObject, ptr);
const inner = stdx.ptrAlignCast(*cy.MapInner, &obj.map.inner);
_ = inner.remove(gvm, args[0]);
return Value.None;
}
Expand All @@ -975,8 +1001,8 @@ fn listSize(_: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, nargs: u8) Val
@setRuntimeSafety(debug);
_ = nargs;
_ = args;
const list = stdx.ptrCastAlign(*cy.HeapObject, ptr);
const inner = stdx.ptrCastAlign(*cy.List(Value), &list.list.list);
const list = stdx.ptrAlignCast(*cy.HeapObject, ptr);
const inner = stdx.ptrAlignCast(*cy.List(Value), &list.list.list);
vm_.releaseObject(gvm, list);
return Value.initF64(@intToFloat(f64, inner.len));
}
Expand Down Expand Up @@ -1179,4 +1205,29 @@ pub fn osUnsetEnv(vm: *cy.UserVM, args: [*]const Value, _: u8) Value {
}

pub extern "c" fn setenv(name: [*:0]const u8, value: [*:0]const u8, overwrite: c_int) c_int;
pub extern "c" fn unsetenv(name: [*:0]const u8) c_int;
pub extern "c" fn unsetenv(name: [*:0]const u8) c_int;

fn stringLen(vm: *cy.UserVM, ptr: *anyopaque, _: [*]const Value, _: u8) Value {
const obj = stdx.ptrAlignCast(*cy.HeapObject, ptr);
defer vm.releaseObject(obj);
return Value.initF64(@intToFloat(f64, obj.string.len));
}

fn stringCharAt(vm: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, _: u8) Value {
const obj = stdx.ptrAlignCast(*cy.HeapObject, ptr);
defer vm.releaseObject(obj);
return Value.initF64(@intToFloat(f64, obj.string.ptr[@floatToInt(u32, args[0].toF64())]));
}

fn constStringLen(_: *cy.UserVM, ptr: *anyopaque, _: [*]const Value, _: u8) Value {
const val = Value{ .val = @ptrToInt(ptr) };
const str = val.asConstStr();
return Value.initF64(@intToFloat(f64, str.len()));
}

fn constStringCharAt(_: *cy.UserVM, ptr: *anyopaque, args: [*]const Value, _: u8) Value {
const val = Value{ .val = @ptrToInt(ptr) };
const str = val.asConstStr();
const idx = @floatToInt(u32, args[0].toF64());
return Value.initF64(@intToFloat(f64, gvm.strBuf[str.start + idx]));
}
15 changes: 8 additions & 7 deletions src/cyber.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@ pub const unescapeString = vm_compiler.unescapeString;
const value = @import("value.zig");
pub const Value = value.Value;
pub const ValuePair = value.ValuePair;
pub const TagBoolean = value.TagBoolean;
pub const TagNone = value.TagNone;
pub const TagError = value.TagError;
pub const TagConstString = value.TagConstString;
pub const TagUserTag = value.TagUserTag;
pub const TagUserTagLiteral = value.TagUserTagLiteral;
pub const TagInteger = value.TagInteger;
pub const BooleanT = value.BooleanT;
pub const NoneT = value.NoneT;
pub const ErrorT = value.ErrorT;
pub const ConstStringT = value.ConstStringT;
pub const UserTagT = value.UserTagT;
pub const UserTagLiteralT = value.UserTagLiteralT;
pub const IntegerT = value.IntegerT;
pub const NumberT = value.NumberT;

pub const ValueUserTag = value.ValueUserTag;

Expand Down
14 changes: 7 additions & 7 deletions src/map.zig
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,13 @@ pub const ValueMap = struct {
return std.hash.Wyhash.hash(0, std.mem.asBytes(&key.val));
} else {
if (key.isPointer()) {
const obj = stdx.ptrCastAlign(*cy.HeapObject, key.asPointer().?);
const obj = stdx.ptrAlignCast(*cy.HeapObject, key.asPointer().?);
if (obj.common.structId == cy.StringS) {
return std.hash.Wyhash.hash(0, obj.string.ptr[0..obj.string.len]);
} else stdx.unsupported();
} else {
switch (key.getTag()) {
cy.TagConstString => {
cy.ConstStringT => {
const slice = key.asConstStr();
return std.hash.Wyhash.hash(0, vm.strBuf[slice.start..slice.end]);
},
Expand All @@ -176,13 +176,13 @@ pub const ValueMap = struct {
fn stringKeyEqual(vm: *const cy.VM, a: []const u8, b: cy.Value) linksection(section) bool {
@setRuntimeSafety(debug);
if (b.isPointer()) {
const obj = stdx.ptrCastAlign(*cy.HeapObject, b.asPointer().?);
const obj = stdx.ptrAlignCast(*cy.HeapObject, b.asPointer().?);
if (obj.common.structId == cy.StringS) {
return std.mem.eql(u8, a, obj.string.ptr[0..obj.string.len]);
} else return false;
} else {
const bTag = b.getTag();
if (bTag == cy.TagConstString) {
if (bTag == cy.ConstStringT) {
const bSlice = b.asConstStr();
const bStr = vm.strBuf[bSlice.start..bSlice.end];
return std.mem.eql(u8, a, bStr);
Expand All @@ -197,7 +197,7 @@ pub const ValueMap = struct {
return a.val == b.val;
} else {
if (a.isPointer()) {
const aObj = stdx.ptrCastAlign(*cy.HeapObject, a.asPointer().?);
const aObj = stdx.ptrAlignCast(*cy.HeapObject, a.asPointer().?);
if (aObj.common.structId == cy.StringS) {
const aStr = aObj.string.ptr[0..aObj.string.len];
if (b.getUserTag() == .string) {
Expand All @@ -207,9 +207,9 @@ pub const ValueMap = struct {
} else stdx.unsupported();
} else {
switch (a.getTag()) {
cy.TagConstString => {
cy.ConstStringT => {
const bTag = b.getTag();
if (bTag == cy.TagConstString) {
if (bTag == cy.ConstStringT) {
const aSlice = a.asConstStr();
const bSlice = b.asConstStr();
const aStr = vm.strBuf[aSlice.start..aSlice.end];
Expand Down
Loading

0 comments on commit db3824a

Please sign in to comment.