...
This commit is contained in:
@@ -29,11 +29,12 @@ public class Parser
|
||||
}
|
||||
}
|
||||
|
||||
return new ModuleNode(rootFilePath, imports, definitions);
|
||||
return new ModuleNode(GetTokensForNode(0), rootFilePath, imports, definitions);
|
||||
}
|
||||
|
||||
private DefinitionNode ParseDefinition()
|
||||
{
|
||||
var startIndex = _index;
|
||||
List<Modifier> modifiers = [];
|
||||
|
||||
List<string> documentationParts = [];
|
||||
@@ -53,13 +54,13 @@ public class Parser
|
||||
var keyword = ExpectSymbol();
|
||||
return keyword.Symbol switch
|
||||
{
|
||||
Symbol.Func => ParseFuncDefinition(modifiers, Optional.OfNullable(documentation)),
|
||||
Symbol.Struct => ParseStruct(modifiers, Optional.OfNullable(documentation)),
|
||||
Symbol.Func => ParseFuncDefinition(startIndex, modifiers, Optional.OfNullable(documentation)),
|
||||
Symbol.Struct => ParseStruct(startIndex, modifiers, Optional.OfNullable(documentation)),
|
||||
_ => throw new Exception("Unexpected symbol: " + keyword.Symbol)
|
||||
};
|
||||
}
|
||||
|
||||
private DefinitionNode ParseFuncDefinition(List<Modifier> modifiers, Optional<string> documentation)
|
||||
private DefinitionNode ParseFuncDefinition(int startIndex, List<Modifier> modifiers, Optional<string> documentation)
|
||||
{
|
||||
var name = ExpectIdentifier();
|
||||
List<FuncParameter> parameters = [];
|
||||
@@ -86,7 +87,7 @@ public class Parser
|
||||
throw new Exception($"Modifiers: {string.Join(", ", modifiers)} is not valid for an extern function");
|
||||
}
|
||||
|
||||
return new ExternFuncDefinitionNode(name.Value, parameters, returnType, documentation);
|
||||
return new ExternFuncDefinitionNode(GetTokensForNode(startIndex), documentation, name.Value, parameters, returnType);
|
||||
}
|
||||
|
||||
var body = ParseBlock();
|
||||
@@ -97,10 +98,10 @@ public class Parser
|
||||
throw new Exception($"Modifiers: {string.Join(", ", modifiers)} is not valid for a local function");
|
||||
}
|
||||
|
||||
return new LocalFuncDefinitionNode(name.Value, parameters, body, returnType, global, documentation);
|
||||
return new LocalFuncDefinitionNode(GetTokensForNode(startIndex), documentation, name.Value, parameters, body, returnType, global);
|
||||
}
|
||||
|
||||
private StructDefinitionNode ParseStruct(List<Modifier> _, Optional<string> documentation)
|
||||
private StructDefinitionNode ParseStruct(int startIndex, List<Modifier> _, Optional<string> documentation)
|
||||
{
|
||||
var name = ExpectIdentifier().Value;
|
||||
|
||||
@@ -124,7 +125,7 @@ public class Parser
|
||||
variables.Add(new StructField(variableName, variableType, variableValue));
|
||||
}
|
||||
|
||||
return new StructDefinitionNode(name, variables, documentation);
|
||||
return new StructDefinitionNode(GetTokensForNode(startIndex), documentation, name, variables);
|
||||
}
|
||||
|
||||
private FuncParameter ParseFuncParameter()
|
||||
@@ -146,6 +147,7 @@ public class Parser
|
||||
|
||||
private StatementNode ParseStatement()
|
||||
{
|
||||
var startIndex = _index;
|
||||
var token = ExpectToken();
|
||||
switch (token)
|
||||
{
|
||||
@@ -163,19 +165,19 @@ public class Parser
|
||||
TryExpectSymbol(Symbol.Comma);
|
||||
}
|
||||
|
||||
return new FuncCallStatementNode(new FuncCall(identifier.Value, parameters));
|
||||
return new FuncCallStatementNode(GetTokensForNode(startIndex), new FuncCall(identifier.Value, parameters));
|
||||
}
|
||||
case Symbol.Assign:
|
||||
{
|
||||
var value = ParseExpression();
|
||||
return new VariableAssignmentNode(identifier.Value, Optional<NubType>.Empty(), value);
|
||||
return new VariableAssignmentNode(GetTokensForNode(startIndex), identifier.Value, Optional<NubType>.Empty(), value);
|
||||
}
|
||||
case Symbol.Colon:
|
||||
{
|
||||
var type = ParseType();
|
||||
ExpectSymbol(Symbol.Assign);
|
||||
var value = ParseExpression();
|
||||
return new VariableAssignmentNode(identifier.Value, type, value);
|
||||
return new VariableAssignmentNode(GetTokensForNode(startIndex), identifier.Value, type, value);
|
||||
}
|
||||
default:
|
||||
{
|
||||
@@ -187,11 +189,11 @@ public class Parser
|
||||
{
|
||||
return symbol.Symbol switch
|
||||
{
|
||||
Symbol.Return => ParseReturn(),
|
||||
Symbol.If => ParseIf(),
|
||||
Symbol.While => ParseWhile(),
|
||||
Symbol.Break => new BreakNode(),
|
||||
Symbol.Continue => new ContinueNode(),
|
||||
Symbol.Return => ParseReturn(startIndex),
|
||||
Symbol.If => ParseIf(startIndex),
|
||||
Symbol.While => ParseWhile(startIndex),
|
||||
Symbol.Break => new BreakNode(GetTokensForNode(startIndex)),
|
||||
Symbol.Continue => new ContinueNode(GetTokensForNode(startIndex)),
|
||||
_ => throw new Exception($"Unexpected symbol {symbol.Symbol}")
|
||||
};
|
||||
}
|
||||
@@ -202,7 +204,7 @@ public class Parser
|
||||
}
|
||||
}
|
||||
|
||||
private ReturnNode ParseReturn()
|
||||
private ReturnNode ParseReturn(int startIndex)
|
||||
{
|
||||
var value = Optional<ExpressionNode>.Empty();
|
||||
if (!TryExpectSymbol(Symbol.Semicolon))
|
||||
@@ -210,10 +212,10 @@ public class Parser
|
||||
value = ParseExpression();
|
||||
}
|
||||
|
||||
return new ReturnNode(value);
|
||||
return new ReturnNode(GetTokensForNode(startIndex), value);
|
||||
}
|
||||
|
||||
private IfNode ParseIf()
|
||||
private IfNode ParseIf(int startIndex)
|
||||
{
|
||||
var condition = ParseExpression();
|
||||
var body = ParseBlock();
|
||||
@@ -221,23 +223,25 @@ public class Parser
|
||||
var elseStatement = Optional<Variant<IfNode, BlockNode>>.Empty();
|
||||
if (TryExpectSymbol(Symbol.Else))
|
||||
{
|
||||
var newStartIndex = _index;
|
||||
elseStatement = TryExpectSymbol(Symbol.If)
|
||||
? (Variant<IfNode, BlockNode>)ParseIf()
|
||||
? (Variant<IfNode, BlockNode>)ParseIf(newStartIndex)
|
||||
: (Variant<IfNode, BlockNode>)ParseBlock();
|
||||
}
|
||||
|
||||
return new IfNode(condition, body, elseStatement);
|
||||
return new IfNode(GetTokensForNode(startIndex), condition, body, elseStatement);
|
||||
}
|
||||
|
||||
private WhileNode ParseWhile()
|
||||
private WhileNode ParseWhile(int startIndex)
|
||||
{
|
||||
var condition = ParseExpression();
|
||||
var body = ParseBlock();
|
||||
return new WhileNode(condition, body);
|
||||
return new WhileNode(GetTokensForNode(startIndex), condition, body);
|
||||
}
|
||||
|
||||
private ExpressionNode ParseExpression(int precedence = 0)
|
||||
{
|
||||
var startIndex = _index;
|
||||
var left = ParsePrimaryExpression();
|
||||
|
||||
while (true)
|
||||
@@ -250,7 +254,7 @@ public class Parser
|
||||
Next();
|
||||
var right = ParseExpression(GetBinaryOperatorPrecedence(op.Value) + 1);
|
||||
|
||||
left = new BinaryExpressionNode(left, op.Value, right);
|
||||
left = new BinaryExpressionNode(GetTokensForNode(startIndex), left, op.Value, right);
|
||||
}
|
||||
|
||||
return left;
|
||||
@@ -316,6 +320,7 @@ public class Parser
|
||||
|
||||
private ExpressionNode ParsePrimaryExpression()
|
||||
{
|
||||
var startIndex = _index;
|
||||
ExpressionNode expr;
|
||||
|
||||
var token = ExpectToken();
|
||||
@@ -323,7 +328,7 @@ public class Parser
|
||||
{
|
||||
case LiteralToken literal:
|
||||
{
|
||||
expr = new LiteralNode(literal.Value, literal.Type);
|
||||
expr = new LiteralNode(GetTokensForNode(startIndex), literal.Value, literal.Type);
|
||||
break;
|
||||
}
|
||||
case IdentifierToken identifier:
|
||||
@@ -341,12 +346,12 @@ public class Parser
|
||||
TryExpectSymbol(Symbol.Comma);
|
||||
}
|
||||
|
||||
expr = new FuncCallExpressionNode(new FuncCall(identifier.Value, parameters));
|
||||
expr = new FuncCallExpressionNode(GetTokensForNode(startIndex), new FuncCall(identifier.Value, parameters));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
expr = new IdentifierNode(identifier.Value);
|
||||
expr = new IdentifierNode(GetTokensForNode(startIndex), identifier.Value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -371,7 +376,7 @@ public class Parser
|
||||
ExpectSymbol(Symbol.OpenParen);
|
||||
var expressionToCast = ParseExpression();
|
||||
ExpectSymbol(Symbol.CloseParen);
|
||||
expr = new CastNode(type, expressionToCast);
|
||||
expr = new CastNode(GetTokensForNode(startIndex), type, expressionToCast);
|
||||
break;
|
||||
}
|
||||
case Symbol.New:
|
||||
@@ -387,25 +392,25 @@ public class Parser
|
||||
initializers.Add(name, value);
|
||||
}
|
||||
|
||||
expr = new StructInitializerNode(type, initializers);
|
||||
expr = new StructInitializerNode(GetTokensForNode(startIndex), type, initializers);
|
||||
break;
|
||||
}
|
||||
case Symbol.Ampersand:
|
||||
{
|
||||
var expression = ParsePrimaryExpression();
|
||||
expr = new AddressOfNode(expression);
|
||||
expr = new AddressOfNode(GetTokensForNode(startIndex), expression);
|
||||
break;
|
||||
}
|
||||
case Symbol.Minus:
|
||||
{
|
||||
var expression = ParsePrimaryExpression();
|
||||
expr = new UnaryExpressionNode(UnaryExpressionOperator.Negate, expression);
|
||||
expr = new UnaryExpressionNode(GetTokensForNode(startIndex), UnaryExpressionOperator.Negate, expression);
|
||||
break;
|
||||
}
|
||||
case Symbol.Bang:
|
||||
{
|
||||
var expression = ParsePrimaryExpression();
|
||||
expr = new UnaryExpressionNode(UnaryExpressionOperator.Invert, expression);
|
||||
expr = new UnaryExpressionNode(GetTokensForNode(startIndex), UnaryExpressionOperator.Invert, expression);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -422,23 +427,23 @@ public class Parser
|
||||
}
|
||||
}
|
||||
|
||||
return ParsePostfixOperators(expr);
|
||||
return ParsePostfixOperators(startIndex, expr);
|
||||
}
|
||||
|
||||
private ExpressionNode ParsePostfixOperators(ExpressionNode expr)
|
||||
private ExpressionNode ParsePostfixOperators(int startIndex, ExpressionNode expr)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (TryExpectSymbol(Symbol.Caret))
|
||||
{
|
||||
expr = new DereferenceNode(expr);
|
||||
expr = new DereferenceNode(GetTokensForNode(startIndex), expr);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (TryExpectSymbol(Symbol.Period))
|
||||
{
|
||||
var structMember = ExpectIdentifier().Value;
|
||||
expr = new MemberAccessNode(expr, structMember);
|
||||
expr = new MemberAccessNode(GetTokensForNode(startIndex), expr, structMember);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -446,7 +451,7 @@ public class Parser
|
||||
{
|
||||
var index = ParseExpression();
|
||||
ExpectSymbol(Symbol.CloseBracket);
|
||||
expr = new ArrayIndexNode(expr, index);
|
||||
expr = new ArrayIndexNode(GetTokensForNode(startIndex), expr, index);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -458,6 +463,7 @@ public class Parser
|
||||
|
||||
private BlockNode ParseBlock()
|
||||
{
|
||||
var startIndex = _index;
|
||||
ExpectSymbol(Symbol.OpenBrace);
|
||||
List<StatementNode> statements = [];
|
||||
while (!TryExpectSymbol(Symbol.CloseBrace))
|
||||
@@ -465,7 +471,7 @@ public class Parser
|
||||
statements.Add(ParseStatement());
|
||||
}
|
||||
|
||||
return new BlockNode(statements);
|
||||
return new BlockNode(GetTokensForNode(startIndex), statements);
|
||||
}
|
||||
|
||||
private NubType ParseType()
|
||||
@@ -592,4 +598,9 @@ public class Parser
|
||||
|
||||
_index++;
|
||||
}
|
||||
|
||||
private IReadOnlyList<Token> GetTokensForNode(int startIndex)
|
||||
{
|
||||
return _tokens[startIndex..Math.Min(_index, _tokens.Count - 1)];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user