...
This commit is contained in:
@@ -1,19 +1,30 @@
|
||||
// c
|
||||
extern func puts(text: cstring)
|
||||
|
||||
struct Human {
|
||||
interface Printable
|
||||
{
|
||||
func print()
|
||||
}
|
||||
|
||||
struct Human : Printable
|
||||
{
|
||||
name: cstring
|
||||
age: u32
|
||||
|
||||
func print()
|
||||
{
|
||||
puts(this.name)
|
||||
}
|
||||
}
|
||||
|
||||
func main(args: []cstring): i64
|
||||
{
|
||||
let x: Human = struct {
|
||||
let x: Printable = struct Human {
|
||||
name = "Oliver"
|
||||
age = 23
|
||||
}
|
||||
|
||||
puts(x.name)
|
||||
x.print()
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ public class QBEGenerator
|
||||
_writer.Indented($"{store} {value}, {destination}");
|
||||
}
|
||||
|
||||
private Val EmitLoad(TypeNode type, string from)
|
||||
private string EmitLoad(TypeNode type, string from)
|
||||
{
|
||||
string load;
|
||||
|
||||
@@ -164,7 +164,7 @@ public class QBEGenerator
|
||||
|
||||
_writer.Indented($"{into} {QBEAssign(type)} {load} {from}");
|
||||
|
||||
return new Val(into, type, ValKind.Direct);
|
||||
return into;
|
||||
}
|
||||
|
||||
private void EmitMemcpy(string source, string destination, string length)
|
||||
@@ -203,7 +203,7 @@ public class QBEGenerator
|
||||
{
|
||||
case ArrayInitializerNode arrayInitializer:
|
||||
{
|
||||
EmitStore(source.Type, EmitUnwrap(EmitArrayInitializer(arrayInitializer)), destinationPointer);
|
||||
EmitStore(source.Type, EmitArrayInitializer(arrayInitializer), destinationPointer);
|
||||
return true;
|
||||
}
|
||||
case StructInitializerNode structInitializer:
|
||||
@@ -218,7 +218,7 @@ public class QBEGenerator
|
||||
}
|
||||
case LiteralNode { Kind: LiteralKind.String } literal:
|
||||
{
|
||||
EmitStore(source.Type, EmitUnwrap(EmitLiteral(literal)), destinationPointer);
|
||||
EmitStore(source.Type, EmitLiteral(literal), destinationPointer);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -368,7 +368,7 @@ public class QBEGenerator
|
||||
|
||||
foreach (var parameter in funcDef.Signature.Parameters)
|
||||
{
|
||||
scope.Declare(parameter.Name, new Val("%" + parameter.Name, parameter.Type, ValKind.Direct));
|
||||
scope.Declare(parameter.Name, new Val("%" + parameter.Name, parameter.Type, false));
|
||||
}
|
||||
|
||||
EmitBlock(funcDef.Body, scope);
|
||||
@@ -410,10 +410,10 @@ public class QBEGenerator
|
||||
|
||||
var scope = new Scope();
|
||||
|
||||
scope.Declare("this", new Val("%this", structDef.Type, ValKind.Direct));
|
||||
scope.Declare("this", new Val("%this", structDef.Type, false));
|
||||
foreach (var parameter in function.Signature.Parameters)
|
||||
{
|
||||
scope.Declare(parameter.Name, new Val("%" + parameter.Name, parameter.Type, ValKind.Direct));
|
||||
scope.Declare(parameter.Name, new Val("%" + parameter.Name, parameter.Type, false));
|
||||
}
|
||||
|
||||
EmitBlock(function.Body, scope);
|
||||
@@ -531,12 +531,12 @@ public class QBEGenerator
|
||||
|
||||
private void EmitAssignment(AssignmentNode assignment)
|
||||
{
|
||||
var destination = EmitExpression(assignment.Target);
|
||||
if (destination.Kind != ValKind.Pointer)
|
||||
if (!assignment.Target.IsLValue)
|
||||
{
|
||||
throw new UnreachableException("Destination of assignment must be a pointer. This should be caught in the type checker");
|
||||
throw new UnreachableException("Destination of assignment must be an lvalue. This should have been caught in the type checker");
|
||||
}
|
||||
|
||||
var destination = EmitExpression(assignment.Target);
|
||||
EmitCopyIntoOrInitialize(assignment.Value, destination.Name);
|
||||
}
|
||||
|
||||
@@ -600,7 +600,7 @@ public class QBEGenerator
|
||||
EmitStore(variableDeclaration.Assignment.Value.Type, value, name);
|
||||
}
|
||||
|
||||
Scope.Declare(variableDeclaration.Name, new Val(name, variableDeclaration.Type, ValKind.Pointer));
|
||||
Scope.Declare(variableDeclaration.Name, new Val(name, variableDeclaration.Type, true));
|
||||
}
|
||||
|
||||
private void EmitWhile(WhileNode whileStatement)
|
||||
@@ -626,7 +626,7 @@ public class QBEGenerator
|
||||
|
||||
private Val EmitExpression(ExpressionNode expression)
|
||||
{
|
||||
return expression switch
|
||||
var value = expression switch
|
||||
{
|
||||
ArrayInitializerNode arrayInitializer => EmitArrayInitializer(arrayInitializer),
|
||||
StructInitializerNode structInitializer => EmitStructInitializer(structInitializer),
|
||||
@@ -646,9 +646,11 @@ public class QBEGenerator
|
||||
ArrayIndexAccessNode arrayIndex => EmitArrayIndexAccess(arrayIndex),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(expression))
|
||||
};
|
||||
|
||||
return new Val(value, expression.Type, expression.IsLValue);
|
||||
}
|
||||
|
||||
private Val EmitArrayIndexAccess(ArrayIndexAccessNode arrayIndexAccess)
|
||||
private string EmitArrayIndexAccess(ArrayIndexAccessNode arrayIndexAccess)
|
||||
{
|
||||
var array = EmitUnwrap(EmitExpression(arrayIndexAccess.Target));
|
||||
var index = EmitUnwrap(EmitExpression(arrayIndexAccess.Index));
|
||||
@@ -661,7 +663,7 @@ public class QBEGenerator
|
||||
_writer.Indented($"{pointer} =l mul {index}, {SizeOf(elementType)}");
|
||||
_writer.Indented($"{pointer} =l add {pointer}, 8");
|
||||
_writer.Indented($"{pointer} =l add {array}, {pointer}");
|
||||
return new Val(pointer, arrayIndexAccess.Type, ValKind.Pointer);
|
||||
return pointer;
|
||||
}
|
||||
|
||||
private void EmitArraysCheck(string array, string index)
|
||||
@@ -688,7 +690,7 @@ public class QBEGenerator
|
||||
_writer.Indented(notOobLabel);
|
||||
}
|
||||
|
||||
private Val EmitArrayInitializer(ArrayInitializerNode arrayInitializer)
|
||||
private string EmitArrayInitializer(ArrayInitializerNode arrayInitializer)
|
||||
{
|
||||
var capacity = EmitUnwrap(EmitExpression(arrayInitializer.Capacity));
|
||||
var elementSize = SizeOf(arrayInitializer.ElementType);
|
||||
@@ -706,26 +708,26 @@ public class QBEGenerator
|
||||
_writer.Indented($"{dataPointer} =l add {arrayPointer}, 8");
|
||||
_writer.Indented($"call $nub_memset(l {dataPointer}, w 0, l {capacityInBytes})");
|
||||
|
||||
return new Val(arrayPointer, arrayInitializer.Type, ValKind.Direct);
|
||||
return arrayPointer;
|
||||
}
|
||||
|
||||
private Val EmitDereference(DereferenceNode dereference)
|
||||
private string EmitDereference(DereferenceNode dereference)
|
||||
{
|
||||
return EmitLoad(dereference.Type, EmitUnwrap(EmitExpression(dereference.Expression)));
|
||||
}
|
||||
|
||||
private Val EmitAddressOf(AddressOfNode addressOf)
|
||||
private string EmitAddressOf(AddressOfNode addressOf)
|
||||
{
|
||||
var value = EmitExpression(addressOf.Expression);
|
||||
if (value.Kind != ValKind.Pointer)
|
||||
if (!value.IsLValue)
|
||||
{
|
||||
throw new UnreachableException("Tried to take address of non-pointer type. This should have been caught in the type checker");
|
||||
throw new UnreachableException("Tried to take address of rvalue. This should have been caught in the type checker");
|
||||
}
|
||||
|
||||
return new Val(value.Name, addressOf.Type, ValKind.Direct);
|
||||
return value.Name;
|
||||
}
|
||||
|
||||
private Val EmitBinaryExpression(BinaryExpressionNode binaryExpression)
|
||||
private string EmitBinaryExpression(BinaryExpressionNode binaryExpression)
|
||||
{
|
||||
var left = EmitUnwrap(EmitExpression(binaryExpression.Left));
|
||||
var right = EmitUnwrap(EmitExpression(binaryExpression.Right));
|
||||
@@ -735,7 +737,7 @@ public class QBEGenerator
|
||||
var instruction = EmitBinaryInstructionFor(binaryExpression.Operator, binaryExpression.Left.Type, left, right);
|
||||
|
||||
_writer.Indented($"{outputName} {QBEAssign(binaryExpression.Left.Type)} {instruction} {left}, {right}");
|
||||
return new Val(outputName, binaryExpression.Type, ValKind.Direct);
|
||||
return outputName;
|
||||
}
|
||||
|
||||
private string EmitBinaryInstructionFor(BinaryOperator op, TypeNode type, string left, string right)
|
||||
@@ -832,24 +834,24 @@ public class QBEGenerator
|
||||
};
|
||||
}
|
||||
|
||||
private Val EmitExternFuncIdent(ExternFuncIdentNode externFuncIdent)
|
||||
private string EmitExternFuncIdent(ExternFuncIdentNode externFuncIdent)
|
||||
{
|
||||
var func = _definitionTable.LookupExternFunc(externFuncIdent.Name);
|
||||
return new Val(ExternFuncName(func), externFuncIdent.Type, ValKind.Direct);
|
||||
return ExternFuncName(func);
|
||||
}
|
||||
|
||||
private Val EmitLocalFuncIdent(LocalFuncIdentNode localFuncIdent)
|
||||
private string EmitLocalFuncIdent(LocalFuncIdentNode localFuncIdent)
|
||||
{
|
||||
var func = _definitionTable.LookupLocalFunc(localFuncIdent.Name);
|
||||
return new Val(LocalFuncName(func), localFuncIdent.Type, ValKind.Direct);
|
||||
return LocalFuncName(func);
|
||||
}
|
||||
|
||||
private Val EmitVariableIdent(VariableIdentNode variableIdent)
|
||||
private string EmitVariableIdent(VariableIdentNode variableIdent)
|
||||
{
|
||||
return Scope.Lookup(variableIdent.Name);
|
||||
return variableIdent.Name;
|
||||
}
|
||||
|
||||
private Val EmitLiteral(LiteralNode literal)
|
||||
private string EmitLiteral(LiteralNode literal)
|
||||
{
|
||||
switch (literal.Kind)
|
||||
{
|
||||
@@ -859,19 +861,19 @@ public class QBEGenerator
|
||||
{
|
||||
var value = float.Parse(literal.Value, CultureInfo.InvariantCulture);
|
||||
var bits = BitConverter.SingleToInt32Bits(value);
|
||||
return new Val(bits.ToString(), literal.Type, ValKind.Direct);
|
||||
return bits.ToString();
|
||||
}
|
||||
|
||||
if (literal.Type is FloatTypeNode { Width: 64 })
|
||||
{
|
||||
var value = double.Parse(literal.Value, CultureInfo.InvariantCulture);
|
||||
var bits = BitConverter.DoubleToInt64Bits(value);
|
||||
return new Val(bits.ToString(), literal.Type, ValKind.Direct);
|
||||
return bits.ToString();
|
||||
}
|
||||
|
||||
if (literal.Type is IntTypeNode)
|
||||
{
|
||||
return new Val(literal.Value, literal.Type, ValKind.Direct);
|
||||
return literal.Value;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -880,21 +882,21 @@ public class QBEGenerator
|
||||
{
|
||||
if (literal.Type is IntTypeNode)
|
||||
{
|
||||
return new Val(literal.Value.Split(".").First(), literal.Type, ValKind.Direct);
|
||||
return literal.Value.Split(".").First();
|
||||
}
|
||||
|
||||
if (literal.Type is FloatTypeNode { Width: 32 })
|
||||
{
|
||||
var value = float.Parse(literal.Value, CultureInfo.InvariantCulture);
|
||||
var bits = BitConverter.SingleToInt32Bits(value);
|
||||
return new Val(bits.ToString(), literal.Type, ValKind.Direct);
|
||||
return bits.ToString();
|
||||
}
|
||||
|
||||
if (literal.Type is FloatTypeNode { Width: 64 })
|
||||
{
|
||||
var value = double.Parse(literal.Value, CultureInfo.InvariantCulture);
|
||||
var bits = BitConverter.DoubleToInt64Bits(value);
|
||||
return new Val(bits.ToString(), literal.Type, ValKind.Direct);
|
||||
return bits.ToString();
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -905,14 +907,14 @@ public class QBEGenerator
|
||||
{
|
||||
var stringLiteral = new StringLiteral(literal.Value, StringName());
|
||||
_stringLiterals.Add(stringLiteral);
|
||||
return new Val(stringLiteral.Name, literal.Type, ValKind.Direct);
|
||||
return stringLiteral.Name;
|
||||
}
|
||||
|
||||
if (literal.Type is CStringTypeNode)
|
||||
{
|
||||
var cStringLiteral = new CStringLiteral(literal.Value, CStringName());
|
||||
_cStringLiterals.Add(cStringLiteral);
|
||||
return new Val(cStringLiteral.Name, literal.Type, ValKind.Direct);
|
||||
return cStringLiteral.Name;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -921,7 +923,7 @@ public class QBEGenerator
|
||||
{
|
||||
if (literal.Type is BoolTypeNode)
|
||||
{
|
||||
return new Val(bool.Parse(literal.Value) ? "1" : "0", literal.Type, ValKind.Direct);
|
||||
return bool.Parse(literal.Value) ? "1" : "0";
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -931,7 +933,7 @@ public class QBEGenerator
|
||||
throw new NotSupportedException($"Cannot create literal of kind '{literal.Kind}' for type {literal.Type}");
|
||||
}
|
||||
|
||||
private Val EmitStructInitializer(StructInitializerNode structInitializer, string? destination = null)
|
||||
private string EmitStructInitializer(StructInitializerNode structInitializer, string? destination = null)
|
||||
{
|
||||
var structDef = _definitionTable.LookupStruct(structInitializer.StructType.Name);
|
||||
|
||||
@@ -959,10 +961,10 @@ public class QBEGenerator
|
||||
EmitCopyIntoOrInitialize(valueExpression, offset);
|
||||
}
|
||||
|
||||
return new Val(destination, structInitializer.StructType, ValKind.Direct);
|
||||
return destination;
|
||||
}
|
||||
|
||||
private Val EmitUnaryExpression(UnaryExpressionNode unaryExpression)
|
||||
private string EmitUnaryExpression(UnaryExpressionNode unaryExpression)
|
||||
{
|
||||
var operand = EmitUnwrap(EmitExpression(unaryExpression.Operand));
|
||||
var outputName = TmpName();
|
||||
@@ -975,16 +977,16 @@ public class QBEGenerator
|
||||
{
|
||||
case IntTypeNode { Signed: true, Width: 64 }:
|
||||
_writer.Indented($"{outputName} =l neg {operand}");
|
||||
return new Val(outputName, unaryExpression.Type, ValKind.Direct);
|
||||
return outputName;
|
||||
case IntTypeNode { Signed: true, Width: 8 or 16 or 32 }:
|
||||
_writer.Indented($"{outputName} =w neg {operand}");
|
||||
return new Val(outputName, unaryExpression.Type, ValKind.Direct);
|
||||
return outputName;
|
||||
case FloatTypeNode { Width: 64 }:
|
||||
_writer.Indented($"{outputName} =d neg {operand}");
|
||||
return new Val(outputName, unaryExpression.Type, ValKind.Direct);
|
||||
return outputName;
|
||||
case FloatTypeNode { Width: 32 }:
|
||||
_writer.Indented($"{outputName} =s neg {operand}");
|
||||
return new Val(outputName, unaryExpression.Type, ValKind.Direct);
|
||||
return outputName;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -995,7 +997,7 @@ public class QBEGenerator
|
||||
{
|
||||
case BoolTypeNode:
|
||||
_writer.Indented($"{outputName} =w xor {operand}, 1");
|
||||
return new Val(outputName, unaryExpression.Type, ValKind.Direct);
|
||||
return outputName;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -1009,7 +1011,7 @@ public class QBEGenerator
|
||||
throw new NotSupportedException($"Unary operator {unaryExpression.Operator} for type {unaryExpression.Operand.Type} not supported");
|
||||
}
|
||||
|
||||
private Val EmitStructFieldAccess(StructFieldAccessNode structFieldAccess)
|
||||
private string EmitStructFieldAccess(StructFieldAccessNode structFieldAccess)
|
||||
{
|
||||
var target = EmitUnwrap(EmitExpression(structFieldAccess.Target));
|
||||
|
||||
@@ -1019,16 +1021,10 @@ public class QBEGenerator
|
||||
var output = TmpName();
|
||||
_writer.Indented($"{output} =l add {target}, {offset}");
|
||||
|
||||
// If the accessed member is an inline struct, it will not be a pointer
|
||||
if (structFieldAccess.Type is StructTypeNode)
|
||||
{
|
||||
return new Val(output, structFieldAccess.Type, ValKind.Direct);
|
||||
}
|
||||
|
||||
return new Val(output, structFieldAccess.Type, ValKind.Pointer);
|
||||
return output;
|
||||
}
|
||||
|
||||
private Val EmitStructFuncCall(StructFuncCallNode structFuncCall)
|
||||
private string EmitStructFuncCall(StructFuncCallNode structFuncCall)
|
||||
{
|
||||
var structDef = _definitionTable.LookupStruct(structFuncCall.StructType.Name);
|
||||
var func = StructFuncName(structDef.Name, structFuncCall.Name);
|
||||
@@ -1046,17 +1042,17 @@ public class QBEGenerator
|
||||
if (structFuncCall.Type is VoidTypeNode)
|
||||
{
|
||||
_writer.Indented($"call {func}({string.Join(", ", parameterStrings)})");
|
||||
return new Val(string.Empty, structFuncCall.Type, ValKind.Direct);
|
||||
return string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
var outputName = TmpName();
|
||||
_writer.Indented($"{outputName} {QBEAssign(structFuncCall.Type)} call {func}({string.Join(", ", parameterStrings)})");
|
||||
return new Val(outputName, structFuncCall.Type, ValKind.Direct);
|
||||
return outputName;
|
||||
}
|
||||
}
|
||||
|
||||
private Val EmitInterfaceFuncCall(InterfaceFuncCallNode interfaceFuncCall)
|
||||
private string EmitInterfaceFuncCall(InterfaceFuncCallNode interfaceFuncCall)
|
||||
{
|
||||
var target = EmitUnwrap(EmitExpression(interfaceFuncCall.InterfaceExpression));
|
||||
|
||||
@@ -1087,17 +1083,17 @@ public class QBEGenerator
|
||||
if (interfaceFuncCall.Type is VoidTypeNode)
|
||||
{
|
||||
_writer.Indented($"call {func}({string.Join(", ", parameterStrings)})");
|
||||
return new Val(string.Empty, interfaceFuncCall.Type, ValKind.Direct);
|
||||
return string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
var outputName = TmpName();
|
||||
_writer.Indented($"{outputName} {QBEAssign(interfaceFuncCall.Type)} call {func}({string.Join(", ", parameterStrings)})");
|
||||
return new Val(outputName, interfaceFuncCall.Type, ValKind.Direct);
|
||||
return outputName;
|
||||
}
|
||||
}
|
||||
|
||||
private Val EmitInterfaceInitializer(InterfaceInitializerNode interfaceInitializer, string? destination = null)
|
||||
private string EmitInterfaceInitializer(InterfaceInitializerNode interfaceInitializer, string? destination = null)
|
||||
{
|
||||
var implementation = EmitUnwrap(EmitExpression(interfaceInitializer.Implementation));
|
||||
|
||||
@@ -1126,10 +1122,10 @@ public class QBEGenerator
|
||||
_writer.Indented($"{objectPointer} =l add {destination}, 8");
|
||||
_writer.Indented($"storel {implementation}, {objectPointer}");
|
||||
|
||||
return new Val(destination, interfaceInitializer.InterfaceType, ValKind.Direct);
|
||||
return destination;
|
||||
}
|
||||
|
||||
private Val EmitFuncCall(FuncCallNode funcCall)
|
||||
private string EmitFuncCall(FuncCallNode funcCall)
|
||||
{
|
||||
var expression = EmitExpression(funcCall.Expression);
|
||||
|
||||
@@ -1145,24 +1141,19 @@ public class QBEGenerator
|
||||
if (funcCall.Type is VoidTypeNode)
|
||||
{
|
||||
_writer.Indented($"call {funcPointer}({string.Join(", ", parameterStrings)})");
|
||||
return new Val(string.Empty, funcCall.Type, ValKind.Direct);
|
||||
return string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
var outputName = TmpName();
|
||||
_writer.Indented($"{outputName} {QBEAssign(funcCall.Type)} call {funcPointer}({string.Join(", ", parameterStrings)})");
|
||||
return new Val(outputName, funcCall.Type, ValKind.Direct);
|
||||
return outputName;
|
||||
}
|
||||
}
|
||||
|
||||
private string EmitUnwrap(Val val)
|
||||
{
|
||||
return val.Kind switch
|
||||
{
|
||||
ValKind.Direct => val.Name,
|
||||
ValKind.Pointer => EmitLoad(val.Type, val.Name).Name,
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
return val.Name;
|
||||
}
|
||||
|
||||
private static int SizeOf(TypeNode type)
|
||||
@@ -1329,7 +1320,7 @@ public class CStringLiteral(string value, string name)
|
||||
public string Name { get; } = name;
|
||||
}
|
||||
|
||||
public record Val(string Name, TypeNode Type, ValKind Kind);
|
||||
public record Val(string Name, TypeNode Type, bool IsLValue);
|
||||
|
||||
public class Scope(Scope? parent = null)
|
||||
{
|
||||
@@ -1355,10 +1346,4 @@ public class Scope(Scope? parent = null)
|
||||
{
|
||||
return new Scope(this);
|
||||
}
|
||||
}
|
||||
|
||||
public enum ValKind
|
||||
{
|
||||
Pointer,
|
||||
Direct,
|
||||
}
|
||||
@@ -22,36 +22,36 @@ public enum BinaryOperator
|
||||
Divide
|
||||
}
|
||||
|
||||
public abstract record ExpressionNode(TypeNode Type) : Node;
|
||||
public abstract record ExpressionNode(TypeNode Type, bool IsLValue) : Node;
|
||||
|
||||
public record BinaryExpressionNode(TypeNode Type, ExpressionNode Left, BinaryOperator Operator, ExpressionNode Right) : ExpressionNode(Type);
|
||||
public record BinaryExpressionNode(TypeNode Type, ExpressionNode Left, BinaryOperator Operator, ExpressionNode Right) : ExpressionNode(Type, false);
|
||||
|
||||
public record UnaryExpressionNode(TypeNode Type, UnaryOperator Operator, ExpressionNode Operand) : ExpressionNode(Type);
|
||||
public record UnaryExpressionNode(TypeNode Type, UnaryOperator Operator, ExpressionNode Operand) : ExpressionNode(Type, false);
|
||||
|
||||
public record FuncCallNode(TypeNode Type, ExpressionNode Expression, IReadOnlyList<ExpressionNode> Parameters) : ExpressionNode(Type);
|
||||
public record FuncCallNode(TypeNode Type, ExpressionNode Expression, IReadOnlyList<ExpressionNode> Parameters) : ExpressionNode(Type, false);
|
||||
|
||||
public record StructFuncCallNode(TypeNode Type, string Name, StructTypeNode StructType, ExpressionNode StructExpression, IReadOnlyList<ExpressionNode> Parameters) : ExpressionNode(Type);
|
||||
public record StructFuncCallNode(TypeNode Type, string Name, StructTypeNode StructType, ExpressionNode StructExpression, IReadOnlyList<ExpressionNode> Parameters) : ExpressionNode(Type, false);
|
||||
|
||||
public record InterfaceFuncCallNode(TypeNode Type, string Name, InterfaceTypeNode InterfaceType, ExpressionNode InterfaceExpression, IReadOnlyList<ExpressionNode> Parameters) : ExpressionNode(Type);
|
||||
public record InterfaceFuncCallNode(TypeNode Type, string Name, InterfaceTypeNode InterfaceType, ExpressionNode InterfaceExpression, IReadOnlyList<ExpressionNode> Parameters) : ExpressionNode(Type, false);
|
||||
|
||||
public record VariableIdentNode(TypeNode Type, string Name) : ExpressionNode(Type);
|
||||
public record VariableIdentNode(TypeNode Type, string Name) : ExpressionNode(Type, true);
|
||||
|
||||
public record LocalFuncIdentNode(TypeNode Type, string Name) : ExpressionNode(Type);
|
||||
public record LocalFuncIdentNode(TypeNode Type, string Name) : ExpressionNode(Type, false);
|
||||
|
||||
public record ExternFuncIdentNode(TypeNode Type, string Name) : ExpressionNode(Type);
|
||||
public record ExternFuncIdentNode(TypeNode Type, string Name) : ExpressionNode(Type, false);
|
||||
|
||||
public record ArrayInitializerNode(TypeNode Type, ExpressionNode Capacity, TypeNode ElementType) : ExpressionNode(Type);
|
||||
public record ArrayInitializerNode(TypeNode Type, ExpressionNode Capacity, TypeNode ElementType) : ExpressionNode(Type, true);
|
||||
|
||||
public record ArrayIndexAccessNode(TypeNode Type, ExpressionNode Target, ExpressionNode Index) : ExpressionNode(Type);
|
||||
public record ArrayIndexAccessNode(TypeNode Type, ExpressionNode Target, ExpressionNode Index) : ExpressionNode(Type, true);
|
||||
|
||||
public record AddressOfNode(TypeNode Type, ExpressionNode Expression) : ExpressionNode(Type);
|
||||
public record AddressOfNode(TypeNode Type, ExpressionNode Expression) : ExpressionNode(Type, false);
|
||||
|
||||
public record LiteralNode(TypeNode Type, string Value, LiteralKind Kind) : ExpressionNode(Type);
|
||||
public record LiteralNode(TypeNode Type, string Value, LiteralKind Kind) : ExpressionNode(Type, false);
|
||||
|
||||
public record StructFieldAccessNode(TypeNode Type, StructTypeNode StructType, ExpressionNode Target, string Field) : ExpressionNode(Type);
|
||||
public record StructFieldAccessNode(TypeNode Type, StructTypeNode StructType, ExpressionNode Target, string Field) : ExpressionNode(Type, true);
|
||||
|
||||
public record StructInitializerNode(StructTypeNode StructType, Dictionary<string, ExpressionNode> Initializers) : ExpressionNode(StructType);
|
||||
public record StructInitializerNode(StructTypeNode StructType, Dictionary<string, ExpressionNode> Initializers) : ExpressionNode(StructType, true);
|
||||
|
||||
public record DereferenceNode(TypeNode Type, ExpressionNode Expression) : ExpressionNode(Type);
|
||||
public record DereferenceNode(TypeNode Type, ExpressionNode Expression) : ExpressionNode(Type, false);
|
||||
|
||||
public record InterfaceInitializerNode(TypeNode Type, InterfaceTypeNode InterfaceType, StructTypeNode StructType, ExpressionNode Implementation) : ExpressionNode(Type);
|
||||
public record InterfaceInitializerNode(TypeNode Type, InterfaceTypeNode InterfaceType, StructTypeNode StructType, ExpressionNode Implementation) : ExpressionNode(Type, true);
|
||||
Reference in New Issue
Block a user