This commit is contained in:
nub31
2025-10-21 20:47:00 +02:00
parent 4a01fbc306
commit e3f819411c
6 changed files with 74 additions and 125 deletions

View File

@@ -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);
}