Remove some unnecessary nesting in the parser

This commit is contained in:
0x4261756D 2024-02-28 19:13:17 +01:00
parent 51390b24d3
commit 820fc7a82e

167
Parser.cs
View File

@ -38,9 +38,11 @@ internal class Parser
{ {
public CodeRegion region = region; public CodeRegion region = region;
} }
public class Assignment(AssignmentNode node) : StatNode public class Assignment(VarlistNode lhs, ExplistNode rhs, CodeRegion startRegion, CodeRegion endRegion) : StatNode
{ {
public AssignmentNode node = node; public VarlistNode lhs = lhs;
public ExplistNode rhs = rhs;
public CodeRegion startRegion = startRegion, endRegion = endRegion;
} }
public class Functioncall(FunctioncallNode node) : StatNode public class Functioncall(FunctioncallNode node) : StatNode
{ {
@ -68,41 +70,57 @@ internal class Parser
public CodeRegion endRegion = endRegion; public CodeRegion endRegion = endRegion;
public BlockNode node = node; public BlockNode node = node;
} }
public class While(WhileNode node) : StatNode public class While(ExpNode condition, BlockNode body, CodeRegion startRegion, CodeRegion endRegion) : StatNode
{ {
public WhileNode node = node; public ExpNode condition = condition;
public BlockNode body = body;
public CodeRegion startRegion = startRegion, endRegion = endRegion;
} }
public class Repeat(RepeatNode node) : StatNode public class Repeat(ExpNode condition, BlockNode body, CodeRegion startRegion, CodeRegion endRegion) : StatNode
{ {
public RepeatNode node = node; public ExpNode condition = condition;
public BlockNode body = body;
public CodeRegion startRegion = startRegion, endRegion = endRegion;
} }
public class If(IfNode node, CodeRegion startRegion, CodeRegion endRegion) : StatNode public class If(ExpNode condition, BlockNode body, List<ElseifNode> elseifs, CodeRegion startRegion, CodeRegion endRegion) : StatNode
{ {
public CodeRegion startRegion = startRegion; public ExpNode condition = condition;
public CodeRegion endRegion = endRegion; public BlockNode body = body;
public IfNode node = node; public List<ElseifNode> elseifs = elseifs;
public BlockNode? else_;
public CodeRegion startRegion = startRegion, endRegion = endRegion;
} }
public class ForNumerical(ForNumericalNode node) : StatNode public class ForNumerical(string variable, ExpNode start, ExpNode end, ExpNode? change, BlockNode body, CodeRegion startRegion, CodeRegion endRegion) : StatNode
{ {
public ForNumericalNode node = node; public string variable = variable;
public ExpNode start = start;
public ExpNode end = end;
public ExpNode? change = change;
public BlockNode body = body;
public CodeRegion startRegion = startRegion, endRegion = endRegion;
} }
public class ForGeneric(ForGenericNode node) : StatNode public class ForGeneric(List<string> vars, ExplistNode exps, BlockNode body, CodeRegion startRegion, CodeRegion endRegion) : StatNode
{ {
public ForGenericNode node = node; public List<string> vars = vars;
public ExplistNode exps = exps;
public BlockNode body = body;
public CodeRegion startRegion = startRegion, endRegion = endRegion;
} }
public class Function(FunctionNode node) : StatNode public class Function(FunctionNode node) : StatNode
{ {
public FunctionNode node = node; public FunctionNode node = node;
} }
public class LocalFunction(LocalFunctionNode node) : StatNode public class LocalFunction(string name, FuncbodyNode body, CodeRegion startRegion, CodeRegion endRegion) : StatNode
{ {
public LocalFunctionNode node = node; public string name = name;
public FuncbodyNode body = body;
public CodeRegion startRegion = startRegion, endRegion = endRegion;
} }
public class Local(LocalNode node, CodeRegion startRegion, CodeRegion endRegion) : StatNode public class Local(AttnamelistNode attnames, ExplistNode? values, CodeRegion startRegion, CodeRegion endRegion) : StatNode
{ {
public CodeRegion startRegion = startRegion; public AttnamelistNode attnames = attnames;
public CodeRegion endRegion = endRegion; public ExplistNode? values = values;
public LocalNode node = node; public CodeRegion startRegion = startRegion, endRegion = endRegion;
} }
} }
public class RetstatNode(ExplistNode? values, CodeRegion startRegion, CodeRegion endRegion) public class RetstatNode(ExplistNode? values, CodeRegion startRegion, CodeRegion endRegion)
@ -110,12 +128,6 @@ internal class Parser
public ExplistNode? values = values; public ExplistNode? values = values;
public CodeRegion startRegion = startRegion, endRegion = endRegion; public CodeRegion startRegion = startRegion, endRegion = endRegion;
} }
public class AssignmentNode(VarlistNode lhs, ExplistNode rhs, CodeRegion startRegion, CodeRegion endRegion)
{
public VarlistNode lhs = lhs;
public ExplistNode rhs = rhs;
public CodeRegion startRegion = startRegion, endRegion = endRegion;
}
public class FunctioncallNode(SuffixexpNode function, string? objectArg, ArgsNode args) public class FunctioncallNode(SuffixexpNode function, string? objectArg, ArgsNode args)
{ {
public SuffixexpNode function = function; public SuffixexpNode function = function;
@ -123,60 +135,12 @@ internal class Parser
public ArgsNode args = args; public ArgsNode args = args;
public CodeRegion startRegion = function.startRegion, endRegion = function.endRegion; public CodeRegion startRegion = function.startRegion, endRegion = function.endRegion;
} }
public class WhileNode(ExpNode condition, BlockNode body, CodeRegion startRegion, CodeRegion endRegion)
{
public ExpNode condition = condition;
public BlockNode body = body;
public CodeRegion startRegion = startRegion, endRegion = endRegion;
}
public class RepeatNode(ExpNode condition, BlockNode body, CodeRegion startRegion, CodeRegion endRegion)
{
public ExpNode condition = condition;
public BlockNode body = body;
public CodeRegion startRegion = startRegion, endRegion = endRegion;
}
public class IfNode(ExpNode condition, BlockNode body, List<ElseifNode> elseifs, CodeRegion startRegion, CodeRegion endRegion)
{
public ExpNode condition = condition;
public BlockNode body = body;
public List<ElseifNode> elseifs = elseifs;
public BlockNode? else_;
public CodeRegion startRegion = startRegion, endRegion = endRegion;
}
public class ForNumericalNode(string variable, ExpNode start, ExpNode end, ExpNode? change, BlockNode body, CodeRegion startRegion, CodeRegion endRegion)
{
public string variable = variable;
public ExpNode start = start;
public ExpNode end = end;
public ExpNode? change = change;
public BlockNode body = body;
public CodeRegion startRegion = startRegion, endRegion = endRegion;
}
public class ForGenericNode(List<string> vars, ExplistNode exps, BlockNode body, CodeRegion startRegion, CodeRegion endRegion)
{
public List<string> vars = vars;
public ExplistNode exps = exps;
public BlockNode body = body;
public CodeRegion startRegion = startRegion, endRegion = endRegion;
}
public class FunctionNode(FuncnameNode name, FuncbodyNode body, CodeRegion startRegion, CodeRegion endRegion) public class FunctionNode(FuncnameNode name, FuncbodyNode body, CodeRegion startRegion, CodeRegion endRegion)
{ {
public FuncnameNode name = name; public FuncnameNode name = name;
public FuncbodyNode body = body; public FuncbodyNode body = body;
public CodeRegion startRegion = startRegion, endRegion = endRegion; public CodeRegion startRegion = startRegion, endRegion = endRegion;
} }
public class LocalFunctionNode(string name, FuncbodyNode body, CodeRegion startRegion, CodeRegion endRegion)
{
public string name = name;
public FuncbodyNode body = body;
public CodeRegion startRegion = startRegion, endRegion = endRegion;
}
public class LocalNode(AttnamelistNode attnames, ExplistNode? values, CodeRegion startRegion, CodeRegion endRegion)
{
public AttnamelistNode attnames = attnames;
public ExplistNode? values = values;
public CodeRegion startRegion = startRegion, endRegion = endRegion;
}
public class ExplistNode(List<ExpNode> exps, CodeRegion startRegion, CodeRegion endRegion) public class ExplistNode(List<ExpNode> exps, CodeRegion startRegion, CodeRegion endRegion)
{ {
public List<ExpNode> exps = exps; public List<ExpNode> exps = exps;
@ -192,9 +156,10 @@ internal class Parser
public abstract class SuffixexpNode(CodeRegion startRegion, CodeRegion endRegion) public abstract class SuffixexpNode(CodeRegion startRegion, CodeRegion endRegion)
{ {
public CodeRegion startRegion = startRegion, endRegion = endRegion; public CodeRegion startRegion = startRegion, endRegion = endRegion;
public class Normal(NormalSuffixNode node) : SuffixexpNode(node.startRegion, node.endRegion) public class Normal(SuffixexpFirstPart firstPart, List<SuffixexpSuffix> suffixes, CodeRegion startRegion, CodeRegion endRegion) : SuffixexpNode(startRegion, endRegion)
{ {
public NormalSuffixNode node = node; public SuffixexpFirstPart firstPart = firstPart;
public List<SuffixexpSuffix> suffixes = suffixes;
} }
public class Functioncall(FunctioncallNode node) : SuffixexpNode(node.startRegion, node.endRegion) public class Functioncall(FunctioncallNode node) : SuffixexpNode(node.startRegion, node.endRegion)
{ {
@ -325,12 +290,6 @@ internal class Parser
public MemberVarNode node = node; public MemberVarNode node = node;
} }
} }
public class NormalSuffixNode(SuffixexpFirstPart firstPart, List<SuffixexpSuffix> suffixes, CodeRegion startRegion, CodeRegion endRegion)
{
public SuffixexpFirstPart firstPart = firstPart;
public List<SuffixexpSuffix> suffixes = suffixes;
public CodeRegion startRegion = startRegion, endRegion = endRegion;
}
public class TableconstructorNode(FieldlistNode? exps, CodeRegion startRegion, CodeRegion endRegion) public class TableconstructorNode(FieldlistNode? exps, CodeRegion startRegion, CodeRegion endRegion)
{ {
public FieldlistNode? exps = exps; public FieldlistNode? exps = exps;
@ -576,7 +535,7 @@ internal class Parser
} }
CodeRegion endRegion = tokens[index].region; CodeRegion endRegion = tokens[index].region;
index += 1; index += 1;
return new StatNode.While(new(condition: condition, body: body, startRegion: startRegion, endRegion: endRegion)); return new StatNode.While(condition: condition, body: body, startRegion: startRegion, endRegion: endRegion);
} }
case TokenType.Repeat: case TokenType.Repeat:
{ {
@ -592,7 +551,7 @@ internal class Parser
} }
index += 1; index += 1;
ExpNode conditon = ParseExp(tokens); ExpNode conditon = ParseExp(tokens);
return new StatNode.Repeat(new(condition: conditon, body: body, startRegion: startRegion, endRegion: tokens[index - 1].region)); return new StatNode.Repeat(condition: conditon, body: body, startRegion: startRegion, endRegion: tokens[index - 1].region);
} }
case TokenType.If: case TokenType.If:
{ {
@ -634,7 +593,7 @@ internal class Parser
{ {
throw new Exception($"Index {index} out of bounds of {tokens.Length}, expected `end` after else-ifs of if starting at {startRegion}"); throw new Exception($"Index {index} out of bounds of {tokens.Length}, expected `end` after else-ifs of if starting at {startRegion}");
} }
IfNode ret = new(condition: condition, body: body, elseifs: elseifs, startRegion: startRegion, endRegion: tokens[index - 1].region); StatNode.If ret = new(condition: condition, body: body, elseifs: elseifs, startRegion: startRegion, endRegion: tokens[index - 1].region);
if(tokens[index].type == TokenType.Else) if(tokens[index].type == TokenType.Else)
{ {
index += 1; index += 1;
@ -650,7 +609,7 @@ internal class Parser
} }
ret.endRegion = tokens[index].region; ret.endRegion = tokens[index].region;
index += 1; index += 1;
return new StatNode.If(node: ret, startRegion: startRegion, endRegion: ret.endRegion); return ret;
} }
case TokenType.For: case TokenType.For:
{ {
@ -713,7 +672,7 @@ internal class Parser
} }
CodeRegion endRegion = tokens[index].region; CodeRegion endRegion = tokens[index].region;
index += 1; index += 1;
return new StatNode.ForNumerical(new(variable: variable, start: start, end: end, change: change, body: body, startRegion: startRegion, endRegion: endRegion)); return new StatNode.ForNumerical(variable: variable, start: start, end: end, change: change, body: body, startRegion: startRegion, endRegion: endRegion);
} }
case TokenType.Comma: case TokenType.Comma:
{ {
@ -766,7 +725,7 @@ internal class Parser
} }
CodeRegion endRegion = tokens[index].region; CodeRegion endRegion = tokens[index].region;
index += 1; index += 1;
return new StatNode.ForGeneric(new(vars: names, exps: exps, body: body, startRegion: startRegion, endRegion: endRegion)); return new StatNode.ForGeneric(vars: names, exps: exps, body: body, startRegion: startRegion, endRegion: endRegion);
} }
case TokenType.In: case TokenType.In:
{ {
@ -792,7 +751,7 @@ internal class Parser
} }
CodeRegion endRegion = tokens[index].region; CodeRegion endRegion = tokens[index].region;
index += 1; index += 1;
return new StatNode.ForGeneric(new(vars: [variable], exps: exps, body: body, startRegion: startRegion, endRegion: endRegion)); return new StatNode.ForGeneric(vars: [variable], exps: exps, body: body, startRegion: startRegion, endRegion: endRegion);
} }
default: default:
{ {
@ -828,19 +787,19 @@ internal class Parser
string name = ((Token.StringData)tokens[index].data!).data; string name = ((Token.StringData)tokens[index].data!).data;
index += 1; index += 1;
FuncbodyNode body = ParseFuncbody(tokens); FuncbodyNode body = ParseFuncbody(tokens);
return new StatNode.LocalFunction(new(name: name, body: body, startRegion: startRegion, endRegion: body.endRegion)); return new StatNode.LocalFunction(name: name, body: body, startRegion: startRegion, endRegion: body.endRegion);
} }
else else
{ {
AttnamelistNode attnames = ParseAttnamelist(tokens); AttnamelistNode attnames = ParseAttnamelist(tokens);
LocalNode ret = new(attnames: attnames, values: null, startRegion: startRegion, endRegion: attnames.endRegion); StatNode.Local ret = new(attnames: attnames, values: null, startRegion: startRegion, endRegion: attnames.endRegion);
if(index < tokens.Length && tokens[index].type == TokenType.Equals) if(index < tokens.Length && tokens[index].type == TokenType.Equals)
{ {
index += 1; index += 1;
ret.values = ParseExplist(tokens); ret.values = ParseExplist(tokens);
ret.endRegion = ret.values.endRegion; ret.endRegion = ret.values.endRegion;
} }
return new StatNode.Local(ret, startRegion: startRegion, endRegion: ret.endRegion); return ret;
} }
} }
case TokenType.ColonColon: case TokenType.ColonColon:
@ -892,7 +851,7 @@ internal class Parser
index += 1; index += 1;
List<VarNode> lhs = [SuffixExpToVar(suffixExp)]; List<VarNode> lhs = [SuffixExpToVar(suffixExp)];
ExplistNode rhs = ParseExplist(tokens); ExplistNode rhs = ParseExplist(tokens);
return new StatNode.Assignment(new(lhs: new(vars: lhs, startRegion: startRegion, endRegion: suffixExp.endRegion), rhs: rhs, startRegion: startRegion, endRegion: rhs.endRegion)); return new StatNode.Assignment(lhs: new(vars: lhs, startRegion: startRegion, endRegion: suffixExp.endRegion), rhs: rhs, startRegion: startRegion, endRegion: rhs.endRegion);
} }
case TokenType.Comma: case TokenType.Comma:
{ {
@ -913,7 +872,7 @@ internal class Parser
index += 1; index += 1;
VarlistNode varlistNode = new(vars: vars, startRegion: startRegion, endRegion: vars[^1].endRegion); VarlistNode varlistNode = new(vars: vars, startRegion: startRegion, endRegion: vars[^1].endRegion);
ExplistNode rhs = ParseExplist(tokens); ExplistNode rhs = ParseExplist(tokens);
return new StatNode.Assignment(new(lhs: varlistNode, rhs: rhs, startRegion: startRegion, endRegion: rhs.endRegion)); return new StatNode.Assignment(lhs: varlistNode, rhs: rhs, startRegion: startRegion, endRegion: rhs.endRegion);
} }
} }
if(suffixExp is SuffixexpNode.Normal) if(suffixExp is SuffixexpNode.Normal)
@ -946,16 +905,16 @@ internal class Parser
{ {
throw new Exception($"Expected a normal suffix expression to convert to var at {suffixExp.startRegion}-{suffixExp.endRegion}"); throw new Exception($"Expected a normal suffix expression to convert to var at {suffixExp.startRegion}-{suffixExp.endRegion}");
} }
if(normal.node.suffixes.Count == 0) if(normal.suffixes.Count == 0)
{ {
if(normal.node.firstPart is not SuffixexpFirstPart.Name name) if(normal.firstPart is not SuffixexpFirstPart.Name name)
{ {
throw new Exception($"Expected a name as first part of suffix expression to convert to var at {normal.node.firstPart.startRegion}-{normal.node.firstPart.endRegion}"); throw new Exception($"Expected a name as first part of suffix expression to convert to var at {normal.firstPart.startRegion}-{normal.firstPart.endRegion}");
} }
return new VarNode.Name(name: name.name, startRegion: suffixExp.startRegion, endRegion: suffixExp.endRegion); return new VarNode.Name(name: name.name, startRegion: suffixExp.startRegion, endRegion: suffixExp.endRegion);
} }
SuffixexpSuffix last = normal.node.suffixes[^1]; SuffixexpSuffix last = normal.suffixes[^1];
_ = normal.node.suffixes.Remove(last); _ = normal.suffixes.Remove(last);
return last switch return last switch
{ {
SuffixexpSuffix.Dot dot => new VarNode.Member(node: new(name: dot.name, value: normal, startRegion: suffixExp.startRegion, endRegion: suffixExp.endRegion), startRegion: suffixExp.startRegion, endRegion: dot.endRegion), SuffixexpSuffix.Dot dot => new VarNode.Member(node: new(name: dot.name, value: normal, startRegion: suffixExp.startRegion, endRegion: suffixExp.endRegion), startRegion: suffixExp.startRegion, endRegion: dot.endRegion),
@ -1081,18 +1040,14 @@ internal class Parser
{ {
SuffixexpSuffix.Args args => new SuffixexpNode.Functioncall( SuffixexpSuffix.Args args => new SuffixexpNode.Functioncall(
node: new( node: new(
function: new SuffixexpNode.Normal( function: new SuffixexpNode.Normal(firstPart, suffixes[..^1], startRegion, args.endRegion),
node: new NormalSuffixNode(firstPart, suffixes[..^1], startRegion, args.endRegion)
),
args: args.node, args: args.node,
objectArg: null objectArg: null
) )
), ),
SuffixexpSuffix.ArgsFirstArg node => new SuffixexpNode.Functioncall( SuffixexpSuffix.ArgsFirstArg node => new SuffixexpNode.Functioncall(
node: new( node: new(
function: new SuffixexpNode.Normal( function: new SuffixexpNode.Normal(firstPart: firstPart, suffixes: suffixes[..^1], startRegion, node.endRegion),
node: new NormalSuffixNode(firstPart: firstPart, suffixes: suffixes[..^1], startRegion, node.endRegion)
),
objectArg: node.node.name, objectArg: node.node.name,
args: node.node.rest args: node.node.rest
) )
@ -1109,7 +1064,7 @@ internal class Parser
endRegion = firstPart.endRegion; endRegion = firstPart.endRegion;
} }
return new SuffixexpNode.Normal(node: new(firstPart: firstPart, suffixes: suffixes, startRegion: startRegion, endRegion: endRegion)); return new SuffixexpNode.Normal(firstPart: firstPart, suffixes: suffixes, startRegion: startRegion, endRegion: endRegion);
} }
private ArgsNode ParseArgs(Token[] tokens) private ArgsNode ParseArgs(Token[] tokens)