diff --git a/src/main/java/me/topchetoeu/jscript/compilation/members/FieldMemberNode.java b/src/main/java/me/topchetoeu/jscript/compilation/members/FieldMemberNode.java index 53edbf3..7888d94 100644 --- a/src/main/java/me/topchetoeu/jscript/compilation/members/FieldMemberNode.java +++ b/src/main/java/me/topchetoeu/jscript/compilation/members/FieldMemberNode.java @@ -9,8 +9,6 @@ import me.topchetoeu.jscript.compilation.CompileResult; import me.topchetoeu.jscript.compilation.JavaScript; import me.topchetoeu.jscript.compilation.Node; import me.topchetoeu.jscript.compilation.values.ObjectNode; -import me.topchetoeu.jscript.compilation.values.VariableNode; -import me.topchetoeu.jscript.compilation.values.constants.StringNode; public class FieldMemberNode implements Member { public final Location loc; @@ -19,14 +17,14 @@ public class FieldMemberNode implements Member { @Override public Location loc() { return loc; } - @Override public void compile(CompileResult target, boolean pollute, boolean enumerable) { + @Override public void compile(CompileResult target, boolean pollute) { if (pollute) target.add(Instruction.dup()); key.compile(target, true); if (value == null) target.add(Instruction.pushUndefined()); else value.compile(target, true); - target.add(Instruction.defField(enumerable)); + target.add(Instruction.defField()); } public FieldMemberNode(Location loc, Node key, Node value) { @@ -35,7 +33,7 @@ public class FieldMemberNode implements Member { this.value = value; } - public static ParseRes parseObject(Source src, int i) { + public static ParseRes parse(Source src, int i) { var n = Parsing.skipEmpty(src, i); var loc = src.loc(i + n); @@ -53,40 +51,4 @@ public class FieldMemberNode implements Member { return ParseRes.res(new FieldMemberNode(loc, name.result, value.result), n); } - - public static ParseRes parseShorthand(Source src, int i) { - var n = Parsing.skipEmpty(src, i); - var loc = src.loc(i + n); - - var var = VariableNode.parse(src, i + n); - if (!var.isSuccess()) return var.chainError(); - n += var.n; - - return ParseRes.res(new FieldMemberNode(loc, new StringNode(loc, var.result.name), var.result), n); - } - - public static ParseRes parseClass(Source src, int i) { - var n = Parsing.skipEmpty(src, i); - var loc = src.loc(i + n); - - var name = ObjectNode.parsePropName(src, i + n); - if (!name.isSuccess()) return name.chainError(); - n += name.n; - n += Parsing.skipEmpty(src, i + n); - - if (!src.is(i + n, "=")) { - var end = JavaScript.parseStatementEnd(src, i + n); - if (!end.isSuccess()) return ParseRes.error(src.loc(i + n), "Expected an end of statement or a field initializer"); - n += end.n; - - return ParseRes.res(new FieldMemberNode(loc, name.result, null), n); - } - n++; - - var value = JavaScript.parseExpression(src, i + n, 2); - if (!value.isSuccess()) return value.chainError(src.loc(i + n), "Expected a value"); - n += value.n; - - return ParseRes.res(new FieldMemberNode(loc, name.result, value.result), n); - } } \ No newline at end of file diff --git a/src/main/java/me/topchetoeu/jscript/compilation/members/Member.java b/src/main/java/me/topchetoeu/jscript/compilation/members/Member.java index 505071a..8f48859 100644 --- a/src/main/java/me/topchetoeu/jscript/compilation/members/Member.java +++ b/src/main/java/me/topchetoeu/jscript/compilation/members/Member.java @@ -6,5 +6,5 @@ import me.topchetoeu.jscript.compilation.CompileResult; public interface Member { Location loc(); - void compile(CompileResult target, boolean pollute, boolean enumerable); + void compile(CompileResult target, boolean pollute); } diff --git a/src/main/java/me/topchetoeu/jscript/compilation/members/PropertyMemberNode.java b/src/main/java/me/topchetoeu/jscript/compilation/members/PropertyMemberNode.java index 8290f73..8e0dcce 100644 --- a/src/main/java/me/topchetoeu/jscript/compilation/members/PropertyMemberNode.java +++ b/src/main/java/me/topchetoeu/jscript/compilation/members/PropertyMemberNode.java @@ -4,7 +4,6 @@ import java.util.Arrays; import me.topchetoeu.jscript.common.Instruction; import me.topchetoeu.jscript.common.Instruction.BreakpointType; -import me.topchetoeu.jscript.common.environment.Environment; import me.topchetoeu.jscript.common.parsing.Location; import me.topchetoeu.jscript.common.parsing.ParseRes; import me.topchetoeu.jscript.common.parsing.Parsing; @@ -12,15 +11,15 @@ import me.topchetoeu.jscript.common.parsing.Source; import me.topchetoeu.jscript.compilation.CompileResult; import me.topchetoeu.jscript.compilation.CompoundNode; import me.topchetoeu.jscript.compilation.FunctionNode; +import me.topchetoeu.jscript.compilation.JavaScript; import me.topchetoeu.jscript.compilation.Node; -import me.topchetoeu.jscript.compilation.Parameters; -import me.topchetoeu.jscript.compilation.patterns.Pattern; import me.topchetoeu.jscript.compilation.values.ObjectNode; +import me.topchetoeu.jscript.compilation.values.VariableNode; import me.topchetoeu.jscript.compilation.values.constants.StringNode; -public class PropertyMemberNode extends FunctionNode implements Member{ +public final class PropertyMemberNode extends FunctionNode implements Member { public final Node key; - public final Pattern argument; + public final VariableNode argument; @Override public String name() { if (key instanceof StringNode str) { @@ -30,10 +29,6 @@ public class PropertyMemberNode extends FunctionNode implements Member{ else return null; } - @Override protected Environment rootEnv(Environment env) { - return env; - } - public boolean isGetter() { return argument == null; } public boolean isSetter() { return argument != null; } @@ -42,17 +37,17 @@ public class PropertyMemberNode extends FunctionNode implements Member{ key.compile(target, true); var id = target.addChild(compileBody(target, name, null)); - target.add(_i -> Instruction.loadFunc(id, true, false, false, false, null, captures(id, target))); + target.add(Instruction.loadFunc(id, name(), captures(id, target))); } - @Override public void compile(CompileResult target, boolean pollute, boolean enumerable) { - compile(target, pollute); - target.add(Instruction.defProp(isSetter(), enumerable)); + @Override public void compile(CompileResult target, boolean pollute) { + super.compile(target, pollute); + target.add(Instruction.defProp(isSetter())); } - public PropertyMemberNode(Location loc, Location end, Node key, Pattern argument, CompoundNode body) { - super(loc, end, argument == null ? new Parameters(Arrays.asList()) : new Parameters(Arrays.asList(argument)), body); + public PropertyMemberNode(Location loc, Location end, Node key, VariableNode argument, CompoundNode body) { + super(loc, end, argument == null ? Arrays.asList() : Arrays.asList(argument), body); this.key = key; this.argument = argument; } @@ -70,11 +65,10 @@ public class PropertyMemberNode extends FunctionNode implements Member{ if (!name.isSuccess()) return name.chainError(src.loc(i + n), "Expected a property name after '" + access + "'"); n += name.n; - var params = Parameters.parseParameters(src, i + n); + var params = JavaScript.parseParameters(src, i + n); if (!params.isSuccess()) return params.chainError(src.loc(i + n), "Expected an argument list"); - if (access.result.equals("get") && params.result.params.size() != 0) return ParseRes.error(src.loc(i + n), "Getter must not have any parameters"); - if (access.result.equals("set") && params.result.params.size() != 1) return ParseRes.error(src.loc(i + n), "Setter must have exactly one parameter"); - if (params.result.rest != null) return ParseRes.error(params.result.rest.loc(), "Property members may not have rest arguments"); + if (access.result.equals("get") && params.result.size() != 0) return ParseRes.error(src.loc(i + n), "Getter must not have any parameters"); + if (access.result.equals("set") && params.result.size() != 1) return ParseRes.error(src.loc(i + n), "Setter must have exactly one parameter"); n += params.n; var body = CompoundNode.parse(src, i + n); @@ -84,7 +78,7 @@ public class PropertyMemberNode extends FunctionNode implements Member{ var end = src.loc(i + n - 1); return ParseRes.res(new PropertyMemberNode( - loc, end, name.result, access.result.equals("get") ? null : params.result.params.get(0), body.result + loc, end, name.result, access.result.equals("get") ? null : params.result.get(0), body.result ), n); } } \ No newline at end of file diff --git a/src/main/java/me/topchetoeu/jscript/compilation/values/ObjectNode.java b/src/main/java/me/topchetoeu/jscript/compilation/values/ObjectNode.java index b694117..8785416 100644 --- a/src/main/java/me/topchetoeu/jscript/compilation/values/ObjectNode.java +++ b/src/main/java/me/topchetoeu/jscript/compilation/values/ObjectNode.java @@ -4,7 +4,6 @@ import java.util.LinkedList; import java.util.List; import me.topchetoeu.jscript.common.Instruction; -import me.topchetoeu.jscript.common.SyntaxException; import me.topchetoeu.jscript.common.parsing.Location; import me.topchetoeu.jscript.common.parsing.ParseRes; import me.topchetoeu.jscript.common.parsing.Parsing; @@ -12,75 +11,18 @@ import me.topchetoeu.jscript.common.parsing.Source; import me.topchetoeu.jscript.compilation.CompileResult; import me.topchetoeu.jscript.compilation.JavaScript; import me.topchetoeu.jscript.compilation.Node; -import me.topchetoeu.jscript.compilation.members.AssignShorthandNode; import me.topchetoeu.jscript.compilation.members.FieldMemberNode; import me.topchetoeu.jscript.compilation.members.Member; -import me.topchetoeu.jscript.compilation.members.MethodMemberNode; import me.topchetoeu.jscript.compilation.members.PropertyMemberNode; -import me.topchetoeu.jscript.compilation.patterns.AssignTarget; -import me.topchetoeu.jscript.compilation.patterns.AssignTargetLike; -import me.topchetoeu.jscript.compilation.patterns.ObjectPattern; import me.topchetoeu.jscript.compilation.values.constants.NumberNode; import me.topchetoeu.jscript.compilation.values.constants.StringNode; -public class ObjectNode extends Node implements AssignTargetLike { +public class ObjectNode extends Node { public final List members; - // TODO: Implement spreading into object - - // private void compileRestObjBuilder(CompileResult target, int srcDupN) { - // var subtarget = target.subtarget(); - // var src = subtarget.scope.defineTemp(); - // var dst = subtarget.scope.defineTemp(); - - // target.add(Instruction.loadObj()); - // target.add(_i -> src.index().toSet(true)); - // target.add(_i -> dst.index().toSet(destructors.size() > 0)); - - // target.add(Instruction.keys(true, true)); - // var start = target.size(); - - // target.add(Instruction.dup()); - // var mid = target.temp(); - - // target.add(_i -> src.index().toGet()); - // target.add(Instruction.dup(1, 1)); - // target.add(Instruction.loadMember()); - - // target.add(_i -> dst.index().toGet()); - // target.add(Instruction.dup(1, 1)); - // target.add(Instruction.storeMember()); - - // target.add(Instruction.discard()); - // var end = target.size(); - // target.add(Instruction.jmp(start - end)); - // target.set(mid, Instruction.jmpIfNot(end - mid + 1)); - - // target.add(Instruction.discard()); - - // target.add(Instruction.dup(srcDupN, 1)); - - // target.scope.end(); - // } - @Override public void compile(CompileResult target, boolean pollute) { target.add(Instruction.loadObj()); - for (var el : members) el.compile(target, true, true); - } - - @Override public AssignTarget toAssignTarget() { - var newMembers = new LinkedList(); - - for (var el : members) { - if (el instanceof FieldMemberNode field) { - if (field.value instanceof AssignTargetLike target) newMembers.add(new ObjectPattern.Member(field.key, target.toAssignTarget())); - else throw new SyntaxException(field.value.loc(), "Expected an assignable in deconstructor"); - } - else if (el instanceof AssignShorthandNode shorthand) newMembers.add(new ObjectPattern.Member(shorthand.key, shorthand.target())); - else throw new SyntaxException(el.loc(), "Unexpected member in deconstructor"); - } - - return new ObjectPattern(loc(), newMembers); + for (var el : members) el.compile(target, true); } public ObjectNode(Location loc, List map) { @@ -136,11 +78,8 @@ public class ObjectNode extends Node implements AssignTargetLike { while (true) { ParseRes prop = ParseRes.first(src, i + n, - MethodMemberNode::parse, PropertyMemberNode::parse, - FieldMemberNode::parseObject, - AssignShorthandNode::parse, - FieldMemberNode::parseShorthand + FieldMemberNode::parse ); if (!prop.isSuccess()) return prop.chainError(src.loc(i + n), "Expected a member in object literal"); n += prop.n;