From c993665ac29e7095bc6788002706cf306ae10b45 Mon Sep 17 00:00:00 2001 From: DevTaube <78918080+DevTaube@users.noreply.github.com> Date: Tue, 24 Jan 2023 19:08:59 +0200 Subject: [PATCH] Added object member pointers and general fixes Added the ".&"-syntax to create pointers of object members, fixed copying of object function members --- currant.js | 34 +++++++++++++++++++++++++++++++++- currant/nodes/node.js | 1 + currant/types/customType.js | 6 +++++- currant/types/pointer.js | 27 +++++++++++++++++++++++++++ tests/pointers.crn | 11 ++++++++++- 5 files changed, 76 insertions(+), 3 deletions(-) diff --git a/currant.js b/currant.js index 8acbc6c..938ab57 100644 --- a/currant.js +++ b/currant.js @@ -384,6 +384,7 @@ class CurrantNode { CurrantStringNode, CurrantMemberAccessNode, CurrantJsReferenceNode, + CurrantMemberPointerNode, CurrantPointerNode, CurrantFunctionNode, CurrantArrayNode, @@ -1759,6 +1760,33 @@ class CurrantPointerNode extends CurrantNode { } +class CurrantMemberPointerNode extends CurrantNode { + + constructor() { super("member-pointer"); } + + doParse() { + super.addChild(super.evalUntilLast(["dot"], true)); + super.nextToken(); + super.expectToken("ampersand"); + super.nextToken(); + super.expectToken("identifier"); + this.refName = super.token().text; + super.expectEnd(); + } + + doExecute() { + let object = super.childValue(0); + if(object.type.constructor !== CurrantCustomType) + throw new Error(`unable to access member - object does not have member "${this.refName}"`); + object = object.get(); + if(!object.variables.has(this.refName)) + throw new Error(`unable to access member - object does not have member "${this.refName}"`); + this.ref = CurrantBlockNode.staticGetVariableWrapper(object.variables, object.block, this.refName); + return new CurrantPointerType().fromNode(this); + } + +} + class CurrantPointerType extends CurrantType { varStorage(size) { return new Array(size); } instNode(node) { @@ -2000,10 +2028,14 @@ class CurrantCustomObject { constructor(data) { this.variables = new Map(); + this.block = data.block; for(const keyName of data.variables.keys()) { this.variables.set(keyName, new CurrantBlockVariableWrapperObject(data.variables.get(keyName).get().copy())); + if(this.variables.get(keyName).get().type.constructor === CurrantFunctionType) { + const functionBody = this.variables.get(keyName).get().get().body; + if(typeof functionBody !== "undefined") functionBody.block = this; + } } - this.block = data.block; } } diff --git a/currant/nodes/node.js b/currant/nodes/node.js index c405d89..c705c52 100644 --- a/currant/nodes/node.js +++ b/currant/nodes/node.js @@ -20,6 +20,7 @@ class CurrantNode { CurrantStringNode, CurrantMemberAccessNode, CurrantJsReferenceNode, + CurrantMemberPointerNode, CurrantPointerNode, CurrantFunctionNode, CurrantArrayNode, diff --git a/currant/types/customType.js b/currant/types/customType.js index 12d28d2..7c786e2 100644 --- a/currant/types/customType.js +++ b/currant/types/customType.js @@ -63,10 +63,14 @@ class CurrantCustomObject { constructor(data) { this.variables = new Map(); + this.block = data.block; for(const keyName of data.variables.keys()) { this.variables.set(keyName, new CurrantBlockVariableWrapperObject(data.variables.get(keyName).get().copy())); + if(this.variables.get(keyName).get().type.constructor === CurrantFunctionType) { + const functionBody = this.variables.get(keyName).get().get().body; + if(typeof functionBody !== "undefined") functionBody.block = this; + } } - this.block = data.block; } } diff --git a/currant/types/pointer.js b/currant/types/pointer.js index ee30065..b2214cc 100644 --- a/currant/types/pointer.js +++ b/currant/types/pointer.js @@ -18,6 +18,33 @@ class CurrantPointerNode extends CurrantNode { } +class CurrantMemberPointerNode extends CurrantNode { + + constructor() { super("member-pointer"); } + + doParse() { + super.addChild(super.evalUntilLast(["dot"], true)); + super.nextToken(); + super.expectToken("ampersand"); + super.nextToken(); + super.expectToken("identifier"); + this.refName = super.token().text; + super.expectEnd(); + } + + doExecute() { + let object = super.childValue(0); + if(object.type.constructor !== CurrantCustomType) + throw new Error(`unable to access member - object does not have member "${this.refName}"`); + object = object.get(); + if(!object.variables.has(this.refName)) + throw new Error(`unable to access member - object does not have member "${this.refName}"`); + this.ref = CurrantBlockNode.staticGetVariableWrapper(object.variables, object.block, this.refName); + return new CurrantPointerType().fromNode(this); + } + +} + class CurrantPointerType extends CurrantType { varStorage(size) { return new Array(size); } instNode(node) { diff --git a/tests/pointers.crn b/tests/pointers.crn index 2009d69..dc923e4 100644 --- a/tests/pointers.crn +++ b/tests/pointers.crn @@ -10,4 +10,13 @@ assert(*b == 420i32); *b = -10i32; -assert(a == -10i32); \ No newline at end of file +assert(a == -10i32); + + +C: type = $(val: i32) {}; + +c: C = C(5i32); +d: ptr = c.&val; +*d = 10i32; + +assert(c.val == 10i32); \ No newline at end of file