small parser fixes

This commit is contained in:
TopchetoEU 2024-12-09 23:37:08 +02:00
parent 54d55814af
commit 2e8e123ec4
Signed by: topchetoeu
GPG Key ID: 6531B8583E5F6ED4
19 changed files with 73 additions and 80 deletions

View File

@ -113,6 +113,7 @@ public class Parsing {
return ParseRes.res((char)newC, n); return ParseRes.res((char)newC, n);
} }
else if (c == '\n') return ParseRes.res(null, n); else if (c == '\n') return ParseRes.res(null, n);
else n--;
} }
return ParseRes.res(src.at(i + n), n + 1); return ParseRes.res(src.at(i + n), n + 1);

View File

@ -23,7 +23,7 @@ public class CompoundNode extends Node {
for (var stm : statements) stm.compileFunctions(target); for (var stm : statements) stm.compileFunctions(target);
} }
public void compile(CompileResult target, boolean pollute, boolean singleEntry, BreakpointType type) { public void compile(CompileResult target, boolean pollute, BreakpointType type) {
List<Node> statements = new ArrayList<Node>(); List<Node> statements = new ArrayList<Node>();
for (var stm : this.statements) { for (var stm : this.statements) {
@ -47,10 +47,6 @@ public class CompoundNode extends Node {
} }
} }
@Override public void compile(CompileResult target, boolean pollute, BreakpointType type) {
compile(target, pollute, true, type);
}
public CompoundNode setEnd(Location loc) { public CompoundNode setEnd(Location loc) {
this.end = loc; this.end = loc;
return this; return this;
@ -61,15 +57,6 @@ public class CompoundNode extends Node {
this.statements = statements; this.statements = statements;
} }
public static void compileMultiEntry(Node node, CompileResult target, boolean pollute, BreakpointType type) {
if (node instanceof CompoundNode comp) {
comp.compile(target, pollute, false, type);
}
else {
node.compile(target, pollute, type);
}
}
public static ParseRes<CompoundNode> parseComma(Source src, int i, Node prev, int precedence) { public static ParseRes<CompoundNode> parseComma(Source src, int i, Node prev, int precedence) {
if (precedence > 1) return ParseRes.failed(); if (precedence > 1) return ParseRes.failed();

View File

@ -37,12 +37,7 @@ public abstract class FunctionNode extends Node {
body.resolve(target); body.resolve(target);
for (var param : params) { for (var param : params) scope.define(param.name);
var index = scope.define(param.name);
target.add(Instruction.loadArg(i++));
target.add(index.index().toSet(false));
}
// if (selfName != null && !scope.has(selfName, false)) { // if (selfName != null && !scope.has(selfName, false)) {
// var i = scope.defineSpecial(new Variable(selfName, true), end); // var i = scope.defineSpecial(new Variable(selfName, true), end);
@ -52,6 +47,12 @@ public abstract class FunctionNode extends Node {
// } // }
body.compileFunctions(target); body.compileFunctions(target);
for (var param : params) {
target.add(Instruction.loadArg(i++)).setLocation(param.loc());
target.add(scope.define(param.name).index().toSet(false)).setLocation(param.loc());
}
body.compile(target, lastReturn, BreakpointType.NONE); body.compile(target, lastReturn, BreakpointType.NONE);
return target; return target;

View File

@ -22,7 +22,7 @@ public class FunctionStatementNode extends FunctionNode {
@Override public void compile(CompileResult target, boolean pollute, String name, BreakpointType bp) { @Override public void compile(CompileResult target, boolean pollute, String name, BreakpointType bp) {
target.add(Instruction.loadFunc(target.childrenIndices.get(this), name(name), captures(target))).setLocation(loc()); target.add(Instruction.loadFunc(target.childrenIndices.get(this), name(name), captures(target))).setLocation(loc());
target.add(VariableNode.toSet(target, end, this.name, false, true)); target.add(VariableNode.toSet(target, end, this.name, false, true)).setLocation(loc());
if (pollute) target.add(Instruction.pushUndefined()); if (pollute) target.add(Instruction.pushUndefined());
} }

View File

@ -193,8 +193,8 @@ public final class JavaScript {
IfNode::parse, IfNode::parse,
WhileNode::parse, WhileNode::parse,
SwitchNode::parse, SwitchNode::parse,
ForInNode::parse,
ForNode::parse, ForNode::parse,
ForInNode::parse,
DoWhileNode::parse, DoWhileNode::parse,
TryNode::parse, TryNode::parse,
CompoundNode::parse, CompoundNode::parse,

View File

@ -32,7 +32,7 @@ public class VariableDeclareNode extends Node {
for (var entry : values) { for (var entry : values) {
if (entry.value != null) { if (entry.value != null) {
entry.value.compile(target, true); entry.value.compile(target, true);
target.add(VariableNode.toSet(target, loc(), entry.var.name, false, true)); target.add(VariableNode.toSet(target, loc(), entry.var.name, false, true)).setLocation(loc());
} }
} }

View File

@ -62,6 +62,7 @@ public class DoWhileNode extends Node {
var bodyRes = JavaScript.parseStatement(src, i + n); var bodyRes = JavaScript.parseStatement(src, i + n);
if (!bodyRes.isSuccess()) return bodyRes.chainError(src.loc(i + n), "Expected a do-while body."); if (!bodyRes.isSuccess()) return bodyRes.chainError(src.loc(i + n), "Expected a do-while body.");
n += bodyRes.n; n += bodyRes.n;
n += Parsing.skipEmpty(src, i + n);
if (!Parsing.isIdentifier(src, i + n, "while")) return ParseRes.failed(); if (!Parsing.isIdentifier(src, i + n, "while")) return ParseRes.failed();
n += 5; n += 5;

View File

@ -7,7 +7,6 @@ import me.topchetoeu.jscript.common.parsing.ParseRes;
import me.topchetoeu.jscript.common.parsing.Parsing; import me.topchetoeu.jscript.common.parsing.Parsing;
import me.topchetoeu.jscript.common.parsing.Source; import me.topchetoeu.jscript.common.parsing.Source;
import me.topchetoeu.jscript.compilation.CompileResult; import me.topchetoeu.jscript.compilation.CompileResult;
import me.topchetoeu.jscript.compilation.CompoundNode;
import me.topchetoeu.jscript.compilation.JavaScript; import me.topchetoeu.jscript.compilation.JavaScript;
import me.topchetoeu.jscript.compilation.LabelContext; import me.topchetoeu.jscript.compilation.LabelContext;
import me.topchetoeu.jscript.compilation.DeferredIntSupplier; import me.topchetoeu.jscript.compilation.DeferredIntSupplier;
@ -38,14 +37,14 @@ public class ForInNode extends Node {
int mid = target.temp(); int mid = target.temp();
target.add(Instruction.loadMember("value")).setLocation(binding.loc()); target.add(Instruction.loadMember("value")).setLocation(binding.loc());
target.add(VariableNode.toSet(target, loc(), binding.name, false, true)); target.add(VariableNode.toSet(target, loc(), binding.name, false, true)).setLocation(binding.loc());
target.setLocationAndDebug(object.loc(), BreakpointType.STEP_OVER); target.setLocationAndDebug(object.loc(), BreakpointType.STEP_OVER);
var end = new DeferredIntSupplier(); var end = new DeferredIntSupplier();
LabelContext.pushLoop(target.env, loc(), label, end, start); LabelContext.pushLoop(target.env, loc(), label, end, start);
CompoundNode.compileMultiEntry(body, target, false, BreakpointType.STEP_OVER); body.compile(target, false, BreakpointType.STEP_OVER);
int endI = target.size(); int endI = target.size();

View File

@ -7,7 +7,6 @@ import me.topchetoeu.jscript.common.parsing.ParseRes;
import me.topchetoeu.jscript.common.parsing.Parsing; import me.topchetoeu.jscript.common.parsing.Parsing;
import me.topchetoeu.jscript.common.parsing.Source; import me.topchetoeu.jscript.common.parsing.Source;
import me.topchetoeu.jscript.compilation.CompileResult; import me.topchetoeu.jscript.compilation.CompileResult;
import me.topchetoeu.jscript.compilation.CompoundNode;
import me.topchetoeu.jscript.compilation.DeferredIntSupplier; import me.topchetoeu.jscript.compilation.DeferredIntSupplier;
import me.topchetoeu.jscript.compilation.JavaScript; import me.topchetoeu.jscript.compilation.JavaScript;
import me.topchetoeu.jscript.compilation.LabelContext; import me.topchetoeu.jscript.compilation.LabelContext;
@ -24,31 +23,34 @@ public class ForNode extends Node {
body.resolve(target); body.resolve(target);
} }
@Override public void compileFunctions(CompileResult target) { @Override public void compileFunctions(CompileResult target) {
declaration.compileFunctions(target); if (declaration != null) declaration.compileFunctions(target);
assignment.compileFunctions(target); if (assignment != null) assignment.compileFunctions(target);
condition.compileFunctions(target); if (condition != null) condition.compileFunctions(target);
body.compileFunctions(target); body.compileFunctions(target);
} }
@Override public void compile(CompileResult target, boolean pollute) { @Override public void compile(CompileResult target, boolean pollute) {
declaration.compile(target, false, BreakpointType.STEP_OVER); if (declaration != null) declaration.compile(target, false, BreakpointType.STEP_OVER);
int start = target.size(); int start = target.size();
CompoundNode.compileMultiEntry(condition, target, true, BreakpointType.STEP_OVER); int mid = -1;
int mid = target.temp(); if (condition != null) {
condition.compile(target, true, BreakpointType.STEP_OVER);
mid = target.temp();
}
var end = new DeferredIntSupplier(); var end = new DeferredIntSupplier();
LabelContext.pushLoop(target.env, loc(), label, end, start); LabelContext.pushLoop(target.env, loc(), label, end, start);
CompoundNode.compileMultiEntry(body, target, false, BreakpointType.STEP_OVER); body.compile(target, false, BreakpointType.STEP_OVER);
CompoundNode.compileMultiEntry(assignment, target, false, BreakpointType.STEP_OVER); if (assignment != null) assignment.compile(target, false, BreakpointType.STEP_OVER);
int endI = target.size(); int endI = target.size();
end.set(endI); end.set(endI);
LabelContext.popLoop(target.env, label); LabelContext.popLoop(target.env, label);
target.add(Instruction.jmp(start - endI)); target.add(Instruction.jmp(start - endI));
target.set(mid, Instruction.jmpIfNot(endI - mid + 1)); if (mid >= 0) target.set(mid, Instruction.jmpIfNot(endI - mid + 1));
if (pollute) target.add(Instruction.pushUndefined()); if (pollute) target.add(Instruction.pushUndefined());
} }

View File

@ -23,7 +23,7 @@ public class IfNode extends Node {
@Override public void compileFunctions(CompileResult target) { @Override public void compileFunctions(CompileResult target) {
condition.compileFunctions(target); condition.compileFunctions(target);
body.compileFunctions(target); body.compileFunctions(target);
if (elseBody != null) body.compileFunctions(target); if (elseBody != null) elseBody.compileFunctions(target);
} }
@Override public void compile(CompileResult target, boolean pollute, BreakpointType breakpoint) { @Override public void compile(CompileResult target, boolean pollute, BreakpointType breakpoint) {
condition.compile(target, true, breakpoint); condition.compile(target, true, breakpoint);
@ -33,7 +33,7 @@ public class IfNode extends Node {
var end = new DeferredIntSupplier(); var end = new DeferredIntSupplier();
LabelContext.getBreak(target.env).push(loc(), label, end); LabelContext.getBreak(target.env).push(loc(), label, end);
body.compile(target, false, BreakpointType.STEP_OVER); body.compile(target, pollute, BreakpointType.STEP_OVER);
LabelContext.getBreak(target.env).pop(label); LabelContext.getBreak(target.env).pop(label);
int endI = target.size(); int endI = target.size();
@ -46,11 +46,11 @@ public class IfNode extends Node {
var end = new DeferredIntSupplier(); var end = new DeferredIntSupplier();
LabelContext.getBreak(target.env).push(loc(), label, end); LabelContext.getBreak(target.env).push(loc(), label, end);
body.compile(target, false, BreakpointType.STEP_OVER); body.compile(target, pollute, BreakpointType.STEP_OVER);
int mid = target.temp(); int mid = target.temp();
elseBody.compile(target, false, BreakpointType.STEP_OVER); elseBody.compile(target, pollute, BreakpointType.STEP_OVER);
LabelContext.getBreak(target.env).pop(label); LabelContext.getBreak(target.env).pop(label);
int endI = target.size(); int endI = target.size();

View File

@ -62,7 +62,7 @@ public class SwitchNode extends Node {
int start = target.temp(); int start = target.temp();
var end = new DeferredIntSupplier(); var end = new DeferredIntSupplier();
LabelContext.getBreak(target.env).push(loc(), label, end); LabelContext.getBreak(target.env).pushLoop(loc(), label, end);
for (var stm : body) { for (var stm : body) {
statementToIndex.put(statementToIndex.size(), target.size()); statementToIndex.put(statementToIndex.size(), target.size());
stm.compile(target, false, BreakpointType.STEP_OVER); stm.compile(target, false, BreakpointType.STEP_OVER);
@ -70,7 +70,7 @@ public class SwitchNode extends Node {
int endI = target.size(); int endI = target.size();
end.set(endI); end.set(endI);
LabelContext.getBreak(target.env).pop(label); LabelContext.getBreak(target.env).popLoop(label);
target.add(Instruction.discard()); target.add(Instruction.discard());
if (pollute) target.add(Instruction.pushUndefined()); if (pollute) target.add(Instruction.pushUndefined());
@ -104,6 +104,7 @@ public class SwitchNode extends Node {
var val = JavaScript.parseExpression(src, i + n, 0); var val = JavaScript.parseExpression(src, i + n, 0);
if (!val.isSuccess()) return val.chainError(src.loc(i + n), "Expected a value after 'case'"); if (!val.isSuccess()) return val.chainError(src.loc(i + n), "Expected a value after 'case'");
n += val.n; n += val.n;
n += Parsing.skipEmpty(src, i + n);
if (!src.is(i + n, ":")) return ParseRes.error(src.loc(i + n), "Expected colons after 'case' value"); if (!src.is(i + n, ":")) return ParseRes.error(src.loc(i + n), "Expected colons after 'case' value");
n++; n++;

View File

@ -46,8 +46,8 @@ public class TryNode extends Node {
if (captureName != null) { if (captureName != null) {
var catchVar = target.scope.defineCatch(captureName); var catchVar = target.scope.defineCatch(captureName);
target.add(Instruction.loadError()); target.add(Instruction.loadError()).setLocation(catchBody.loc());
target.add(catchVar.index().toSet(false)); target.add(catchVar.index().toSet(false)).setLocation(catchBody.loc());
catchBody.compile(target, false); catchBody.compile(target, false);
target.scope.undefineCatch(); target.scope.undefineCatch();
} }

View File

@ -7,7 +7,6 @@ import me.topchetoeu.jscript.common.parsing.ParseRes;
import me.topchetoeu.jscript.common.parsing.Parsing; import me.topchetoeu.jscript.common.parsing.Parsing;
import me.topchetoeu.jscript.common.parsing.Source; import me.topchetoeu.jscript.common.parsing.Source;
import me.topchetoeu.jscript.compilation.CompileResult; import me.topchetoeu.jscript.compilation.CompileResult;
import me.topchetoeu.jscript.compilation.CompoundNode;
import me.topchetoeu.jscript.compilation.DeferredIntSupplier; import me.topchetoeu.jscript.compilation.DeferredIntSupplier;
import me.topchetoeu.jscript.compilation.JavaScript; import me.topchetoeu.jscript.compilation.JavaScript;
import me.topchetoeu.jscript.compilation.LabelContext; import me.topchetoeu.jscript.compilation.LabelContext;
@ -33,7 +32,7 @@ public class WhileNode extends Node {
LabelContext.pushLoop(target.env, loc(), label, end, start); LabelContext.pushLoop(target.env, loc(), label, end, start);
CompoundNode.compileMultiEntry(body, target, false, BreakpointType.STEP_OVER); body.compile(target, false, BreakpointType.STEP_OVER);
var endI = target.size(); var endI = target.size();
end.set(endI + 1); end.set(endI + 1);

View File

@ -42,13 +42,6 @@ public final class PropertyMemberNode extends FunctionNode implements Member {
key.compile(target, true); key.compile(target, true);
target.add(Instruction.loadFunc(target.childrenIndices.get(this), name(name), captures(target))).setLocation(loc()); target.add(Instruction.loadFunc(target.childrenIndices.get(this), name(name), captures(target))).setLocation(loc());
target.add(VariableNode.toSet(target, end, name(name), false, true));
target.add(Instruction.defProp(isSetter()));
}
@Override public void compile(CompileResult target, boolean pollute) {
super.compile(target, pollute);
target.add(Instruction.defProp(isSetter())); target.add(Instruction.defProp(isSetter()));
} }

View File

@ -16,7 +16,9 @@ public class ArrayNode extends Node {
public final Node[] statements; public final Node[] statements;
@Override public void compileFunctions(CompileResult target) { @Override public void compileFunctions(CompileResult target) {
for (var stm : statements) stm.compileFunctions(target); for (var stm : statements) {
if (stm != null) stm.compileFunctions(target);
}
} }
@Override public void compile(CompileResult target, boolean pollute) { @Override public void compile(CompileResult target, boolean pollute) {

View File

@ -31,28 +31,35 @@ public class RegexNode extends Node {
var inBrackets = false; var inBrackets = false;
while (true) { loop: while (true) {
if (src.is(i + n, '[')) { switch (src.at(i + n)) {
n++; case '[':
inBrackets = true; inBrackets = true;
source.append(src.at(i + n)); source.append('[');
continue; n++;
} continue;
else if (src.is(i + n, ']')) { case ']':
n++; inBrackets = false;
inBrackets = false; source.append(']');
source.append(src.at(i + n)); n++;
continue; continue;
} case '/':
else if (src.is(i + n, '/') && !inBrackets) { n++;
n++; if (inBrackets) {
break; source.append('/');
} continue;
}
var charRes = Parsing.parseChar(src, i + n); else break loop;
if (charRes.result == null) return ParseRes.error(src.loc(i + n), "Multiline regular expressions are not allowed"); case '\\':
source.append(charRes.result); source.append('\\');
n++; source.append(src.at(i + n + 1));
n += 2;
break;
default:
source.append(src.at(i + n));
n++;
break;
}
} }
while (true) { while (true) {

View File

@ -23,7 +23,7 @@ public class VariableNode extends Node implements ChangeTarget {
} }
@Override public void afterAssign(CompileResult target, boolean pollute) { @Override public void afterAssign(CompileResult target, boolean pollute) {
target.add(VariableNode.toSet(target, loc(), name, pollute, false)); target.add(VariableNode.toSet(target, loc(), name, pollute, false)).setLocation(loc());
} }
@Override public void compile(CompileResult target, boolean pollute) { @Override public void compile(CompileResult target, boolean pollute) {

View File

@ -14,7 +14,7 @@ public class DiscardNode extends Node {
public final Node value; public final Node value;
@Override public void compileFunctions(CompileResult target) { @Override public void compileFunctions(CompileResult target) {
value.compileFunctions(target); if (value != null) value.compileFunctions(target);
} }
@Override public void compile(CompileResult target, boolean pollute) { @Override public void compile(CompileResult target, boolean pollute) {

View File

@ -22,11 +22,11 @@ public class VariableAssignNode extends Node {
target.add(VariableNode.toGet(target, loc(), name)); target.add(VariableNode.toGet(target, loc(), name));
FunctionNode.compileWithName(value, target, true, name); FunctionNode.compileWithName(value, target, true, name);
target.add(Instruction.operation(operation)); target.add(Instruction.operation(operation));
target.add(VariableNode.toSet(target, loc(), name, pollute, false)); target.add(VariableNode.toSet(target, loc(), name, pollute, false)).setLocation(loc());
} }
else { else {
FunctionNode.compileWithName(value, target, true, name); FunctionNode.compileWithName(value, target, true, name);
target.add(VariableNode.toSet(target, loc(), name, pollute, false)); target.add(VariableNode.toSet(target, loc(), name, pollute, false)).setLocation(loc());
} }
} }