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);
}
else if (c == '\n') return ParseRes.res(null, n);
else n--;
}
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);
}
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>();
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) {
this.end = loc;
return this;
@ -61,15 +57,6 @@ public class CompoundNode extends Node {
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) {
if (precedence > 1) return ParseRes.failed();

View File

@ -37,12 +37,7 @@ public abstract class FunctionNode extends Node {
body.resolve(target);
for (var param : params) {
var index = scope.define(param.name);
target.add(Instruction.loadArg(i++));
target.add(index.index().toSet(false));
}
for (var param : params) scope.define(param.name);
// if (selfName != null && !scope.has(selfName, false)) {
// var i = scope.defineSpecial(new Variable(selfName, true), end);
@ -52,6 +47,12 @@ public abstract class FunctionNode extends Node {
// }
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);
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) {
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());
}

View File

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

View File

@ -32,7 +32,7 @@ public class VariableDeclareNode extends Node {
for (var entry : values) {
if (entry.value != null) {
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);
if (!bodyRes.isSuccess()) return bodyRes.chainError(src.loc(i + n), "Expected a do-while body.");
n += bodyRes.n;
n += Parsing.skipEmpty(src, i + n);
if (!Parsing.isIdentifier(src, i + n, "while")) return ParseRes.failed();
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.Source;
import me.topchetoeu.jscript.compilation.CompileResult;
import me.topchetoeu.jscript.compilation.CompoundNode;
import me.topchetoeu.jscript.compilation.JavaScript;
import me.topchetoeu.jscript.compilation.LabelContext;
import me.topchetoeu.jscript.compilation.DeferredIntSupplier;
@ -38,14 +37,14 @@ public class ForInNode extends Node {
int mid = target.temp();
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);
var end = new DeferredIntSupplier();
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();

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.Source;
import me.topchetoeu.jscript.compilation.CompileResult;
import me.topchetoeu.jscript.compilation.CompoundNode;
import me.topchetoeu.jscript.compilation.DeferredIntSupplier;
import me.topchetoeu.jscript.compilation.JavaScript;
import me.topchetoeu.jscript.compilation.LabelContext;
@ -24,31 +23,34 @@ public class ForNode extends Node {
body.resolve(target);
}
@Override public void compileFunctions(CompileResult target) {
declaration.compileFunctions(target);
assignment.compileFunctions(target);
condition.compileFunctions(target);
if (declaration != null) declaration.compileFunctions(target);
if (assignment != null) assignment.compileFunctions(target);
if (condition != null) condition.compileFunctions(target);
body.compileFunctions(target);
}
@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();
CompoundNode.compileMultiEntry(condition, target, true, BreakpointType.STEP_OVER);
int mid = target.temp();
int mid = -1;
if (condition != null) {
condition.compile(target, true, BreakpointType.STEP_OVER);
mid = target.temp();
}
var end = new DeferredIntSupplier();
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();
end.set(endI);
LabelContext.popLoop(target.env, label);
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());
}

View File

@ -23,7 +23,7 @@ public class IfNode extends Node {
@Override public void compileFunctions(CompileResult target) {
condition.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) {
condition.compile(target, true, breakpoint);
@ -33,7 +33,7 @@ public class IfNode extends Node {
var end = new DeferredIntSupplier();
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);
int endI = target.size();
@ -46,11 +46,11 @@ public class IfNode extends Node {
var end = new DeferredIntSupplier();
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();
elseBody.compile(target, false, BreakpointType.STEP_OVER);
elseBody.compile(target, pollute, BreakpointType.STEP_OVER);
LabelContext.getBreak(target.env).pop(label);
int endI = target.size();

View File

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

View File

@ -46,8 +46,8 @@ public class TryNode extends Node {
if (captureName != null) {
var catchVar = target.scope.defineCatch(captureName);
target.add(Instruction.loadError());
target.add(catchVar.index().toSet(false));
target.add(Instruction.loadError()).setLocation(catchBody.loc());
target.add(catchVar.index().toSet(false)).setLocation(catchBody.loc());
catchBody.compile(target, false);
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.Source;
import me.topchetoeu.jscript.compilation.CompileResult;
import me.topchetoeu.jscript.compilation.CompoundNode;
import me.topchetoeu.jscript.compilation.DeferredIntSupplier;
import me.topchetoeu.jscript.compilation.JavaScript;
import me.topchetoeu.jscript.compilation.LabelContext;
@ -33,7 +32,7 @@ public class WhileNode extends Node {
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();
end.set(endI + 1);

View File

@ -42,13 +42,6 @@ public final class PropertyMemberNode extends FunctionNode implements Member {
key.compile(target, true);
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()));
}

View File

@ -16,7 +16,9 @@ public class ArrayNode extends Node {
public final Node[] statements;
@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) {

View File

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

View File

@ -23,7 +23,7 @@ public class VariableNode extends Node implements ChangeTarget {
}
@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) {

View File

@ -14,7 +14,7 @@ public class DiscardNode extends Node {
public final Node value;
@Override public void compileFunctions(CompileResult target) {
value.compileFunctions(target);
if (value != null) value.compileFunctions(target);
}
@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));
FunctionNode.compileWithName(value, target, true, name);
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 {
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());
}
}