...
This commit is contained in:
@@ -1,6 +1,25 @@
|
|||||||
namespace main
|
namespace main
|
||||||
|
|
||||||
export func main(args: []cstring): i64 {
|
struct Human
|
||||||
c::puts("test")
|
{
|
||||||
|
name: cstring
|
||||||
|
age: i64
|
||||||
|
}
|
||||||
|
|
||||||
|
func test() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export func main(args: []cstring): i64
|
||||||
|
{
|
||||||
|
let x: []cstring
|
||||||
|
|
||||||
|
x = [2]cstring
|
||||||
|
|
||||||
|
x[0] = "test1"
|
||||||
|
x[1] = "test2"
|
||||||
|
|
||||||
|
c::puts(x[1])
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ const string BIN_DIR = "bin";
|
|||||||
const string INT_DIR = "bin-int";
|
const string INT_DIR = "bin-int";
|
||||||
var INT_BUILTIN_DIR = Path.Join(INT_DIR, "builtin");
|
var INT_BUILTIN_DIR = Path.Join(INT_DIR, "builtin");
|
||||||
var INT_OBJECT_DIR = Path.Join(INT_DIR, "obj");
|
var INT_OBJECT_DIR = Path.Join(INT_DIR, "obj");
|
||||||
|
var INT_DEBUG_DIR = Path.Join(INT_DIR, "debug");
|
||||||
|
|
||||||
if (Directory.Exists(INT_DIR))
|
if (Directory.Exists(INT_DIR))
|
||||||
{
|
{
|
||||||
@@ -21,6 +22,7 @@ if (Directory.Exists(INT_DIR))
|
|||||||
Directory.CreateDirectory(BIN_DIR);
|
Directory.CreateDirectory(BIN_DIR);
|
||||||
Directory.CreateDirectory(INT_BUILTIN_DIR);
|
Directory.CreateDirectory(INT_BUILTIN_DIR);
|
||||||
Directory.CreateDirectory(INT_OBJECT_DIR);
|
Directory.CreateDirectory(INT_OBJECT_DIR);
|
||||||
|
Directory.CreateDirectory(INT_DEBUG_DIR);
|
||||||
|
|
||||||
var options = new Options();
|
var options = new Options();
|
||||||
|
|
||||||
@@ -116,14 +118,20 @@ var objectFiles = new List<string>();
|
|||||||
|
|
||||||
foreach (var file in options.Files)
|
foreach (var file in options.Files)
|
||||||
{
|
{
|
||||||
|
var outFileName = $"{HexString.CreateUnique(8)}_{Path.GetFileNameWithoutExtension(file)}";
|
||||||
|
|
||||||
var ssa = QBEGenerator.Emit(boundSyntaxTrees[file], boundDefinitionTable);
|
var ssa = QBEGenerator.Emit(boundSyntaxTrees[file], boundDefinitionTable);
|
||||||
|
File.WriteAllText(Path.Join(INT_DEBUG_DIR, $"{outFileName}.ssa"), ssa);
|
||||||
|
|
||||||
var asm = await QBE.Invoke(ssa);
|
var asm = await QBE.Invoke(ssa);
|
||||||
if (asm == null)
|
if (asm == null)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fileName = Path.Join(INT_OBJECT_DIR, $"{HexString.CreateUnique(8)}_{Path.GetFileNameWithoutExtension(file)}.o");
|
File.WriteAllText(Path.Join(INT_DEBUG_DIR, $"{outFileName}.s"), asm);
|
||||||
|
|
||||||
|
var fileName = Path.Join(INT_OBJECT_DIR, $"{outFileName}.o");
|
||||||
var asmSuccess = await GCC.Assemble(asm, fileName);
|
var asmSuccess = await GCC.Assemble(asm, fileName);
|
||||||
if (!asmSuccess)
|
if (!asmSuccess)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -477,8 +477,8 @@ public static class QBEGenerator
|
|||||||
{
|
{
|
||||||
switch (statement)
|
switch (statement)
|
||||||
{
|
{
|
||||||
case BoundArrayIndexAssignmentNode arrayIndexAssignment:
|
case BoundAssignmentNode assignment:
|
||||||
EmitArrayIndexAssignment(arrayIndexAssignment);
|
EmitAssignment(assignment);
|
||||||
break;
|
break;
|
||||||
case BoundBreakNode:
|
case BoundBreakNode:
|
||||||
EmitBreak();
|
EmitBreak();
|
||||||
@@ -486,15 +486,9 @@ public static class QBEGenerator
|
|||||||
case BoundContinueNode:
|
case BoundContinueNode:
|
||||||
EmitContinue();
|
EmitContinue();
|
||||||
break;
|
break;
|
||||||
case BoundDereferenceAssignmentNode dereferenceAssignment:
|
|
||||||
EmitDereferenceAssignment(dereferenceAssignment);
|
|
||||||
break;
|
|
||||||
case BoundIfNode ifStatement:
|
case BoundIfNode ifStatement:
|
||||||
EmitIf(ifStatement);
|
EmitIf(ifStatement);
|
||||||
break;
|
break;
|
||||||
case BoundMemberAssignmentNode memberAssignment:
|
|
||||||
EmitMemberAssignment(memberAssignment);
|
|
||||||
break;
|
|
||||||
case BoundReturnNode @return:
|
case BoundReturnNode @return:
|
||||||
EmitReturn(@return);
|
EmitReturn(@return);
|
||||||
break;
|
break;
|
||||||
@@ -504,9 +498,6 @@ public static class QBEGenerator
|
|||||||
case BoundVariableDeclarationNode variableDeclaration:
|
case BoundVariableDeclarationNode variableDeclaration:
|
||||||
EmitVariableDeclaration(variableDeclaration);
|
EmitVariableDeclaration(variableDeclaration);
|
||||||
break;
|
break;
|
||||||
case BoundVariableAssignmentNode variableAssignment:
|
|
||||||
EmitVariableAssignment(variableAssignment);
|
|
||||||
break;
|
|
||||||
case BoundWhileNode whileStatement:
|
case BoundWhileNode whileStatement:
|
||||||
EmitWhile(whileStatement);
|
EmitWhile(whileStatement);
|
||||||
break;
|
break;
|
||||||
@@ -515,30 +506,16 @@ public static class QBEGenerator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void EmitArrayIndexAssignment(BoundArrayIndexAssignmentNode arrayIndexAssignment)
|
private static void EmitAssignment(BoundAssignmentNode assignment)
|
||||||
{
|
{
|
||||||
var array = EmitUnwrap(EmitExpression(arrayIndexAssignment.ArrayIndexAccess.Array));
|
var expression = EmitExpression(assignment.Expression);
|
||||||
var index = EmitUnwrap(EmitExpression(arrayIndexAssignment.ArrayIndexAccess.Index));
|
if (expression.Kind != ValKind.Pointer)
|
||||||
EmitArrayBoundsCheck(array, index);
|
|
||||||
var value = EmitUnwrap(EmitExpression(arrayIndexAssignment.Value));
|
|
||||||
|
|
||||||
switch (arrayIndexAssignment.ArrayIndexAccess.Array.Type)
|
|
||||||
{
|
{
|
||||||
case NubArrayType arrayType:
|
throw new UnreachableException();
|
||||||
{
|
|
||||||
var pointer = VarName();
|
|
||||||
_builder.AppendLine($" {pointer} =l mul {index}, {SizeOf(arrayType.ElementType)}");
|
|
||||||
_builder.AppendLine($" {pointer} =l add {pointer}, 8");
|
|
||||||
_builder.AppendLine($" {pointer} =l add {array}, {pointer}");
|
|
||||||
|
|
||||||
EmitCopy(arrayType.ElementType, value, pointer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var value = EmitUnwrap(EmitExpression(assignment.Value));
|
||||||
|
EmitCopy(assignment.Value.Type, value, expression.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void EmitBlock(BoundBlockNode block, List<Variable>? variables = null)
|
private static void EmitBlock(BoundBlockNode block, List<Variable>? variables = null)
|
||||||
@@ -578,13 +555,6 @@ public static class QBEGenerator
|
|||||||
_codeIsReachable = false;
|
_codeIsReachable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void EmitDereferenceAssignment(BoundDereferenceAssignmentNode dereferenceAssignment)
|
|
||||||
{
|
|
||||||
var pointer = EmitUnwrap(EmitExpression(dereferenceAssignment.Dereference.Expression));
|
|
||||||
var value = EmitUnwrap(EmitExpression(dereferenceAssignment.Value));
|
|
||||||
EmitCopy(dereferenceAssignment.Value.Type, value, pointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void EmitIf(BoundIfNode ifStatement)
|
private static void EmitIf(BoundIfNode ifStatement)
|
||||||
{
|
{
|
||||||
var trueLabel = LabelName();
|
var trueLabel = LabelName();
|
||||||
@@ -609,24 +579,6 @@ public static class QBEGenerator
|
|||||||
_builder.AppendLine(endLabel);
|
_builder.AppendLine(endLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void EmitMemberAssignment(BoundMemberAssignmentNode memberAssignment)
|
|
||||||
{
|
|
||||||
var structType = memberAssignment.MemberAccess.Expression.Type as NubStructType;
|
|
||||||
Debug.Assert(structType != null);
|
|
||||||
|
|
||||||
var structDefinition = _definitionTable.LookupStruct(structType.Namespace, structType.Name).GetValue();
|
|
||||||
var offset = OffsetOf(structDefinition, memberAssignment.MemberAccess.Member);
|
|
||||||
|
|
||||||
var item = EmitUnwrap(EmitExpression(memberAssignment.MemberAccess.Expression));
|
|
||||||
var pointer = VarName();
|
|
||||||
|
|
||||||
_builder.AppendLine($" {pointer} =l add {item}, {offset}");
|
|
||||||
|
|
||||||
var value = EmitUnwrap(EmitExpression(memberAssignment.Value));
|
|
||||||
|
|
||||||
EmitCopy(memberAssignment.Value.Type, value, pointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void EmitReturn(BoundReturnNode @return)
|
private static void EmitReturn(BoundReturnNode @return)
|
||||||
{
|
{
|
||||||
if (@return.Value.HasValue)
|
if (@return.Value.HasValue)
|
||||||
@@ -647,13 +599,6 @@ public static class QBEGenerator
|
|||||||
_variables.Push(new Variable(variableDeclaration.Name, new Val(tmp, variableDeclaration.Type, ValKind.Pointer)));
|
_variables.Push(new Variable(variableDeclaration.Name, new Val(tmp, variableDeclaration.Type, ValKind.Pointer)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void EmitVariableAssignment(BoundVariableAssignmentNode variableAssignment)
|
|
||||||
{
|
|
||||||
var value = EmitUnwrap(EmitExpression(variableAssignment.Value));
|
|
||||||
var variable = _variables.Single(x => x.Name == variableAssignment.Identifier.Name);
|
|
||||||
EmitCopy(variableAssignment.Value.Type, value, variable.Val.Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void EmitWhile(BoundWhileNode whileStatement)
|
private static void EmitWhile(BoundWhileNode whileStatement)
|
||||||
{
|
{
|
||||||
var conditionLabel = LabelName();
|
var conditionLabel = LabelName();
|
||||||
@@ -685,7 +630,6 @@ public static class QBEGenerator
|
|||||||
BoundArrayInitializerNode arrayInitializer => EmitArrayInitializer(arrayInitializer),
|
BoundArrayInitializerNode arrayInitializer => EmitArrayInitializer(arrayInitializer),
|
||||||
BoundBinaryExpressionNode binaryExpression => EmitBinaryExpression(binaryExpression),
|
BoundBinaryExpressionNode binaryExpression => EmitBinaryExpression(binaryExpression),
|
||||||
BoundDereferenceNode dereference => EmitDereference(dereference),
|
BoundDereferenceNode dereference => EmitDereference(dereference),
|
||||||
BoundFixedArrayInitializerNode fixedArrayInitializer => EmitFixedArrayInitializer(fixedArrayInitializer),
|
|
||||||
BoundFuncCallNode funcCallExpression => EmitFuncCall(funcCallExpression),
|
BoundFuncCallNode funcCallExpression => EmitFuncCall(funcCallExpression),
|
||||||
BoundIdentifierNode identifier => EmitIdentifier(identifier),
|
BoundIdentifierNode identifier => EmitIdentifier(identifier),
|
||||||
BoundLiteralNode literal => EmitLiteral(literal),
|
BoundLiteralNode literal => EmitLiteral(literal),
|
||||||
@@ -703,31 +647,18 @@ public static class QBEGenerator
|
|||||||
return new Val(name, anonymousFunc.Type, ValKind.Func);
|
return new Val(name, anonymousFunc.Type, ValKind.Func);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string EmitArrayIndexPointer(BoundArrayIndexAccessNode arrayIndexAccess)
|
private static Val EmitArrayIndexAccess(BoundArrayIndexAccessNode arrayIndexAccess)
|
||||||
{
|
{
|
||||||
var array = EmitUnwrap(EmitExpression(arrayIndexAccess.Array));
|
var array = EmitUnwrap(EmitExpression(arrayIndexAccess.Array));
|
||||||
var index = EmitUnwrap(EmitExpression(arrayIndexAccess.Index));
|
var index = EmitUnwrap(EmitExpression(arrayIndexAccess.Index));
|
||||||
EmitArrayBoundsCheck(array, index);
|
|
||||||
|
|
||||||
var elementType = arrayIndexAccess.Array.Type switch
|
var elementType = ((NubArrayType)arrayIndexAccess.Array.Type).ElementType;
|
||||||
{
|
|
||||||
NubArrayType arrayType => arrayType.ElementType,
|
|
||||||
_ => throw new ArgumentOutOfRangeException()
|
|
||||||
};
|
|
||||||
|
|
||||||
var pointer = VarName();
|
var pointer = VarName();
|
||||||
_builder.AppendLine($" {pointer} =l mul {index}, {SizeOf(elementType)}");
|
_builder.AppendLine($" {pointer} =l mul {index}, {SizeOf(elementType)}");
|
||||||
_builder.AppendLine($" {pointer} =l add {pointer}, 8");
|
_builder.AppendLine($" {pointer} =l add {pointer}, 8");
|
||||||
_builder.AppendLine($" {pointer} =l add {array}, {pointer}");
|
_builder.AppendLine($" {pointer} =l add {array}, {pointer}");
|
||||||
return pointer;
|
return new Val(pointer, arrayIndexAccess.Type, ValKind.Pointer);
|
||||||
}
|
|
||||||
|
|
||||||
private static Val EmitArrayIndexAccess(BoundArrayIndexAccessNode arrayIndexAccess)
|
|
||||||
{
|
|
||||||
var pointer = EmitArrayIndexPointer(arrayIndexAccess);
|
|
||||||
var outputName = VarName();
|
|
||||||
_builder.AppendLine($" {outputName} {QBEAssign(arrayIndexAccess.Type)} {QBELoad(arrayIndexAccess.Type)} {pointer}");
|
|
||||||
return new Val(outputName, arrayIndexAccess.Type, ValKind.Immediate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void EmitArrayBoundsCheck(string array, string index)
|
private static void EmitArrayBoundsCheck(string array, string index)
|
||||||
@@ -785,31 +716,13 @@ public static class QBEGenerator
|
|||||||
|
|
||||||
private static Val EmitAddressOf(BoundAddressOfNode addressOf)
|
private static Val EmitAddressOf(BoundAddressOfNode addressOf)
|
||||||
{
|
{
|
||||||
switch (addressOf.Expression)
|
var value = EmitExpression(addressOf.Expression);
|
||||||
|
if (value.Kind != ValKind.Pointer)
|
||||||
{
|
{
|
||||||
case BoundArrayIndexAccessNode arrayIndexAccess:
|
throw new UnreachableException();
|
||||||
{
|
|
||||||
var pointer = EmitArrayIndexPointer(arrayIndexAccess);
|
|
||||||
return new Val(pointer, addressOf.Type, ValKind.Immediate);
|
|
||||||
}
|
|
||||||
case BoundDereferenceNode dereference:
|
|
||||||
{
|
|
||||||
return EmitExpression(dereference.Expression);
|
|
||||||
}
|
|
||||||
case BoundIdentifierNode identifier:
|
|
||||||
{
|
|
||||||
if (identifier.Namespace.HasValue)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException("There is nothing to address in another namespace");
|
|
||||||
}
|
|
||||||
|
|
||||||
return _variables.Single(x => x.Name == identifier.Name).Val;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Val EmitBinaryExpression(BoundBinaryExpressionNode binaryExpression)
|
private static Val EmitBinaryExpression(BoundBinaryExpressionNode binaryExpression)
|
||||||
@@ -1217,19 +1130,27 @@ public static class QBEGenerator
|
|||||||
if (memberAccess.Member == "count")
|
if (memberAccess.Member == "count")
|
||||||
{
|
{
|
||||||
_builder.AppendLine($" {output} =l loadl {item}");
|
_builder.AppendLine($" {output} =l loadl {item}");
|
||||||
break;
|
return new Val(output, memberAccess.Type, ValKind.Immediate);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new UnreachableException();
|
break;
|
||||||
}
|
}
|
||||||
case NubStringType:
|
case NubStringType:
|
||||||
{
|
{
|
||||||
_builder.AppendLine($" {output} =l call $nub_string_length(l {item})");
|
if (memberAccess.Member == "count")
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" {output} =l call $nub_string_length(l {item})");
|
||||||
|
return new Val(output, memberAccess.Type, ValKind.Immediate);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NubCStringType:
|
case NubCStringType:
|
||||||
{
|
{
|
||||||
_builder.AppendLine($" {output} =l call $nub_cstring_length(l {item})");
|
if (memberAccess.Member == "count")
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" {output} =l call $nub_cstring_length(l {item})");
|
||||||
|
return new Val(output, memberAccess.Type, ValKind.Immediate);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NubStructType structType:
|
case NubStructType structType:
|
||||||
@@ -1237,35 +1158,12 @@ public static class QBEGenerator
|
|||||||
var structDefinition = _definitionTable.LookupStruct(structType.Namespace, structType.Name).GetValue();
|
var structDefinition = _definitionTable.LookupStruct(structType.Namespace, structType.Name).GetValue();
|
||||||
var offset = OffsetOf(structDefinition, memberAccess.Member);
|
var offset = OffsetOf(structDefinition, memberAccess.Member);
|
||||||
|
|
||||||
var offsetName = VarName();
|
_builder.AppendLine($" {output} =l add {item}, {offset}");
|
||||||
_builder.AppendLine($" {offsetName} =l add {item}, {offset}");
|
return new Val(output, memberAccess.Type, ValKind.Pointer);
|
||||||
_builder.AppendLine($" {output} {QBEAssign(memberAccess.Type)} {QBELoad(memberAccess.Type)} {item}");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Val(output, memberAccess.Type, ValKind.Immediate);
|
throw new UnreachableException();
|
||||||
}
|
|
||||||
|
|
||||||
private static Val EmitFixedArrayInitializer(BoundFixedArrayInitializerNode fixedArrayInitializer)
|
|
||||||
{
|
|
||||||
var totalSize = SizeOf(fixedArrayInitializer.Type);
|
|
||||||
var outputName = VarName();
|
|
||||||
_builder.AppendLine($" {outputName} =l alloc8 {totalSize}");
|
|
||||||
|
|
||||||
_builder.AppendLine($" storel {fixedArrayInitializer.Capacity}, {outputName}");
|
|
||||||
|
|
||||||
var dataPtr = VarName();
|
|
||||||
_builder.AppendLine($" {dataPtr} =l add {outputName}, 8");
|
|
||||||
|
|
||||||
var dataSize = totalSize - 8;
|
|
||||||
_builder.AppendLine($" call $nub_memset(l {dataPtr}, w 0, l {dataSize})");
|
|
||||||
|
|
||||||
return new Val(outputName, fixedArrayInitializer.Type, ValKind.Immediate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Val EmitFuncCall(BoundFuncCallNode funcCall)
|
private static Val EmitFuncCall(BoundFuncCallNode funcCall)
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ using Syntax.Typing;
|
|||||||
namespace Syntax.Parsing.Node;
|
namespace Syntax.Parsing.Node;
|
||||||
|
|
||||||
public abstract record ExpressionNode(IEnumerable<Token> Tokens) : Node(Tokens);
|
public abstract record ExpressionNode(IEnumerable<Token> Tokens) : Node(Tokens);
|
||||||
public abstract record LValueNode(IEnumerable<Token> Tokens) : ExpressionNode(Tokens);
|
|
||||||
|
|
||||||
public record BinaryExpressionNode(IEnumerable<Token> Tokens, ExpressionNode Left, BinaryExpressionOperator Operator, ExpressionNode Right) : ExpressionNode(Tokens);
|
public record BinaryExpressionNode(IEnumerable<Token> Tokens, ExpressionNode Left, BinaryExpressionOperator Operator, ExpressionNode Right) : ExpressionNode(Tokens);
|
||||||
|
|
||||||
@@ -32,13 +31,12 @@ public enum UnaryExpressionOperator
|
|||||||
}
|
}
|
||||||
|
|
||||||
public record FuncCallNode(IEnumerable<Token> Tokens, ExpressionNode Expression, List<ExpressionNode> Parameters) : ExpressionNode(Tokens);
|
public record FuncCallNode(IEnumerable<Token> Tokens, ExpressionNode Expression, List<ExpressionNode> Parameters) : ExpressionNode(Tokens);
|
||||||
public record IdentifierNode(IEnumerable<Token> Tokens, Optional<string> Namespace, string Name) : LValueNode(Tokens);
|
public record IdentifierNode(IEnumerable<Token> Tokens, Optional<string> Namespace, string Name) : ExpressionNode(Tokens);
|
||||||
public record ArrayInitializerNode(IEnumerable<Token> Tokens, ExpressionNode Capacity, NubType ElementType) : ExpressionNode(Tokens);
|
public record ArrayInitializerNode(IEnumerable<Token> Tokens, ExpressionNode Capacity, NubType ElementType) : ExpressionNode(Tokens);
|
||||||
public record ArrayIndexAccessNode(IEnumerable<Token> Tokens, ExpressionNode Array, ExpressionNode Index) : LValueNode(Tokens);
|
public record ArrayIndexAccessNode(IEnumerable<Token> Tokens, ExpressionNode Array, ExpressionNode Index) : ExpressionNode(Tokens);
|
||||||
public record AnonymousFuncNode(IEnumerable<Token> Tokens, List<FuncParameter> Parameters, BlockNode Body, NubType ReturnType) : ExpressionNode(Tokens);
|
public record AnonymousFuncNode(IEnumerable<Token> Tokens, List<FuncParameter> Parameters, BlockNode Body, NubType ReturnType) : ExpressionNode(Tokens);
|
||||||
public record AddressOfNode(IEnumerable<Token> Tokens, LValueNode Expression) : ExpressionNode(Tokens);
|
public record AddressOfNode(IEnumerable<Token> Tokens, ExpressionNode Expression) : ExpressionNode(Tokens);
|
||||||
public record FixedArrayInitializerNode(IEnumerable<Token> Tokens, NubType ElementType, int Capacity) : ExpressionNode(Tokens);
|
|
||||||
public record LiteralNode(IEnumerable<Token> Tokens, string Literal, LiteralKind Kind) : ExpressionNode(Tokens);
|
public record LiteralNode(IEnumerable<Token> Tokens, string Literal, LiteralKind Kind) : ExpressionNode(Tokens);
|
||||||
public record MemberAccessNode(IEnumerable<Token> Tokens, ExpressionNode Expression, string Member) : ExpressionNode(Tokens);
|
public record MemberAccessNode(IEnumerable<Token> Tokens, ExpressionNode Expression, string Member) : ExpressionNode(Tokens);
|
||||||
public record StructInitializerNode(IEnumerable<Token> Tokens, NubStructType StructType, Dictionary<string, ExpressionNode> Initializers) : ExpressionNode(Tokens);
|
public record StructInitializerNode(IEnumerable<Token> Tokens, NubStructType StructType, Dictionary<string, ExpressionNode> Initializers) : ExpressionNode(Tokens);
|
||||||
public record DereferenceNode(IEnumerable<Token> Tokens, ExpressionNode Expression) : LValueNode(Tokens);
|
public record DereferenceNode(IEnumerable<Token> Tokens, ExpressionNode Expression) : ExpressionNode(Tokens);
|
||||||
|
|||||||
@@ -7,12 +7,9 @@ namespace Syntax.Parsing.Node;
|
|||||||
public record StatementNode(IEnumerable<Token> Tokens) : Node(Tokens);
|
public record StatementNode(IEnumerable<Token> Tokens) : Node(Tokens);
|
||||||
public record StatementExpressionNode(IEnumerable<Token> Tokens, ExpressionNode Expression) : StatementNode(Tokens);
|
public record StatementExpressionNode(IEnumerable<Token> Tokens, ExpressionNode Expression) : StatementNode(Tokens);
|
||||||
public record ReturnNode(IEnumerable<Token> Tokens, Optional<ExpressionNode> Value) : StatementNode(Tokens);
|
public record ReturnNode(IEnumerable<Token> Tokens, Optional<ExpressionNode> Value) : StatementNode(Tokens);
|
||||||
public record MemberAssignmentNode(IEnumerable<Token> Tokens, MemberAccessNode MemberAccess, ExpressionNode Value) : StatementNode(Tokens);
|
public record AssignmentNode(IEnumerable<Token> Tokens, ExpressionNode Expression, ExpressionNode Value) : StatementNode(Tokens);
|
||||||
public record IfNode(IEnumerable<Token> Tokens, ExpressionNode Condition, BlockNode Body, Optional<Variant<IfNode, BlockNode>> Else) : StatementNode(Tokens);
|
public record IfNode(IEnumerable<Token> Tokens, ExpressionNode Condition, BlockNode Body, Optional<Variant<IfNode, BlockNode>> Else) : StatementNode(Tokens);
|
||||||
public record DereferenceAssignmentNode(IEnumerable<Token> Tokens, DereferenceNode Dereference, ExpressionNode Value) : StatementNode(Tokens);
|
|
||||||
public record VariableAssignmentNode(IEnumerable<Token> Tokens, IdentifierNode Identifier, ExpressionNode Value) : StatementNode(Tokens);
|
|
||||||
public record VariableDeclarationNode(IEnumerable<Token> Tokens, string Name, NubType Type) : StatementNode(Tokens);
|
public record VariableDeclarationNode(IEnumerable<Token> Tokens, string Name, NubType Type) : StatementNode(Tokens);
|
||||||
public record ContinueNode(IEnumerable<Token> Tokens) : StatementNode(Tokens);
|
public record ContinueNode(IEnumerable<Token> Tokens) : StatementNode(Tokens);
|
||||||
public record BreakNode(IEnumerable<Token> Tokens) : StatementNode(Tokens);
|
public record BreakNode(IEnumerable<Token> Tokens) : StatementNode(Tokens);
|
||||||
public record ArrayIndexAssignmentNode(IEnumerable<Token> Tokens, ArrayIndexAccessNode ArrayIndexAccess, ExpressionNode Value) : StatementNode(Tokens);
|
|
||||||
public record WhileNode(IEnumerable<Token> Tokens, ExpressionNode Condition, BlockNode Body) : StatementNode(Tokens);
|
public record WhileNode(IEnumerable<Token> Tokens, ExpressionNode Condition, BlockNode Body) : StatementNode(Tokens);
|
||||||
|
|||||||
@@ -222,46 +222,10 @@ public static class Parser
|
|||||||
{
|
{
|
||||||
var expr = ParseExpression();
|
var expr = ParseExpression();
|
||||||
|
|
||||||
if (Peek().TryGetValue(out var token))
|
if (TryExpectSymbol(Symbol.Assign))
|
||||||
{
|
{
|
||||||
if (token is SymbolToken symbol)
|
var value = ParseExpression();
|
||||||
{
|
return new AssignmentNode(GetTokensForNode(startIndex), expr, value);
|
||||||
switch (symbol.Symbol)
|
|
||||||
{
|
|
||||||
case Symbol.Assign:
|
|
||||||
{
|
|
||||||
switch (expr)
|
|
||||||
{
|
|
||||||
case MemberAccessNode memberAccess:
|
|
||||||
{
|
|
||||||
Next();
|
|
||||||
var value = ParseExpression();
|
|
||||||
return new MemberAssignmentNode(GetTokensForNode(startIndex), memberAccess, value);
|
|
||||||
}
|
|
||||||
case ArrayIndexAccessNode arrayIndexAccess:
|
|
||||||
{
|
|
||||||
Next();
|
|
||||||
var value = ParseExpression();
|
|
||||||
return new ArrayIndexAssignmentNode(GetTokensForNode(startIndex), arrayIndexAccess, value);
|
|
||||||
}
|
|
||||||
case IdentifierNode identifier:
|
|
||||||
{
|
|
||||||
Next();
|
|
||||||
var value = ParseExpression();
|
|
||||||
return new VariableAssignmentNode(GetTokensForNode(startIndex), identifier, value);
|
|
||||||
}
|
|
||||||
case DereferenceNode dereference:
|
|
||||||
{
|
|
||||||
Next();
|
|
||||||
var value = ParseExpression();
|
|
||||||
return new DereferenceAssignmentNode(GetTokensForNode(startIndex), dereference, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new StatementExpressionNode(GetTokensForNode(startIndex), expr);
|
return new StatementExpressionNode(GetTokensForNode(startIndex), expr);
|
||||||
@@ -471,20 +435,6 @@ public static class Parser
|
|||||||
expr = expression;
|
expr = expression;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Symbol.Ampersand:
|
|
||||||
{
|
|
||||||
var expression = ParsePrimaryExpression();
|
|
||||||
if (expression is not LValueNode lValue)
|
|
||||||
{
|
|
||||||
throw new ParseException(Diagnostic
|
|
||||||
.Error("& symbol can only be used on lvalues")
|
|
||||||
.At(expression)
|
|
||||||
.Build());
|
|
||||||
}
|
|
||||||
|
|
||||||
expr = new AddressOfNode(GetTokensForNode(startIndex), lValue);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Symbol.Minus:
|
case Symbol.Minus:
|
||||||
{
|
{
|
||||||
var expression = ParsePrimaryExpression();
|
var expression = ParsePrimaryExpression();
|
||||||
@@ -499,35 +449,10 @@ public static class Parser
|
|||||||
}
|
}
|
||||||
case Symbol.OpenBracket:
|
case Symbol.OpenBracket:
|
||||||
{
|
{
|
||||||
if (Peek().TryGetValue(out var capacityToken) && capacityToken is LiteralToken { Kind: LiteralKind.Integer } literalToken)
|
var capacity = ParseExpression();
|
||||||
{
|
ExpectSymbol(Symbol.CloseBracket);
|
||||||
var capacity = int.Parse(literalToken.Value);
|
var type = ParseType();
|
||||||
Next();
|
expr = new ArrayInitializerNode(GetTokensForNode(startIndex), capacity, type);
|
||||||
ExpectSymbol(Symbol.CloseBracket);
|
|
||||||
var elementType = ParseType();
|
|
||||||
|
|
||||||
if (capacity > 0)
|
|
||||||
{
|
|
||||||
expr = new FixedArrayInitializerNode(GetTokensForNode(startIndex), elementType, capacity);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new ParseException(Diagnostic
|
|
||||||
.Error("Fixed array size must be a positive integer")
|
|
||||||
.WithHelp("Use a positive integer literal for the array size")
|
|
||||||
.At(literalToken)
|
|
||||||
.Build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var capacity = ParseExpression();
|
|
||||||
ExpectSymbol(Symbol.CloseBracket);
|
|
||||||
var type = ParseType();
|
|
||||||
|
|
||||||
expr = new ArrayInitializerNode(GetTokensForNode(startIndex), capacity, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Symbol.Alloc:
|
case Symbol.Alloc:
|
||||||
@@ -583,6 +508,12 @@ public static class Parser
|
|||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
if (TryExpectSymbol(Symbol.Ampersand))
|
||||||
|
{
|
||||||
|
expr = new AddressOfNode(GetTokensForNode(startIndex), expr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (TryExpectSymbol(Symbol.Caret))
|
if (TryExpectSymbol(Symbol.Caret))
|
||||||
{
|
{
|
||||||
expr = new DereferenceNode(GetTokensForNode(startIndex), expr);
|
expr = new DereferenceNode(GetTokensForNode(startIndex), expr);
|
||||||
|
|||||||
@@ -124,26 +124,23 @@ public static class Binder
|
|||||||
{
|
{
|
||||||
return node switch
|
return node switch
|
||||||
{
|
{
|
||||||
ArrayIndexAssignmentNode statement => BindArrayIndex(statement),
|
AssignmentNode statement => BindAssignment(statement),
|
||||||
BreakNode statement => BindBreak(statement),
|
BreakNode statement => BindBreak(statement),
|
||||||
ContinueNode statement => BindContinue(statement),
|
ContinueNode statement => BindContinue(statement),
|
||||||
DereferenceAssignmentNode statement => BindDereferenceAssignment(statement),
|
|
||||||
IfNode statement => BindIf(statement),
|
IfNode statement => BindIf(statement),
|
||||||
MemberAssignmentNode statement => BindMemberAssignment(statement),
|
|
||||||
ReturnNode statement => BindReturn(statement),
|
ReturnNode statement => BindReturn(statement),
|
||||||
StatementExpressionNode statement => BindStatementExpression(statement),
|
StatementExpressionNode statement => BindStatementExpression(statement),
|
||||||
VariableAssignmentNode statement => BindVariableAssignment(statement),
|
|
||||||
VariableDeclarationNode statement => BindVariableDeclaration(statement),
|
VariableDeclarationNode statement => BindVariableDeclaration(statement),
|
||||||
WhileNode statement => BindWhile(statement),
|
WhileNode statement => BindWhile(statement),
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(node))
|
_ => throw new ArgumentOutOfRangeException(nameof(node))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BoundArrayIndexAssignmentNode BindArrayIndex(ArrayIndexAssignmentNode statement)
|
private static BoundStatementNode BindAssignment(AssignmentNode statement)
|
||||||
{
|
{
|
||||||
var boundArrayIndex = BindArrayIndexAccess(statement.ArrayIndexAccess);
|
var expression = BindExpression(statement.Expression);
|
||||||
var elementType = ((NubArrayType)boundArrayIndex.Type).ElementType;
|
var value = BindExpression(statement.Value, expression.Type);
|
||||||
return new BoundArrayIndexAssignmentNode(statement.Tokens, boundArrayIndex, BindExpression(statement.Value, elementType));
|
return new BoundAssignmentNode(statement.Tokens, expression, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BoundBreakNode BindBreak(BreakNode statement)
|
private static BoundBreakNode BindBreak(BreakNode statement)
|
||||||
@@ -156,13 +153,6 @@ public static class Binder
|
|||||||
return new BoundContinueNode(statement.Tokens);
|
return new BoundContinueNode(statement.Tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BoundDereferenceAssignmentNode BindDereferenceAssignment(DereferenceAssignmentNode statement)
|
|
||||||
{
|
|
||||||
var boundDereference = BindDereference(statement.Dereference);
|
|
||||||
var dereferenceBaseType = ((NubPointerType)boundDereference.Type).BaseType;
|
|
||||||
return new BoundDereferenceAssignmentNode(statement.Tokens, boundDereference, BindExpression(statement.Value, dereferenceBaseType));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static BoundIfNode BindIf(IfNode statement)
|
private static BoundIfNode BindIf(IfNode statement)
|
||||||
{
|
{
|
||||||
var elseStatement = Optional.Empty<Variant<BoundIfNode, BoundBlockNode>>();
|
var elseStatement = Optional.Empty<Variant<BoundIfNode, BoundBlockNode>>();
|
||||||
@@ -179,13 +169,6 @@ public static class Binder
|
|||||||
return new BoundIfNode(statement.Tokens, BindExpression(statement.Condition, NubPrimitiveType.Bool), BindBlock(statement.Body), elseStatement);
|
return new BoundIfNode(statement.Tokens, BindExpression(statement.Condition, NubPrimitiveType.Bool), BindBlock(statement.Body), elseStatement);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BoundMemberAssignmentNode BindMemberAssignment(MemberAssignmentNode statement)
|
|
||||||
{
|
|
||||||
var boundMemberAccess = BindMemberAccess(statement.MemberAccess);
|
|
||||||
var elementType = ((NubArrayType)boundMemberAccess.Type).ElementType;
|
|
||||||
return new BoundMemberAssignmentNode(statement.Tokens, boundMemberAccess, BindExpression(statement.Value, elementType));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static BoundReturnNode BindReturn(ReturnNode statement)
|
private static BoundReturnNode BindReturn(ReturnNode statement)
|
||||||
{
|
{
|
||||||
var value = Optional.Empty<BoundExpressionNode>();
|
var value = Optional.Empty<BoundExpressionNode>();
|
||||||
@@ -203,12 +186,6 @@ public static class Binder
|
|||||||
return new BoundStatementExpressionNode(statement.Tokens, BindExpression(statement.Expression));
|
return new BoundStatementExpressionNode(statement.Tokens, BindExpression(statement.Expression));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BoundVariableAssignmentNode BindVariableAssignment(VariableAssignmentNode statement)
|
|
||||||
{
|
|
||||||
var variableType = _variables[statement.Identifier.Name];
|
|
||||||
return new BoundVariableAssignmentNode(statement.Tokens, BindIdentifier(statement.Identifier), BindExpression(statement.Value, variableType));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static BoundVariableDeclarationNode BindVariableDeclaration(VariableDeclarationNode statement)
|
private static BoundVariableDeclarationNode BindVariableDeclaration(VariableDeclarationNode statement)
|
||||||
{
|
{
|
||||||
_variables[statement.Name] = statement.Type;
|
_variables[statement.Name] = statement.Type;
|
||||||
@@ -230,7 +207,6 @@ public static class Binder
|
|||||||
ArrayInitializerNode expression => BindArrayInitializer(expression),
|
ArrayInitializerNode expression => BindArrayInitializer(expression),
|
||||||
BinaryExpressionNode expression => BindBinaryExpression(expression),
|
BinaryExpressionNode expression => BindBinaryExpression(expression),
|
||||||
DereferenceNode expression => BindDereference(expression),
|
DereferenceNode expression => BindDereference(expression),
|
||||||
FixedArrayInitializerNode expression => BindFixedArrayInitializer(expression),
|
|
||||||
FuncCallNode expression => BindFuncCall(expression),
|
FuncCallNode expression => BindFuncCall(expression),
|
||||||
IdentifierNode expression => BindIdentifier(expression),
|
IdentifierNode expression => BindIdentifier(expression),
|
||||||
LiteralNode expression => BindLiteral(expression, expectedType),
|
LiteralNode expression => BindLiteral(expression, expectedType),
|
||||||
@@ -243,7 +219,7 @@ public static class Binder
|
|||||||
|
|
||||||
private static BoundAddressOfNode BindAddressOf(AddressOfNode expression)
|
private static BoundAddressOfNode BindAddressOf(AddressOfNode expression)
|
||||||
{
|
{
|
||||||
var inner = (BoundLValueNode)BindExpression(expression.Expression);
|
var inner = BindExpression(expression.Expression);
|
||||||
return new BoundAddressOfNode(expression.Tokens, new NubPointerType(inner.Type), inner);
|
return new BoundAddressOfNode(expression.Tokens, new NubPointerType(inner.Type), inner);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,11 +267,6 @@ public static class Binder
|
|||||||
return new BoundDereferenceNode(expression.Tokens, dereferencedType, boundExpression);
|
return new BoundDereferenceNode(expression.Tokens, dereferencedType, boundExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BoundFixedArrayInitializerNode BindFixedArrayInitializer(FixedArrayInitializerNode expression)
|
|
||||||
{
|
|
||||||
return new BoundFixedArrayInitializerNode(expression.Tokens, new NubArrayType(expression.ElementType), expression.ElementType, expression.Capacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static BoundFuncCallNode BindFuncCall(FuncCallNode expression)
|
private static BoundFuncCallNode BindFuncCall(FuncCallNode expression)
|
||||||
{
|
{
|
||||||
var boundExpression = BindExpression(expression.Expression);
|
var boundExpression = BindExpression(expression.Expression);
|
||||||
|
|||||||
@@ -5,17 +5,15 @@ using Syntax.Tokenization;
|
|||||||
namespace Syntax.Typing.BoundNode;
|
namespace Syntax.Typing.BoundNode;
|
||||||
|
|
||||||
public abstract record BoundExpressionNode(IEnumerable<Token> Tokens, NubType Type) : BoundNode(Tokens);
|
public abstract record BoundExpressionNode(IEnumerable<Token> Tokens, NubType Type) : BoundNode(Tokens);
|
||||||
public abstract record BoundLValueNode(IEnumerable<Token> Tokens, NubType Type) : BoundExpressionNode(Tokens, Type);
|
|
||||||
public record BoundBinaryExpressionNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Left, BinaryExpressionOperator Operator, BoundExpressionNode Right) : BoundExpressionNode(Tokens, Type);
|
public record BoundBinaryExpressionNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Left, BinaryExpressionOperator Operator, BoundExpressionNode Right) : BoundExpressionNode(Tokens, Type);
|
||||||
public record BoundUnaryExpressionNode(IEnumerable<Token> Tokens, NubType Type, UnaryExpressionOperator Operator, BoundExpressionNode Operand) : BoundExpressionNode(Tokens, Type);
|
public record BoundUnaryExpressionNode(IEnumerable<Token> Tokens, NubType Type, UnaryExpressionOperator Operator, BoundExpressionNode Operand) : BoundExpressionNode(Tokens, Type);
|
||||||
public record BoundFuncCallNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Expression, List<BoundExpressionNode> Parameters) : BoundExpressionNode(Tokens, Type);
|
public record BoundFuncCallNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Expression, List<BoundExpressionNode> Parameters) : BoundExpressionNode(Tokens, Type);
|
||||||
public record BoundIdentifierNode(IEnumerable<Token> Tokens, NubType Type, Optional<string> Namespace, string Name) : BoundLValueNode(Tokens, Type);
|
public record BoundIdentifierNode(IEnumerable<Token> Tokens, NubType Type, Optional<string> Namespace, string Name) : BoundExpressionNode(Tokens, Type);
|
||||||
public record BoundArrayInitializerNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Capacity, NubType ElementType) : BoundExpressionNode(Tokens, Type);
|
public record BoundArrayInitializerNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Capacity, NubType ElementType) : BoundExpressionNode(Tokens, Type);
|
||||||
public record BoundArrayIndexAccessNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Array, BoundExpressionNode Index) : BoundLValueNode(Tokens, Type);
|
public record BoundArrayIndexAccessNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Array, BoundExpressionNode Index) : BoundExpressionNode(Tokens, Type);
|
||||||
public record BoundAnonymousFuncNode(IEnumerable<Token> Tokens, NubType Type, List<BoundFuncParameter> Parameters, BoundBlockNode Body, NubType ReturnType) : BoundExpressionNode(Tokens, Type);
|
public record BoundAnonymousFuncNode(IEnumerable<Token> Tokens, NubType Type, List<BoundFuncParameter> Parameters, BoundBlockNode Body, NubType ReturnType) : BoundExpressionNode(Tokens, Type);
|
||||||
public record BoundAddressOfNode(IEnumerable<Token> Tokens, NubType Type, BoundLValueNode Expression) : BoundExpressionNode(Tokens, Type);
|
public record BoundAddressOfNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Expression) : BoundExpressionNode(Tokens, Type);
|
||||||
public record BoundFixedArrayInitializerNode(IEnumerable<Token> Tokens, NubType Type, NubType ElementType, int Capacity) : BoundExpressionNode(Tokens, Type);
|
|
||||||
public record BoundLiteralNode(IEnumerable<Token> Tokens, NubType Type, string Literal, LiteralKind Kind) : BoundExpressionNode(Tokens, Type);
|
public record BoundLiteralNode(IEnumerable<Token> Tokens, NubType Type, string Literal, LiteralKind Kind) : BoundExpressionNode(Tokens, Type);
|
||||||
public record BoundMemberAccessNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Expression, string Member) : BoundExpressionNode(Tokens, Type);
|
public record BoundMemberAccessNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Expression, string Member) : BoundExpressionNode(Tokens, Type);
|
||||||
public record BoundStructInitializerNode(IEnumerable<Token> Tokens, NubType Type, NubStructType StructType, Dictionary<string, BoundExpressionNode> Initializers) : BoundExpressionNode(Tokens, Type);
|
public record BoundStructInitializerNode(IEnumerable<Token> Tokens, NubType Type, NubStructType StructType, Dictionary<string, BoundExpressionNode> Initializers) : BoundExpressionNode(Tokens, Type);
|
||||||
public record BoundDereferenceNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Expression) : BoundLValueNode(Tokens, Type);
|
public record BoundDereferenceNode(IEnumerable<Token> Tokens, NubType Type, BoundExpressionNode Expression) : BoundExpressionNode(Tokens, Type);
|
||||||
|
|||||||
@@ -6,12 +6,9 @@ namespace Syntax.Typing.BoundNode;
|
|||||||
public record BoundStatementNode(IEnumerable<Token> Tokens) : BoundNode(Tokens);
|
public record BoundStatementNode(IEnumerable<Token> Tokens) : BoundNode(Tokens);
|
||||||
public record BoundStatementExpressionNode(IEnumerable<Token> Tokens, BoundExpressionNode Expression) : BoundStatementNode(Tokens);
|
public record BoundStatementExpressionNode(IEnumerable<Token> Tokens, BoundExpressionNode Expression) : BoundStatementNode(Tokens);
|
||||||
public record BoundReturnNode(IEnumerable<Token> Tokens, Optional<BoundExpressionNode> Value) : BoundStatementNode(Tokens);
|
public record BoundReturnNode(IEnumerable<Token> Tokens, Optional<BoundExpressionNode> Value) : BoundStatementNode(Tokens);
|
||||||
public record BoundMemberAssignmentNode(IEnumerable<Token> Tokens, BoundMemberAccessNode MemberAccess, BoundExpressionNode Value) : BoundStatementNode(Tokens);
|
public record BoundAssignmentNode(IEnumerable<Token> Tokens, BoundExpressionNode Expression, BoundExpressionNode Value) : BoundStatementNode(Tokens);
|
||||||
public record BoundIfNode(IEnumerable<Token> Tokens, BoundExpressionNode Condition, BoundBlockNode Body, Optional<Variant<BoundIfNode, BoundBlockNode>> Else) : BoundStatementNode(Tokens);
|
public record BoundIfNode(IEnumerable<Token> Tokens, BoundExpressionNode Condition, BoundBlockNode Body, Optional<Variant<BoundIfNode, BoundBlockNode>> Else) : BoundStatementNode(Tokens);
|
||||||
public record BoundDereferenceAssignmentNode(IEnumerable<Token> Tokens, BoundDereferenceNode Dereference, BoundExpressionNode Value) : BoundStatementNode(Tokens);
|
|
||||||
public record BoundVariableAssignmentNode(IEnumerable<Token> Tokens, BoundIdentifierNode Identifier, BoundExpressionNode Value) : BoundStatementNode(Tokens);
|
|
||||||
public record BoundVariableDeclarationNode(IEnumerable<Token> Tokens, string Name, NubType Type) : BoundStatementNode(Tokens);
|
public record BoundVariableDeclarationNode(IEnumerable<Token> Tokens, string Name, NubType Type) : BoundStatementNode(Tokens);
|
||||||
public record BoundContinueNode(IEnumerable<Token> Tokens) : BoundStatementNode(Tokens);
|
public record BoundContinueNode(IEnumerable<Token> Tokens) : BoundStatementNode(Tokens);
|
||||||
public record BoundBreakNode(IEnumerable<Token> Tokens) : BoundStatementNode(Tokens);
|
public record BoundBreakNode(IEnumerable<Token> Tokens) : BoundStatementNode(Tokens);
|
||||||
public record BoundArrayIndexAssignmentNode(IEnumerable<Token> Tokens, BoundArrayIndexAccessNode ArrayIndexAccess, BoundExpressionNode Value) : BoundStatementNode(Tokens);
|
|
||||||
public record BoundWhileNode(IEnumerable<Token> Tokens, BoundExpressionNode Condition, BoundBlockNode Body) : BoundStatementNode(Tokens);
|
public record BoundWhileNode(IEnumerable<Token> Tokens, BoundExpressionNode Condition, BoundBlockNode Body) : BoundStatementNode(Tokens);
|
||||||
|
|||||||
Reference in New Issue
Block a user