Skip to content

Commit

Permalink
Add test, fix bug
Browse files Browse the repository at this point in the history
  • Loading branch information
drew-y committed Sep 9, 2024
1 parent 6500917 commit 1e062fb
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 43 deletions.
29 changes: 17 additions & 12 deletions src/__tests__/compiler.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {
e2eVoidText,
gcVoidText,
genericsText,
kitchenSink,
goodTypeInferenceText,
tcoText,
} from "./fixtures/e2e-file.js";
Expand All @@ -28,8 +27,8 @@ describe("E2E Compiler Pipeline", () => {
t.expect(fn(), "Main function returns correct value").toEqual(55n);
});

test("Compiler can compile gc objects and map correct fns", async (t) => {
const mod = await compile(gcVoidText);
test("Compiler kitchen sink", async (t) => {
const mod = await compile(kitchenSink);
const instance = getWasmInstance(mod);
t.expect(mod.validate(), "Module is valid");
const test1 = getWasmFn("test1", instance);
Expand All @@ -39,20 +38,34 @@ describe("E2E Compiler Pipeline", () => {
const test5 = getWasmFn("test5", instance);
const test6 = getWasmFn("test6", instance);
const test7 = getWasmFn("test7", instance);
const test8 = getWasmFn("test8", instance);
const test9 = getWasmFn("test9", instance);
assert(test1, "Test1 exists");
assert(test2, "Test2 exists");
assert(test3, "Test3 exists");
assert(test4, "Test4 exists");
assert(test5, "Test5 exists");
assert(test6, "Test6 exists");
assert(test7, "Test7 exists");
assert(test8, "Test8 exists");
assert(test9, "Test9 exists");

// Static method resolution tests
t.expect(test1(), "test 1 returns correct value").toEqual(13);
t.expect(test2(), "test 2 returns correct value").toEqual(1);
t.expect(test3(), "test 3 returns correct value").toEqual(2);
t.expect(test4(), "test 4 returns correct value").toEqual(52);

// Match based type narrowing (and basic gc)
t.expect(test5(), "test 5 returns correct value").toEqual(52);
t.expect(test6(), "test 6 returns correct value").toEqual(21);
t.expect(test7(), "test 7 returns correct value").toEqual(-1);

// Generic type test
t.expect(test8(), "test 8 returns correct value").toEqual(143);

// Generic object type test
t.expect(test9(), "test 9 returns correct value").toEqual(7.5);
});

test("Compiler can do tco", async (t) => {
Expand All @@ -61,12 +74,4 @@ describe("E2E Compiler Pipeline", () => {
const did = spy.mock.calls.some((call) => call[1].startsWith("fib"));
t.expect(did);
});

test("Generic fn compilation", async (t) => {
const mod = await compile(genericsText);
const instance = getWasmInstance(mod);
const main = getWasmFn("main", instance);
assert(main, "Main exists");
t.expect(main(), "main 1 returns correct value").toEqual(143);
});
});
43 changes: 27 additions & 16 deletions src/__tests__/fixtures/e2e-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub fn main()
`;

export const gcVoidText = `
export const kitchenSink = `
use std::all
obj Vec {
Expand Down Expand Up @@ -90,6 +90,32 @@ pub fn test6()
pub fn test7()
let vec = Bitly { x: 52, y: 2, z: 21 }
get_num_from_vec_sub_obj(vec)
type DSArrayI32 = DSArray<i32>
// Test generic functions, should return 143
pub fn test8()
let arr2 = ds_array_init<f64>(10)
arr2.set<f64>(0, 1.5)
arr2.get<f64>(0)
let arr: DSArrayI32 = ds_array_init<i32>(10)
arr.set<i32>(9, 143)
arr.get<i32>(9)
obj VecGeneric<T> {
x: T,
y: T,
z: T
}
// Test generic object initialization, should return 7.5
pub fn test9()
let vec = VecGeneric<i32> { x: 7, y: 2, z: 3 }
vec.x
let vec2 = VecGeneric<f64> { x: 7.5, y: 2.5, z: 3.5 }
vec2.x
`;

export const tcoText = `
Expand Down Expand Up @@ -119,18 +145,3 @@ fn fib_alias(n: i32, a: i64, b: i64) -> i64
pub fn main() -> i64
fib(10, 0i64, 1i64)
`;

export const genericsText = `
use std::all
type DSArrayI32 = DSArray<i32>
pub fn main()
let arr2 = ds_array_init<f64>(10)
arr2.set<f64>(0, 1.5)
arr2.get<f64>(0)
let arr: DSArrayI32 = ds_array_init<i32>(10)
arr.set<i32>(9, 143)
arr.get<i32>(9)
`;
4 changes: 2 additions & 2 deletions src/assembler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -446,8 +446,8 @@ const buildObjectType = (opts: CompileExprOpts, obj: ObjectType): TypeRef => {
name: field.name,
})),
],
supertype: obj.parentObj
? binaryenTypeToHeapType(mapBinaryenType(opts, obj.parentObj))
supertype: obj.parentObjType
? binaryenTypeToHeapType(mapBinaryenType(opts, obj.parentObjType))
: undefined,
});

