From 7b4331a8419affa8f23a5fb7de5c75571532461c Mon Sep 17 00:00:00 2001 From: arnav-ag Date: Wed, 10 Apr 2024 23:40:16 +0800 Subject: [PATCH] Working direct array access on function calls --- src/parser/ooga.js | 124 ++++++++++++++++++++++++++--------- src/parser/ooga.pegjs | 37 ++++++----- src/vm/oogavm-typechecker.ts | 3 +- 3 files changed, 116 insertions(+), 48 deletions(-) diff --git a/src/parser/ooga.js b/src/parser/ooga.js index d887aef..491d415 100644 --- a/src/parser/ooga.js +++ b/src/parser/ooga.js @@ -503,25 +503,33 @@ function peg$parse(input, options) { var peg$f33 = function(callee, args) { // Handle function calls on member expressions return { tag: "CallExpression", callee: callee, arguments: args }; }; - var peg$f34 = function(head, args) { - return { tag: "CallExpression", arguments: args }; - }; - var peg$f35 = function(head, property) { // Support for chaining dot syntax + var peg$f34 = function(head, property) { // Support for chaining dot syntax return { - tag: "MemberExpression", - object: head, + operation: "propertyAccess", property: property }; }; + var peg$f35 = function(head, index) { // Allow for immediate index access + return { + operation: "indexAccess", + index: index + }; + }; var peg$f36 = function(head, tail) { return tail.reduce(function(result, element) { - // Depending on the type of element (call or member access), adjust the target of the call or property access - if (element.tag === "CallExpression") { - element.callee = result; - } else { // For member expressions - element.object = result; + if (element.operation === "propertyAccess") { + return { + tag: "MemberExpression", + object: result, + property: element.property + }; + } else if (element.operation === "indexAccess") { + return { + tag: "ArraySliceIndex", + arrayExpression: result, + index: element.index + }; } - return element; }, head); }; var peg$f37 = function(callee, args) { // Handles function/method calls @@ -902,7 +910,7 @@ function peg$parse(input, options) { type: { tag:'Array', elementType: {type: type}, - length: -1, + length: elements.length, is_bound: false }, elements: elements, @@ -3383,7 +3391,7 @@ function peg$parse(input, options) { } function peg$parseCallExpression() { - var s0, s1, s2, s3, s4, s5, s6, s7; + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; s0 = peg$currPos; s1 = peg$currPos; @@ -3409,10 +3417,23 @@ function peg$parse(input, options) { s2 = []; s3 = peg$currPos; s4 = peg$parse__(); - s5 = peg$parseArguments(); + if (input.charCodeAt(peg$currPos) === 46) { + s5 = peg$c6; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e16); } + } if (s5 !== peg$FAILED) { - peg$savedPos = s3; - s3 = peg$f34(s1, s5); + s6 = peg$parse__(); + s7 = peg$parseIdentifier(); + if (s7 !== peg$FAILED) { + peg$savedPos = s3; + s3 = peg$f34(s1, s7); + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } } else { peg$currPos = s3; s3 = peg$FAILED; @@ -3420,19 +3441,32 @@ function peg$parse(input, options) { if (s3 === peg$FAILED) { s3 = peg$currPos; s4 = peg$parse__(); - if (input.charCodeAt(peg$currPos) === 46) { - s5 = peg$c6; + if (input.charCodeAt(peg$currPos) === 91) { + s5 = peg$c4; peg$currPos++; } else { s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e16); } + if (peg$silentFails === 0) { peg$fail(peg$e10); } } if (s5 !== peg$FAILED) { s6 = peg$parse__(); - s7 = peg$parseIdentifier(); + s7 = peg$parseExpression(); if (s7 !== peg$FAILED) { - peg$savedPos = s3; - s3 = peg$f35(s1, s7); + s8 = peg$parse__(); + if (input.charCodeAt(peg$currPos) === 93) { + s9 = peg$c5; + peg$currPos++; + } else { + s9 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e11); } + } + if (s9 !== peg$FAILED) { + peg$savedPos = s3; + s3 = peg$f35(s1, s7); + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } } else { peg$currPos = s3; s3 = peg$FAILED; @@ -3446,10 +3480,23 @@ function peg$parse(input, options) { s2.push(s3); s3 = peg$currPos; s4 = peg$parse__(); - s5 = peg$parseArguments(); + if (input.charCodeAt(peg$currPos) === 46) { + s5 = peg$c6; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e16); } + } if (s5 !== peg$FAILED) { - peg$savedPos = s3; - s3 = peg$f34(s1, s5); + s6 = peg$parse__(); + s7 = peg$parseIdentifier(); + if (s7 !== peg$FAILED) { + peg$savedPos = s3; + s3 = peg$f34(s1, s7); + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } } else { peg$currPos = s3; s3 = peg$FAILED; @@ -3457,19 +3504,32 @@ function peg$parse(input, options) { if (s3 === peg$FAILED) { s3 = peg$currPos; s4 = peg$parse__(); - if (input.charCodeAt(peg$currPos) === 46) { - s5 = peg$c6; + if (input.charCodeAt(peg$currPos) === 91) { + s5 = peg$c4; peg$currPos++; } else { s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e16); } + if (peg$silentFails === 0) { peg$fail(peg$e10); } } if (s5 !== peg$FAILED) { s6 = peg$parse__(); - s7 = peg$parseIdentifier(); + s7 = peg$parseExpression(); if (s7 !== peg$FAILED) { - peg$savedPos = s3; - s3 = peg$f35(s1, s7); + s8 = peg$parse__(); + if (input.charCodeAt(peg$currPos) === 93) { + s9 = peg$c5; + peg$currPos++; + } else { + s9 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e11); } + } + if (s9 !== peg$FAILED) { + peg$savedPos = s3; + s3 = peg$f35(s1, s7); + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } } else { peg$currPos = s3; s3 = peg$FAILED; diff --git a/src/parser/ooga.pegjs b/src/parser/ooga.pegjs index 9ab43e3..dc06211 100644 --- a/src/parser/ooga.pegjs +++ b/src/parser/ooga.pegjs @@ -324,32 +324,39 @@ NewExpression CallExpression = head:( - callee:(MemberExpression/LambdaDeclaration) __ args:Arguments { // Handle function calls on member expressions + callee:(MemberExpression / LambdaDeclaration) __ args:Arguments { // Handle function calls on member expressions return { tag: "CallExpression", callee: callee, arguments: args }; } ) tail:( - // The tail part remains the same, handling further call expressions and property accesses - __ args:Arguments { - return { tag: "CallExpression", arguments: args }; - } - / __ "." __ property:Identifier { // Support for chaining dot syntax + __ "." __ property:Identifier { // Support for chaining dot syntax return { - tag: "MemberExpression", - object: head, + operation: "propertyAccess", property: property }; } + / __ "[" __ index:Expression __ "]" { // Allow for immediate index access + return { + operation: "indexAccess", + index: index + }; + } )* { return tail.reduce(function(result, element) { - // Depending on the type of element (call or member access), adjust the target of the call or property access - if (element.tag === "CallExpression") { - element.callee = result; - } else { // For member expressions - element.object = result; + if (element.operation === "propertyAccess") { + return { + tag: "MemberExpression", + object: result, + property: element.property + }; + } else if (element.operation === "indexAccess") { + return { + tag: "ArraySliceIndex", + arrayExpression: result, + index: element.index + }; } - return element; }, head); } @@ -1032,7 +1039,7 @@ ArraySliceLiteral type: { tag:'Array', elementType: {type: type}, - length: -1, + length: elements.length, is_bound: false }, elements: elements, diff --git a/src/vm/oogavm-typechecker.ts b/src/vm/oogavm-typechecker.ts index dbbdef8..4cbbbd8 100644 --- a/src/vm/oogavm-typechecker.ts +++ b/src/vm/oogavm-typechecker.ts @@ -213,6 +213,7 @@ function getType(t, struct_te): Type { return t.type; } else if (t.type.tag === 'Struct') { // Ensure that the struct is defined + log('GetType StructType:', t.type.name, struct_te); const structType = lookup_type(t.type.name, struct_te); t.type = structType; log('Exiting getType, returning StructType, ', structType); @@ -333,7 +334,7 @@ const type_comp = { // We now can set the fields of the struct. We do this now to allow for recursive struct definitions const fields = comp.fields.map( - f => new StructField(f.name.name, getType(f, struct_te)) + f => new StructField(f.name.name, getType(f, extended_struct_te)) ); // log('Fields for struct', structName); // log(fields);