Skip to content

Commit

Permalink
Support nominal object initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
drew-y committed Aug 31, 2024
1 parent e60cac5 commit 088b1d3
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 15 deletions.
42 changes: 31 additions & 11 deletions src/semantics/init-entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,16 @@ export const initEntities: SemanticProcessor = (expr) => {
return initTypeAlias(expr);
}

// Object literal
if (expr.calls("object")) {
return initObjectLiteral(expr);
}

// Nominal object definition
if (expr.calls("obj")) {
return initNominalObjectType(expr);
}

return initCall(expr);
};

Expand Down Expand Up @@ -228,22 +234,36 @@ const initTypeExprEntities = (type?: Expr): Expr | undefined => {
throw new Error("Invalid type entity");
};

const initNominalObjectType = (obj: List) => {
const hasExtension = obj.optionalIdentifierAt(2)?.is("extends");
return new ObjectType({
...obj.metadata,
name: obj.identifierAt(1),
parentObjExpr: hasExtension ? obj.at(3) : undefined,
value: extractObjectFields(hasExtension ? obj.listAt(4) : obj.listAt(2)),
});
};

const initObjectType = (obj: List) => {
return new ObjectType({
...obj.metadata,
name: obj.syntaxId.toString(),
value: obj.sliceAsArray(1).map((v) => {
if (!v.isList()) {
throw new Error("Invalid object field");
}
const name = v.identifierAt(1);
const typeExpr = initTypeExprEntities(v.at(2));
value: extractObjectFields(obj),
});
};

if (!name || !typeExpr) {
throw new Error("Invalid object field");
}
const extractObjectFields = (obj: List) => {
return obj.sliceAsArray(1).map((v) => {
if (!v.isList()) {
throw new Error("Invalid object field");
}
const name = v.identifierAt(1);
const typeExpr = initTypeExprEntities(v.at(2));

return { name: name.value, typeExpr };
}),
if (!name || !typeExpr) {
throw new Error("Invalid object field");
}

return { name: name.value, typeExpr };
});
};
2 changes: 2 additions & 0 deletions src/semantics/init-primitive-types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { i32, f32, i64, f64, bool, dVoid } from "../syntax-objects/types.js";
import { voidBaseObject } from "../syntax-objects/types.js";
import { SemanticProcessor } from "./types.js";

export const initPrimitiveTypes: SemanticProcessor = (expr) => {
Expand All @@ -8,5 +9,6 @@ export const initPrimitiveTypes: SemanticProcessor = (expr) => {
expr.registerEntity(f64);
expr.registerEntity(bool);
expr.registerEntity(dVoid);
expr.registerEntity(voidBaseObject);
return expr;
};
7 changes: 7 additions & 0 deletions src/syntax-objects/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ export class List extends Syntax {
return id;
}

optionalIdentifierAt(index: number): Identifier | undefined {
const id = this.at(index);
if (id?.isIdentifier()) {
return id;
}
}

listAt(index: number): List {
const id = this.at(index);
if (!id?.isList()) {
Expand Down
9 changes: 5 additions & 4 deletions src/syntax-objects/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,20 +163,22 @@ export type ObjectField = { name: string; typeExpr: Expr; type?: Type };
export class ObjectType extends BaseType {
readonly kindOfType = "object";
fields: ObjectField[];
parentObjExpr?: Expr;
parentObj?: ObjectType;
/** Type used for locals, globals, function return type */
binaryenType?: number;

constructor(
opts: NamedEntityOpts & {
value: ObjectField[];
parentObj?: ObjectType | null;
parentObjExpr?: Expr;
parentObj?: ObjectType;
}
) {
super(opts);
this.fields = opts.value;
this.parentObj =
opts.parentObj !== null ? opts.parentObj ?? voidBaseObject : undefined;
this.parentObj = opts.parentObj;
this.parentObjExpr = opts.parentObjExpr;
}

get size() {
Expand Down Expand Up @@ -293,6 +295,5 @@ export const dVoid = PrimitiveType.from("void");
export const voidBaseObject = new ObjectType({
name: "Object",
value: [],
parentObj: null,
});
export const CDT_ADDRESS_TYPE = i32;

0 comments on commit 088b1d3

Please sign in to comment.