Skip to content

Commit

Permalink
Support getters and setters (#213)
Browse files Browse the repository at this point in the history
* evaluate object value members if out is passed

* implement getters and setters for object literals

* update object_macro test

* mention getters and setters in the docs

* update the changelog
  • Loading branch information
JeanJPNM committed Nov 17, 2023
1 parent 2f492e5 commit e10534d
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 3 deletions.
1 change: 1 addition & 0 deletions compiler/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Added support for getters and setters.
- Added brief documentation to some senseable properties.
- Added typings for the `id` property on symbols.
- Added the `getBuildings` helper function.
Expand Down
49 changes: 47 additions & 2 deletions compiler/src/handlers/Object.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import { CompilerError } from "../CompilerError";
import { es, IInstruction, IValue, THandler } from "../types";
import {
es,
IInstruction,
IScope,
IValue,
TEOutput,
THandler,
TValueInstructions,
} from "../types";
import { extractDestrucuringOut, pipeInsts } from "../utils";
import {
AssignmentValue,
BaseValue,
DestructuringValue,
IObjectValueData,
LazyValue,
Expand Down Expand Up @@ -39,7 +48,19 @@ export const ObjectExpression: THandler = (
const memberOut = extractDestrucuringOut(out, index);
const member = pipeInsts(c.handleEval(scope, value, memberOut), inst);

data[index] = member;
if (prop.type !== "ObjectMethod" || prop.kind === "method") {
data[index] = member;
} else {
if (!(data[index] instanceof ObjectGetSetEntry))
data[index] = new ObjectGetSetEntry();
const entry = data[index] as ObjectGetSetEntry;

if (prop.kind === "get") {
entry.getter = member;
} else {
entry.setter = member;
}
}
}
return [new ObjectValue(data), inst];
};
Expand Down Expand Up @@ -200,3 +221,27 @@ export const AssignmentPattern: THandler<IValue> = (

return [new AssignmentValue(left, right), inst];
};

class ObjectGetSetEntry extends BaseValue {
macro = true;
getter?: IValue;
setter?: IValue;

constructor() {
super();
}

eval(scope: IScope, out?: TEOutput): TValueInstructions {
if (!this.getter)
throw new CompilerError("This property does not have a getter");
const [value, inst] = this.getter.call(scope, [], out);
return [value ?? new LiteralValue(null), inst];
}

"="(scope: IScope, value: IValue, out?: TEOutput): TValueInstructions {
if (!this.setter)
throw new CompilerError("This property does not have a setter");
const [, inst] = this.setter.call(scope, [value], out);
return [value, inst];
}
}
4 changes: 3 additions & 1 deletion compiler/src/values/ObjectValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ export class ObjectValue extends VoidValue {
// constructor or toString
if (Object.prototype.hasOwnProperty.call(this.data, key.data)) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return [this.data[key.data]!, []];
const member = this.data[key.data]!;
if (out) return member.eval(scope, out);
return [member, []];
}
}

Expand Down
4 changes: 4 additions & 0 deletions compiler/test/in/object_macro.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@ const obj = {
c(number) {
print("Number is ", number);
},
get d() {
return Math.rand(10);
},
};

print(obj.a);
print(obj.b);
print(obj[0]);
obj.c(20);
print(obj.d);

printFlush();
2 changes: 2 additions & 0 deletions compiler/test/out/object_macro.mlog
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ print "String literal"
print "number index"
print "Number is "
print 20
op rand &t0:&t1 10
print &t0:&t1
printflush message1
1 change: 1 addition & 0 deletions website/docs/guide/syntax-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ Behavior:
- Works just like [constants](#variable-declarations), inlines each value on the places it's used.
- Arrays have a compile time constant `length` property.
- Objects can be declared with getters and setters
Limitations:
Expand Down

0 comments on commit e10534d

Please sign in to comment.