Expand Down
2 changes: 1 addition & 1 deletion src/semantics/check-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ const checkObjectType = (obj: ObjectType): ObjectType => {
});

if (obj.parentObjExpr) {
assertValidExtension(obj, obj.parentObj);
assertValidExtension(obj, obj.parentObjType);
}

return obj;
Expand Down
4 changes: 2 additions & 2 deletions src/semantics/resolution/resolve-object-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ export const resolveObjectTypeTypes = (

if (obj.parentObjExpr) {
const parentType = getExprType(obj.parentObjExpr);
obj.parentObj = parentType?.isObjectType() ? parentType : undefined;
obj.parentObjType = parentType?.isObjectType() ? parentType : undefined;
} else {
obj.parentObj = voidBaseObject;
obj.parentObjType = voidBaseObject;
}

return obj;
Expand Down
1 change: 1 addition & 0 deletions src/syntax-objects/syntax.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ export abstract class Syntax {
};
}

/** Clone this object (Implementations should not carry over resolved type expression) */
abstract clone(parent?: Expr): Expr;

/** Should emit in compliance with core language spec */
Expand Down
19 changes: 9 additions & 10 deletions src/syntax-objects/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ export class ObjectType extends BaseType {
genericInstances?: ObjectType[];
fields: ObjectField[];
parentObjExpr?: Expr;
parentObj?: ObjectType;
parentObjType?: ObjectType;
/** Type used for locals, globals, function return type */
binaryenType?: number;

Expand All @@ -184,7 +184,7 @@ export class ObjectType extends BaseType {
this.fields.forEach((field) => {
field.typeExpr.parent = this;
});
this.parentObj = opts.parentObj;
this.parentObjType = opts.parentObj;
this.parentObjExpr = opts.parentObjExpr;
this.typeParameters = opts.typeParameters;
}
Expand Down Expand Up @@ -212,8 +212,7 @@ export class ObjectType extends BaseType {
typeExpr: field.typeExpr.clone(),
type: field.type?.clone(),
})),
parentObj: this.parentObj,
parentObjExpr: this.parentObj?.clone(),
parentObjExpr: this.parentObjExpr?.clone(),
typeParameters: this.typeParameters,
});
}
Expand All @@ -223,8 +222,8 @@ export class ObjectType extends BaseType {
return true;
}

if (this.parentObj) {
return this.parentObj.extends(ancestor);
if (this.parentObjType) {
return this.parentObjType.extends(ancestor);
}

return false;
Expand All @@ -241,8 +240,8 @@ export class ObjectType extends BaseType {

getAncestorIds(start: number[] = []): number[] {
start.push(this.idNum);
if (this.parentObj) {
return this.parentObj.getAncestorIds(start);
if (this.parentObjType) {
return this.parentObjType.getAncestorIds(start);
}
return start;
}
Expand All @@ -256,8 +255,8 @@ export class ObjectType extends BaseType {
return start;
}

if (this.parentObj) {
return this.parentObj.extensionDistance(ancestor, start + 1);
if (this.parentObjType) {
return this.parentObjType.extensionDistance(ancestor, start + 1);
}

throw new Error(`${this.name} does not extend ${ancestor.name}`);
Expand Down

0 comments on commit 1e062fb

Please sign in to comment.