...
This commit is contained in:
@@ -100,23 +100,19 @@ public record UnaryExpressionNode(List<Token> Tokens, NubType Type, UnaryOperato
|
||||
|
||||
public record FuncCallNode(List<Token> Tokens, NubType Type, ExpressionNode Expression, List<ExpressionNode> Parameters) : RValueExpressionNode(Tokens, Type);
|
||||
|
||||
public record LValueIdentifierNode(List<Token> Tokens, NubType Type, string Name) : LValueExpressionNode(Tokens, Type);
|
||||
|
||||
public record RValueIdentifierNode(List<Token> Tokens, NubType Type, string Name) : RValueExpressionNode(Tokens, Type);
|
||||
public record VariableIdentifierNode(List<Token> Tokens, NubType Type, string Name) : LValueExpressionNode(Tokens, Type);
|
||||
|
||||
public record FuncIdentifierNode(List<Token> Tokens, NubType Type, string Module, string Name, string? ExternSymbol) : RValueExpressionNode(Tokens, Type);
|
||||
|
||||
public record ArrayInitializerNode(List<Token> Tokens, NubType Type, ExpressionNode Capacity, NubType ElementType) : RValueExpressionNode(Tokens, Type);
|
||||
public record ArrayInitializerNode(List<Token> Tokens, NubType Type, ExpressionNode Capacity, NubType ElementType) : LValueExpressionNode(Tokens, Type);
|
||||
|
||||
public record ArrayIndexAccessNode(List<Token> Tokens, NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Tokens, Type);
|
||||
|
||||
public record ConstArrayIndexAccessNode(List<Token> Tokens, NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Tokens, Type);
|
||||
|
||||
public record SliceIndexAccessNode(List<Token> Tokens, NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Tokens, Type);
|
||||
|
||||
public record AddressOfNode(List<Token> Tokens, NubType Type, LValueExpressionNode LValue) : RValueExpressionNode(Tokens, Type);
|
||||
|
||||
public record StructFieldAccessNode(List<Token> Tokens, NubType Type, LValueExpressionNode Target, string Field) : LValueExpressionNode(Tokens, Type);
|
||||
public record StructFieldAccessNode(List<Token> Tokens, NubType Type, ExpressionNode Target, string Field) : LValueExpressionNode(Tokens, Type);
|
||||
|
||||
public record StructInitializerNode(List<Token> Tokens, NubStructType StructType, Dictionary<string, ExpressionNode> Initializers) : LValueExpressionNode(Tokens, StructType);
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ public sealed class TypeChecker
|
||||
{
|
||||
foreach (var parameter in node.Prototype.Parameters)
|
||||
{
|
||||
CurrentScope.DeclareVariable(new Variable(parameter.Name, ResolveType(parameter.Type), VariableKind.RValue));
|
||||
CurrentScope.DeclareVariable(new Variable(parameter.Name, ResolveType(parameter.Type)));
|
||||
}
|
||||
|
||||
var prototype = CheckFuncPrototype(node.Prototype);
|
||||
@@ -211,7 +211,7 @@ public sealed class TypeChecker
|
||||
throw new TypeCheckerException(Diagnostic.Error($"Cannot infer type of variable {statement.Name}").At(statement).Build());
|
||||
}
|
||||
|
||||
CurrentScope.DeclareVariable(new Variable(statement.Name, type, VariableKind.LValue));
|
||||
CurrentScope.DeclareVariable(new Variable(statement.Name, type));
|
||||
|
||||
return new VariableDeclarationNode(statement.Tokens, statement.Name, assignmentNode, type);
|
||||
}
|
||||
@@ -248,7 +248,6 @@ public sealed class TypeChecker
|
||||
LocalIdentifierSyntax expression => CheckLocalIdentifier(expression),
|
||||
ModuleIdentifierSyntax expression => CheckModuleIdentifier(expression),
|
||||
BoolLiteralSyntax expression => CheckBoolLiteral(expression),
|
||||
ConstArrayInitializerSyntax expression => CheckConstArrayInitializer(expression),
|
||||
StringLiteralSyntax expression => CheckStringLiteral(expression, expectedType),
|
||||
IntLiteralSyntax expression => CheckIntLiteral(expression, expectedType),
|
||||
FloatLiteralSyntax expression => CheckFloatLiteral(expression, expectedType),
|
||||
@@ -284,13 +283,6 @@ public sealed class TypeChecker
|
||||
throw new TypeCheckerException(Diagnostic.Error($"Cannot convert {result.Type} to {expectedType}").At(node).Build());
|
||||
}
|
||||
|
||||
private ArrayInitializerNode CheckConstArrayInitializer(ConstArrayInitializerSyntax expression)
|
||||
{
|
||||
var elementType = ResolveType(expression.ElementType);
|
||||
var type = new NubArrayType(elementType);
|
||||
return new ArrayInitializerNode(expression.Tokens, type, new IntLiteralNode([], new NubIntType(false, 64), expression.Capacity), elementType);
|
||||
}
|
||||
|
||||
private FloatToIntBuiltinNode CheckFloatToInt(FloatToIntBuiltinSyntax expression)
|
||||
{
|
||||
var value = CheckExpression(expression.Value);
|
||||
@@ -334,8 +326,6 @@ public sealed class TypeChecker
|
||||
return target.Type switch
|
||||
{
|
||||
NubArrayType arrayType => new ArrayIndexAccessNode(expression.Tokens, arrayType.ElementType, target, index),
|
||||
NubConstArrayType constArrayType => new ConstArrayIndexAccessNode(expression.Tokens, constArrayType.ElementType, target, index),
|
||||
NubSliceType sliceType => new SliceIndexAccessNode(expression.Tokens, sliceType.ElementType, target, index),
|
||||
_ => throw new TypeCheckerException(Diagnostic.Error($"Cannot use array indexer on type {target.Type}").At(expression).Build())
|
||||
};
|
||||
}
|
||||
@@ -576,12 +566,7 @@ public sealed class TypeChecker
|
||||
var scopeIdent = CurrentScope.LookupVariable(expression.Name);
|
||||
if (scopeIdent != null)
|
||||
{
|
||||
return scopeIdent.Kind switch
|
||||
{
|
||||
VariableKind.LValue => new LValueIdentifierNode(expression.Tokens, scopeIdent.Type, expression.Name),
|
||||
VariableKind.RValue => new RValueIdentifierNode(expression.Tokens, scopeIdent.Type, expression.Name),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
return new VariableIdentifierNode(expression.Tokens, scopeIdent.Type, expression.Name);
|
||||
}
|
||||
|
||||
var module = _importedModules[CurrentScope.Module];
|
||||
@@ -686,12 +671,7 @@ public sealed class TypeChecker
|
||||
.Build());
|
||||
}
|
||||
|
||||
if (target is not LValueExpressionNode lValueTarget)
|
||||
{
|
||||
throw new TypeCheckerException(Diagnostic.Error("Struct field access is not an lvalue (this should never happen)").At(expression.Target).Build());
|
||||
}
|
||||
|
||||
return new StructFieldAccessNode(expression.Tokens, field.Type, lValueTarget, expression.Member);
|
||||
return new StructFieldAccessNode(expression.Tokens, field.Type, target, expression.Member);
|
||||
}
|
||||
default:
|
||||
{
|
||||
@@ -894,13 +874,7 @@ public sealed class TypeChecker
|
||||
}
|
||||
}
|
||||
|
||||
public enum VariableKind
|
||||
{
|
||||
LValue,
|
||||
RValue
|
||||
}
|
||||
|
||||
public record Variable(string Name, NubType Type, VariableKind Kind);
|
||||
public record Variable(string Name, NubType Type);
|
||||
|
||||
public class Scope(string module, Scope? parent = null)
|
||||
{
|
||||
|
||||
@@ -191,7 +191,7 @@ public class Generator
|
||||
{
|
||||
var target = EmitLValue(assignmentNode.Target);
|
||||
var value = EmitExpression(assignmentNode.Value);
|
||||
_builder.BuildStore(value, target);
|
||||
_builder.BuildStore(Unbox(value), target);
|
||||
}
|
||||
|
||||
private void EmitBreak(BreakNode breakNode)
|
||||
@@ -223,7 +223,7 @@ public class Generator
|
||||
else
|
||||
{
|
||||
var returnValue = EmitExpression(returnNode.Value);
|
||||
_builder.BuildRet(returnValue);
|
||||
_builder.BuildRet(Unbox(returnValue));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,7 +247,7 @@ public class Generator
|
||||
if (variableDeclarationNode.Assignment != null)
|
||||
{
|
||||
var initValue = EmitExpression(variableDeclarationNode.Assignment);
|
||||
_builder.BuildStore(initValue, alloca);
|
||||
_builder.BuildStore(Unbox(initValue), alloca);
|
||||
}
|
||||
|
||||
_namedValues[variableDeclarationNode.Name] = alloca;
|
||||
@@ -258,18 +258,17 @@ public class Generator
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private LLVMValueRef EmitExpression(ExpressionNode expressionNode)
|
||||
private Box EmitExpression(ExpressionNode expressionNode)
|
||||
{
|
||||
switch (expressionNode)
|
||||
{
|
||||
case LValueExpressionNode lvalue:
|
||||
{
|
||||
var value = EmitLValue(lvalue);
|
||||
return _builder.BuildLoad2(MapType(lvalue.Type), value);
|
||||
return new Box(EmitLValue(lvalue), true);
|
||||
}
|
||||
case RValueExpressionNode rvalue:
|
||||
{
|
||||
return EmitRValue(rvalue);
|
||||
return new Box(EmitRValue(rvalue), false);
|
||||
}
|
||||
default:
|
||||
{
|
||||
@@ -283,12 +282,12 @@ public class Generator
|
||||
return lValueNode switch
|
||||
{
|
||||
ArrayIndexAccessNode arrayIndexAccessNode => EmitArrayIndexAccess(arrayIndexAccessNode),
|
||||
ConstArrayIndexAccessNode constArrayIndexAccessNode => EmitConstArrayIndexAccess(constArrayIndexAccessNode),
|
||||
ArrayInitializerNode arrayInitializerNode => EmitArrayInitializer(arrayInitializerNode),
|
||||
DereferenceNode dereferenceNode => EmitDereference(dereferenceNode),
|
||||
LValueIdentifierNode lValueIdentifierNode => EmitLValueIdentifier(lValueIdentifierNode),
|
||||
SliceIndexAccessNode sliceIndexAccessNode => EmitSliceIndexAccess(sliceIndexAccessNode),
|
||||
StructFieldAccessNode structFieldAccessNode => EmitStructFieldAccess(structFieldAccessNode),
|
||||
StructInitializerNode structInitializerNode => EmitStructInitializer(structInitializerNode),
|
||||
VariableIdentifierNode variableIdentifierNode => _namedValues[variableIdentifierNode.Name],
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(lValueNode))
|
||||
};
|
||||
}
|
||||
@@ -298,7 +297,6 @@ public class Generator
|
||||
return rValueNode switch
|
||||
{
|
||||
AddressOfNode addressOfNode => EmitAddressOf(addressOfNode),
|
||||
ArrayInitializerNode arrayInitializerNode => EmitArrayInitializer(arrayInitializerNode),
|
||||
BinaryExpressionNode binaryExpressionNode => EmitBinaryExpression(binaryExpressionNode),
|
||||
BoolLiteralNode boolLiteralNode => EmitBoolLiteral(boolLiteralNode),
|
||||
ConvertFloatNode convertFloatNode => EmitConvertFloat(convertFloatNode),
|
||||
@@ -310,7 +308,6 @@ public class Generator
|
||||
FuncCallNode funcCallNode => EmitFuncCall(funcCallNode),
|
||||
FuncIdentifierNode funcIdentifierNode => EmitFuncIdentifier(funcIdentifierNode),
|
||||
IntLiteralNode intLiteralNode => EmitIntLiteral(intLiteralNode),
|
||||
RValueIdentifierNode rValueIdentifierNode => EmitRValueIdentifier(rValueIdentifierNode),
|
||||
SizeBuiltinNode sizeBuiltinNode => EmitSizeBuiltin(sizeBuiltinNode),
|
||||
StringLiteralNode stringLiteralNode => EmitStringLiteral(stringLiteralNode),
|
||||
UIntLiteralNode uIntLiteralNode => EmitUIntLiteral(uIntLiteralNode),
|
||||
@@ -327,13 +324,13 @@ public class Generator
|
||||
var target = EmitExpression(arrayIndexAccessNode.Target);
|
||||
var index = EmitExpression(arrayIndexAccessNode.Index);
|
||||
|
||||
return _builder.BuildGEP2(elementType, target, [index]);
|
||||
return _builder.BuildGEP2(elementType, Unbox(target), [Unbox(index)]);
|
||||
}
|
||||
|
||||
private LLVMValueRef EmitArrayInitializer(ArrayInitializerNode arrayInitializerNode)
|
||||
{
|
||||
var capacity = EmitExpression(arrayInitializerNode.Capacity);
|
||||
return _builder.BuildArrayAlloca(MapType(arrayInitializerNode.ElementType), capacity);
|
||||
return _builder.BuildArrayAlloca(MapType(arrayInitializerNode.ElementType), Unbox(capacity));
|
||||
}
|
||||
|
||||
private LLVMValueRef EmitBinaryExpression(BinaryExpressionNode binaryExpressionNode)
|
||||
@@ -347,24 +344,24 @@ public class Generator
|
||||
{
|
||||
return binaryExpressionNode.Operator switch
|
||||
{
|
||||
BinaryOperator.Plus => _builder.BuildAdd(left, right),
|
||||
BinaryOperator.Minus => _builder.BuildSub(left, right),
|
||||
BinaryOperator.Multiply => _builder.BuildMul(left, right),
|
||||
BinaryOperator.Divide => _builder.BuildSDiv(left, right),
|
||||
BinaryOperator.Modulo => _builder.BuildSRem(left, right),
|
||||
BinaryOperator.Plus => _builder.BuildAdd(Unbox(left), Unbox(right)),
|
||||
BinaryOperator.Minus => _builder.BuildSub(Unbox(left), Unbox(right)),
|
||||
BinaryOperator.Multiply => _builder.BuildMul(Unbox(left), Unbox(right)),
|
||||
BinaryOperator.Divide => _builder.BuildSDiv(Unbox(left), Unbox(right)),
|
||||
BinaryOperator.Modulo => _builder.BuildSRem(Unbox(left), Unbox(right)),
|
||||
|
||||
BinaryOperator.Equal => _builder.BuildICmp(LLVMIntPredicate.LLVMIntEQ, left, right),
|
||||
BinaryOperator.NotEqual => _builder.BuildICmp(LLVMIntPredicate.LLVMIntNE, left, right),
|
||||
BinaryOperator.LessThan => _builder.BuildICmp(LLVMIntPredicate.LLVMIntSLT, left, right),
|
||||
BinaryOperator.LessThanOrEqual => _builder.BuildICmp(LLVMIntPredicate.LLVMIntSLE, left, right),
|
||||
BinaryOperator.GreaterThan => _builder.BuildICmp(LLVMIntPredicate.LLVMIntSGT, left, right),
|
||||
BinaryOperator.GreaterThanOrEqual => _builder.BuildICmp(LLVMIntPredicate.LLVMIntSGE, left, right),
|
||||
BinaryOperator.Equal => _builder.BuildICmp(LLVMIntPredicate.LLVMIntEQ, Unbox(left), Unbox(right)),
|
||||
BinaryOperator.NotEqual => _builder.BuildICmp(LLVMIntPredicate.LLVMIntNE, Unbox(left), Unbox(right)),
|
||||
BinaryOperator.LessThan => _builder.BuildICmp(LLVMIntPredicate.LLVMIntSLT, Unbox(left), Unbox(right)),
|
||||
BinaryOperator.LessThanOrEqual => _builder.BuildICmp(LLVMIntPredicate.LLVMIntSLE, Unbox(left), Unbox(right)),
|
||||
BinaryOperator.GreaterThan => _builder.BuildICmp(LLVMIntPredicate.LLVMIntSGT, Unbox(left), Unbox(right)),
|
||||
BinaryOperator.GreaterThanOrEqual => _builder.BuildICmp(LLVMIntPredicate.LLVMIntSGE, Unbox(left), Unbox(right)),
|
||||
|
||||
BinaryOperator.BitwiseAnd => _builder.BuildAnd(left, right),
|
||||
BinaryOperator.BitwiseOr => _builder.BuildOr(left, right),
|
||||
BinaryOperator.BitwiseXor => _builder.BuildXor(left, right),
|
||||
BinaryOperator.LeftShift => _builder.BuildShl(left, right),
|
||||
BinaryOperator.RightShift => _builder.BuildAShr(left, right),
|
||||
BinaryOperator.BitwiseAnd => _builder.BuildAnd(Unbox(left), Unbox(right)),
|
||||
BinaryOperator.BitwiseOr => _builder.BuildOr(Unbox(left), Unbox(right)),
|
||||
BinaryOperator.BitwiseXor => _builder.BuildXor(Unbox(left), Unbox(right)),
|
||||
BinaryOperator.LeftShift => _builder.BuildShl(Unbox(left), Unbox(right)),
|
||||
BinaryOperator.RightShift => _builder.BuildAShr(Unbox(left), Unbox(right)),
|
||||
|
||||
_ => throw new NotSupportedException($"Binary operator {binaryExpressionNode.Operator} not supported for int")
|
||||
};
|
||||
@@ -374,18 +371,18 @@ public class Generator
|
||||
{
|
||||
return binaryExpressionNode.Operator switch
|
||||
{
|
||||
BinaryOperator.Plus => _builder.BuildFAdd(left, right),
|
||||
BinaryOperator.Minus => _builder.BuildFSub(left, right),
|
||||
BinaryOperator.Multiply => _builder.BuildFMul(left, right),
|
||||
BinaryOperator.Divide => _builder.BuildFDiv(left, right),
|
||||
BinaryOperator.Modulo => _builder.BuildFRem(left, right),
|
||||
BinaryOperator.Plus => _builder.BuildFAdd(Unbox(left), Unbox(right)),
|
||||
BinaryOperator.Minus => _builder.BuildFSub(Unbox(left), Unbox(right)),
|
||||
BinaryOperator.Multiply => _builder.BuildFMul(Unbox(left), Unbox(right)),
|
||||
BinaryOperator.Divide => _builder.BuildFDiv(Unbox(left), Unbox(right)),
|
||||
BinaryOperator.Modulo => _builder.BuildFRem(Unbox(left), Unbox(right)),
|
||||
|
||||
BinaryOperator.Equal => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealOEQ, left, right),
|
||||
BinaryOperator.NotEqual => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealONE, left, right),
|
||||
BinaryOperator.LessThan => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealOLT, left, right),
|
||||
BinaryOperator.LessThanOrEqual => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealOLE, left, right),
|
||||
BinaryOperator.GreaterThan => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealOGT, left, right),
|
||||
BinaryOperator.GreaterThanOrEqual => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealOGE, left, right),
|
||||
BinaryOperator.Equal => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealOEQ, Unbox(left), Unbox(right)),
|
||||
BinaryOperator.NotEqual => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealONE, Unbox(left), Unbox(right)),
|
||||
BinaryOperator.LessThan => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealOLT, Unbox(left), Unbox(right)),
|
||||
BinaryOperator.LessThanOrEqual => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealOLE, Unbox(left), Unbox(right)),
|
||||
BinaryOperator.GreaterThan => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealOGT, Unbox(left), Unbox(right)),
|
||||
BinaryOperator.GreaterThanOrEqual => _builder.BuildFCmp(LLVMRealPredicate.LLVMRealOGE, Unbox(left), Unbox(right)),
|
||||
|
||||
_ => throw new NotSupportedException($"Binary operator {binaryExpressionNode.Operator} not supported for float")
|
||||
};
|
||||
@@ -395,10 +392,10 @@ public class Generator
|
||||
{
|
||||
return binaryExpressionNode.Operator switch
|
||||
{
|
||||
BinaryOperator.LogicalAnd => _builder.BuildAnd(left, right),
|
||||
BinaryOperator.LogicalOr => _builder.BuildOr(left, right),
|
||||
BinaryOperator.Equal => _builder.BuildICmp(LLVMIntPredicate.LLVMIntEQ, left, right),
|
||||
BinaryOperator.NotEqual => _builder.BuildICmp(LLVMIntPredicate.LLVMIntNE, left, right),
|
||||
BinaryOperator.LogicalAnd => _builder.BuildAnd(Unbox(left), Unbox(right)),
|
||||
BinaryOperator.LogicalOr => _builder.BuildOr(Unbox(left), Unbox(right)),
|
||||
BinaryOperator.Equal => _builder.BuildICmp(LLVMIntPredicate.LLVMIntEQ, Unbox(left), Unbox(right)),
|
||||
BinaryOperator.NotEqual => _builder.BuildICmp(LLVMIntPredicate.LLVMIntNE, Unbox(left), Unbox(right)),
|
||||
_ => throw new NotSupportedException($"Binary operator {binaryExpressionNode.Operator} not supported for bool")
|
||||
};
|
||||
}
|
||||
@@ -411,16 +408,6 @@ public class Generator
|
||||
return LLVMValueRef.CreateConstInt(LLVMTypeRef.Int1, boolLiteralNode.Value ? 1ul : 0ul);
|
||||
}
|
||||
|
||||
private LLVMValueRef EmitConstArrayIndexAccess(ConstArrayIndexAccessNode constArrayIndexAccessNode)
|
||||
{
|
||||
var arrayType = (NubConstArrayType)constArrayIndexAccessNode.Target.Type;
|
||||
|
||||
var target = EmitExpression(constArrayIndexAccessNode.Target);
|
||||
var index = EmitExpression(constArrayIndexAccessNode.Index);
|
||||
|
||||
return _builder.BuildGEP2(MapType(arrayType), target, [LLVMValueRef.CreateConstInt(LLVMTypeRef.Int64, 0), index]);
|
||||
}
|
||||
|
||||
private LLVMValueRef EmitConvertFloat(ConvertFloatNode convertFloatNode)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
@@ -459,8 +446,8 @@ public class Generator
|
||||
private LLVMValueRef EmitFuncCall(FuncCallNode funcCallNode)
|
||||
{
|
||||
var function = EmitExpression(funcCallNode.Expression);
|
||||
var args = funcCallNode.Parameters.Select(EmitExpression).ToArray();
|
||||
return _builder.BuildCall2(MapType(funcCallNode.Expression.Type), function, args);
|
||||
var args = funcCallNode.Parameters.Select(x => Unbox(EmitExpression(x))).ToArray();
|
||||
return _builder.BuildCall2(MapType(funcCallNode.Expression.Type), Unbox(function), args);
|
||||
}
|
||||
|
||||
private LLVMValueRef EmitFuncIdentifier(FuncIdentifierNode funcIdentifierNode)
|
||||
@@ -478,16 +465,6 @@ public class Generator
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private LLVMValueRef EmitLValueIdentifier(LValueIdentifierNode lValueIdentifierNode)
|
||||
{
|
||||
return _namedValues[lValueIdentifierNode.Name];
|
||||
}
|
||||
|
||||
private LLVMValueRef EmitRValueIdentifier(RValueIdentifierNode rValueIdentifierNode)
|
||||
{
|
||||
return _builder.BuildLoad2(MapType(rValueIdentifierNode.Type), _namedValues[rValueIdentifierNode.Name], rValueIdentifierNode.Name);
|
||||
}
|
||||
|
||||
private LLVMValueRef EmitSizeBuiltin(SizeBuiltinNode sizeBuiltinNode)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
@@ -506,7 +483,7 @@ public class Generator
|
||||
private LLVMValueRef EmitStructFieldAccess(StructFieldAccessNode structFieldAccessNode)
|
||||
{
|
||||
var type = (NubStructType)structFieldAccessNode.Target.Type;
|
||||
var target = EmitLValue(structFieldAccessNode.Target);
|
||||
var target = EmitLValue((LValueExpressionNode)structFieldAccessNode.Target);
|
||||
var fieldIndex = type.Fields.FindIndex(x => x.Name == structFieldAccessNode.Field);
|
||||
return _builder.BuildStructGEP2(MapType(structFieldAccessNode.Target.Type), target, (uint)fieldIndex);
|
||||
}
|
||||
@@ -522,7 +499,7 @@ public class Generator
|
||||
var fieldIndex = structInitializerNode.StructType.Fields.FindIndex(x => x.Name == initializer.Key);
|
||||
var fieldPtr = _builder.BuildStructGEP2(type, ptr, (uint)fieldIndex);
|
||||
|
||||
_builder.BuildStore(value, fieldPtr);
|
||||
_builder.BuildStore(Unbox(value), fieldPtr);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
@@ -538,10 +515,22 @@ public class Generator
|
||||
var operand = EmitExpression(unaryExpressionNode.Operand);
|
||||
return unaryExpressionNode.Operator switch
|
||||
{
|
||||
UnaryOperator.Negate when unaryExpressionNode.Operand.Type is NubIntType => _builder.BuildNeg(operand),
|
||||
UnaryOperator.Negate when unaryExpressionNode.Operand.Type is NubFloatType => _builder.BuildFNeg(operand),
|
||||
UnaryOperator.Invert => _builder.BuildNot(operand),
|
||||
UnaryOperator.Negate when unaryExpressionNode.Operand.Type is NubIntType => _builder.BuildNeg(Unbox(operand)),
|
||||
UnaryOperator.Negate when unaryExpressionNode.Operand.Type is NubFloatType => _builder.BuildFNeg(Unbox(operand)),
|
||||
UnaryOperator.Invert => _builder.BuildNot(Unbox(operand)),
|
||||
_ => throw new NotImplementedException($"Unary operator {unaryExpressionNode.Operator} not implemented")
|
||||
};
|
||||
}
|
||||
|
||||
private LLVMValueRef Unbox(Box box)
|
||||
{
|
||||
if (box.LValue)
|
||||
{
|
||||
return _builder.BuildLoad2(box.Value.TypeOf, box.Value);
|
||||
}
|
||||
|
||||
return box.Value;
|
||||
}
|
||||
|
||||
private record Box(LLVMValueRef Value, bool LValue);
|
||||
}
|
||||
@@ -530,22 +530,13 @@ public sealed class Parser
|
||||
return expr;
|
||||
}
|
||||
|
||||
private ExpressionSyntax ParseArrayInitializer(int startIndex)
|
||||
{
|
||||
if (TryExpectIntLiteral(out var intLiteral))
|
||||
{
|
||||
ExpectSymbol(Symbol.CloseBracket);
|
||||
var type = ParseType();
|
||||
return new ConstArrayInitializerSyntax(GetTokens(startIndex), Convert.ToInt64(intLiteral.Value, intLiteral.Base), type);
|
||||
}
|
||||
else
|
||||
private ArrayInitializerSyntax ParseArrayInitializer(int startIndex)
|
||||
{
|
||||
var capacity = ParseExpression();
|
||||
ExpectSymbol(Symbol.CloseBracket);
|
||||
var type = ParseType();
|
||||
return new ArrayInitializerSyntax(GetTokens(startIndex), capacity, type);
|
||||
}
|
||||
}
|
||||
|
||||
private StructInitializerSyntax ParseStructInitializer(int startIndex)
|
||||
{
|
||||
|
||||
@@ -88,8 +88,6 @@ public record ModuleIdentifierSyntax(List<Token> Tokens, string Module, string N
|
||||
|
||||
public record ArrayInitializerSyntax(List<Token> Tokens, ExpressionSyntax Capacity, TypeSyntax ElementType) : ExpressionSyntax(Tokens);
|
||||
|
||||
public record ConstArrayInitializerSyntax(List<Token> Tokens, long Capacity, TypeSyntax ElementType) : ExpressionSyntax(Tokens);
|
||||
|
||||
public record ArrayIndexAccessSyntax(List<Token> Tokens, ExpressionSyntax Target, ExpressionSyntax Index) : ExpressionSyntax(Tokens);
|
||||
|
||||
public record AddressOfSyntax(List<Token> Tokens, ExpressionSyntax Target) : ExpressionSyntax(Tokens);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
.build/out: main.nub
|
||||
nubc main.nub
|
||||
clang -o .build/out .build/main.ll
|
||||
|
||||
clean:
|
||||
@rm -r .build 2>/dev/null || true
|
||||
|
||||
Reference in New Issue
Block a user