This commit is contained in:
nub31
2025-10-17 14:45:55 +02:00
parent 21a5f016a0
commit f471e40471
10 changed files with 1783 additions and 285 deletions

View File

@@ -59,7 +59,7 @@ var cFilePath = Path.Combine(".build", "out.c");
File.WriteAllText(cFilePath, c);
using var process = Process.Start("gcc", ["-ffreestanding", "-nostartfiles", "-c", "-o", Path.Combine(".build", "out.o"), cFilePath]);
using var process = Process.Start("gcc", ["-ffreestanding", "-nostartfiles", "-std=c23", "-g", "-c", "-o", Path.Combine(".build", "out.o"), cFilePath]);
process.WaitForExit();

View File

@@ -1,54 +1,56 @@
using NubLang.Syntax;
namespace NubLang.Ast;
public abstract record Node;
public abstract record Node(List<Token> Tokens);
#region Definitions
public abstract record DefinitionNode(string Module, string Name) : Node;
public abstract record DefinitionNode(List<Token> Tokens, string Module, string Name) : Node(Tokens);
public record FuncParameterNode(string Name, NubType Type) : Node;
public record FuncParameterNode(List<Token> Tokens, string Name, NubType Type) : Node(Tokens);
public record FuncSignatureNode(List<FuncParameterNode> Parameters, NubType ReturnType) : Node;
public record FuncSignatureNode(List<Token> Tokens, List<FuncParameterNode> Parameters, NubType ReturnType) : Node(Tokens);
public record FuncNode(string Module, string Name, string? ExternSymbol, FuncSignatureNode Signature, BlockNode? Body) : DefinitionNode(Module, Name);
public record FuncNode(List<Token> Tokens, string Module, string Name, string? ExternSymbol, FuncSignatureNode Signature, BlockNode? Body) : DefinitionNode(Tokens, Module, Name);
public record StructFieldNode(string Name, NubType Type, ExpressionNode? Value) : Node;
public record StructFieldNode(List<Token> Tokens, string Name, NubType Type, ExpressionNode? Value) : Node(Tokens);
public record StructFuncNode(string Name, FuncSignatureNode Signature, BlockNode Body) : Node;
public record StructFuncNode(List<Token> Tokens, string Name, FuncSignatureNode Signature, BlockNode Body) : Node(Tokens);
public record StructNode(string Module, string Name, List<StructFieldNode> Fields, List<StructFuncNode> Functions) : DefinitionNode(Module, Name);
public record StructNode(List<Token> Tokens, string Module, string Name, List<StructFieldNode> Fields, List<StructFuncNode> Functions) : DefinitionNode(Tokens, Module, Name);
public record GlobalVariableNode(string Module, string Name, ExpressionNode Value) : DefinitionNode(Module, Name);
public record GlobalVariableNode(List<Token> Tokens, string Module, string Name, ExpressionNode Value) : DefinitionNode(Tokens, Module, Name);
#endregion
#region Statements
public abstract record StatementNode : Node;
public abstract record StatementNode(List<Token> Tokens) : Node(Tokens);
public abstract record TerminalStatementNode : StatementNode;
public abstract record TerminalStatementNode(List<Token> Tokens) : StatementNode(Tokens);
public record BlockNode(List<StatementNode> Statements) : StatementNode;
public record BlockNode(List<Token> Tokens, List<StatementNode> Statements) : StatementNode(Tokens);
public record StatementFuncCallNode(FuncCallNode FuncCall) : StatementNode;
public record StatementFuncCallNode(List<Token> Tokens, FuncCallNode FuncCall) : StatementNode(Tokens);
public record StatementStructFuncCallNode(StructFuncCallNode StructFuncCall) : StatementNode;
public record StatementStructFuncCallNode(List<Token> Tokens, StructFuncCallNode StructFuncCall) : StatementNode(Tokens);
public record ReturnNode(ExpressionNode? Value) : TerminalStatementNode;
public record ReturnNode(List<Token> Tokens, ExpressionNode? Value) : TerminalStatementNode(Tokens);
public record AssignmentNode(LValueExpressionNode Target, ExpressionNode Value) : StatementNode;
public record AssignmentNode(List<Token> Tokens, LValueExpressionNode Target, ExpressionNode Value) : StatementNode(Tokens);
public record IfNode(ExpressionNode Condition, BlockNode Body, Variant<IfNode, BlockNode>? Else) : StatementNode;
public record IfNode(List<Token> Tokens, ExpressionNode Condition, BlockNode Body, Variant<IfNode, BlockNode>? Else) : StatementNode(Tokens);
public record VariableDeclarationNode(string Name, ExpressionNode? Assignment, NubType Type) : StatementNode;
public record VariableDeclarationNode(List<Token> Tokens, string Name, ExpressionNode? Assignment, NubType Type) : StatementNode(Tokens);
public record ContinueNode : TerminalStatementNode;
public record ContinueNode(List<Token> Tokens) : TerminalStatementNode(Tokens);
public record BreakNode : TerminalStatementNode;
public record BreakNode(List<Token> Tokens) : TerminalStatementNode(Tokens);
public record WhileNode(ExpressionNode Condition, BlockNode Body) : StatementNode;
public record WhileNode(List<Token> Tokens, ExpressionNode Condition, BlockNode Body) : StatementNode(Tokens);
public record DeferNode(StatementNode Statement) : StatementNode;
public record DeferNode(List<Token> Tokens, StatementNode Statement) : StatementNode(Tokens);
#endregion
@@ -82,58 +84,58 @@ public enum BinaryOperator
BitwiseOr
}
public abstract record ExpressionNode(NubType Type) : Node;
public abstract record ExpressionNode(List<Token> Tokens, NubType Type) : Node(Tokens);
public abstract record LValueExpressionNode(NubType Type) : ExpressionNode(Type);
public abstract record LValueExpressionNode(List<Token> Tokens, NubType Type) : ExpressionNode(Tokens, Type);
public abstract record RValueExpressionNode(NubType Type) : ExpressionNode(Type);
public abstract record RValueExpressionNode(List<Token> Tokens, NubType Type) : ExpressionNode(Tokens, Type);
public record StringLiteralNode(NubType Type, string Value) : RValueExpressionNode(Type);
public record StringLiteralNode(List<Token> Tokens, NubType Type, string Value) : RValueExpressionNode(Tokens, Type);
public record CStringLiteralNode(NubType Type, string Value) : RValueExpressionNode(Type);
public record CStringLiteralNode(List<Token> Tokens, NubType Type, string Value) : RValueExpressionNode(Tokens, Type);
public record IntLiteralNode(NubType Type, long Value) : RValueExpressionNode(Type);
public record IntLiteralNode(List<Token> Tokens, NubType Type, long Value) : RValueExpressionNode(Tokens, Type);
public record UIntLiteralNode(NubType Type, ulong Value) : RValueExpressionNode(Type);
public record UIntLiteralNode(List<Token> Tokens, NubType Type, ulong Value) : RValueExpressionNode(Tokens, Type);
public record Float32LiteralNode(NubType Type, float Value) : RValueExpressionNode(Type);
public record Float32LiteralNode(List<Token> Tokens, NubType Type, float Value) : RValueExpressionNode(Tokens, Type);
public record Float64LiteralNode(NubType Type, double Value) : RValueExpressionNode(Type);
public record Float64LiteralNode(List<Token> Tokens, NubType Type, double Value) : RValueExpressionNode(Tokens, Type);
public record BoolLiteralNode(NubType Type, bool Value) : RValueExpressionNode(Type);
public record BoolLiteralNode(List<Token> Tokens, NubType Type, bool Value) : RValueExpressionNode(Tokens, Type);
public record BinaryExpressionNode(NubType Type, ExpressionNode Left, BinaryOperator Operator, ExpressionNode Right) : RValueExpressionNode(Type);
public record BinaryExpressionNode(List<Token> Tokens, NubType Type, ExpressionNode Left, BinaryOperator Operator, ExpressionNode Right) : RValueExpressionNode(Tokens, Type);
public record UnaryExpressionNode(NubType Type, UnaryOperator Operator, ExpressionNode Operand) : RValueExpressionNode(Type);
public record UnaryExpressionNode(List<Token> Tokens, NubType Type, UnaryOperator Operator, ExpressionNode Operand) : RValueExpressionNode(Tokens, Type);
public record FuncCallNode(NubType Type, ExpressionNode Expression, List<ExpressionNode> Parameters) : RValueExpressionNode(Type);
public record FuncCallNode(List<Token> Tokens, NubType Type, ExpressionNode Expression, List<ExpressionNode> Parameters) : RValueExpressionNode(Tokens, Type);
public record StructFuncCallNode(NubType Type, string Module, string StructName, string FuncName, ExpressionNode StructExpression, List<ExpressionNode> Parameters) : RValueExpressionNode(Type);
public record StructFuncCallNode(List<Token> Tokens, NubType Type, string Module, string StructName, string FuncName, ExpressionNode StructExpression, List<ExpressionNode> Parameters) : RValueExpressionNode(Tokens, Type);
public record LValueIdentifierNode(NubType Type, string Name) : LValueExpressionNode(Type);
public record LValueIdentifierNode(List<Token> Tokens, NubType Type, string Name) : LValueExpressionNode(Tokens, Type);
public record RValueIdentifierNode(NubType Type, string Name) : RValueExpressionNode(Type);
public record RValueIdentifierNode(List<Token> Tokens, NubType Type, string Name) : RValueExpressionNode(Tokens, Type);
public record FuncIdentifierNode(NubType Type, string Module, string Name, string? ExternSymbol) : RValueExpressionNode(Type);
public record FuncIdentifierNode(List<Token> Tokens, NubType Type, string Module, string Name, string? ExternSymbol) : RValueExpressionNode(Tokens, Type);
public record ArrayInitializerNode(NubType Type, ExpressionNode Capacity, NubType ElementType) : RValueExpressionNode(Type);
public record ArrayInitializerNode(List<Token> Tokens, NubType Type, ExpressionNode Capacity, NubType ElementType) : RValueExpressionNode(Tokens, Type);
public record ArrayIndexAccessNode(NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Type);
public record ArrayIndexAccessNode(List<Token> Tokens, NubType Type, ExpressionNode Target, ExpressionNode Index) : LValueExpressionNode(Tokens, Type);
public record AddressOfNode(NubType Type, LValueExpressionNode LValue) : RValueExpressionNode(Type);
public record AddressOfNode(List<Token> Tokens, NubType Type, LValueExpressionNode LValue) : RValueExpressionNode(Tokens, Type);
public record StructFieldAccessNode(NubType Type, ExpressionNode Target, string Field) : LValueExpressionNode(Type);
public record StructFieldAccessNode(List<Token> Tokens, NubType Type, ExpressionNode Target, string Field) : LValueExpressionNode(Tokens, Type);
public record StructInitializerNode(NubStructType StructType, Dictionary<string, ExpressionNode> Initializers) : RValueExpressionNode(StructType);
public record StructInitializerNode(List<Token> Tokens, NubStructType StructType, Dictionary<string, ExpressionNode> Initializers) : RValueExpressionNode(Tokens, StructType);
public record DereferenceNode(NubType Type, ExpressionNode Target) : LValueExpressionNode(Type);
public record DereferenceNode(List<Token> Tokens, NubType Type, ExpressionNode Target) : LValueExpressionNode(Tokens, Type);
public record ConvertIntNode(NubType Type, ExpressionNode Value, NubIntType ValueType, NubIntType TargetType) : RValueExpressionNode(Type);
public record ConvertIntNode(List<Token> Tokens, NubType Type, ExpressionNode Value, NubIntType ValueType, NubIntType TargetType) : RValueExpressionNode(Tokens, Type);
public record ConvertFloatNode(NubType Type, ExpressionNode Value, NubFloatType ValueType, NubFloatType TargetType) : RValueExpressionNode(Type);
public record ConvertFloatNode(List<Token> Tokens, NubType Type, ExpressionNode Value, NubFloatType ValueType, NubFloatType TargetType) : RValueExpressionNode(Tokens, Type);
public record SizeBuiltinNode(NubType Type, NubType TargetType) : RValueExpressionNode(Type);
public record SizeBuiltinNode(List<Token> Tokens, NubType Type, NubType TargetType) : RValueExpressionNode(Tokens, Type);
public record FloatToIntBuiltinNode(NubType Type, ExpressionNode Value, NubFloatType ValueType, NubIntType TargetType) : RValueExpressionNode(Type);
public record FloatToIntBuiltinNode(List<Token> Tokens, NubType Type, ExpressionNode Value, NubFloatType ValueType, NubIntType TargetType) : RValueExpressionNode(Tokens, Type);
#endregion

View File

@@ -160,7 +160,7 @@ public sealed class TypeChecker
var fields = node.Fields.Select(CheckStructField).ToList();
var functions = node.Functions.Select(CheckStructFunc).ToList();
return new StructNode(CurrentScope.Module, node.Name, fields, functions);
return new StructNode(node.Tokens, CurrentScope.Module, node.Name, fields, functions);
}
private StructFuncNode CheckStructFunc(StructFuncSyntax function)
@@ -173,7 +173,7 @@ public sealed class TypeChecker
_funcReturnTypes.Push(ResolveType(function.Signature.ReturnType));
var body = CheckBlock(function.Body);
_funcReturnTypes.Pop();
return new StructFuncNode(function.Name, CheckFuncSignature(function.Signature), body);
return new StructFuncNode(function.Tokens, function.Name, CheckFuncSignature(function.Signature), body);
}
private StructFieldNode CheckStructField(StructFieldSyntax field)
@@ -184,7 +184,7 @@ public sealed class TypeChecker
value = CheckExpression(field.Value, ResolveType(field.Type));
}
return new StructFieldNode(field.Name, ResolveType(field.Type), value);
return new StructFieldNode(field.Tokens, field.Name, ResolveType(field.Type), value);
}
private FuncNode CheckFuncDefinition(FuncSyntax node)
@@ -207,7 +207,7 @@ public sealed class TypeChecker
{
if (signature.ReturnType is NubVoidType)
{
body.Statements.Add(new ReturnNode(null));
body.Statements.Add(new ReturnNode(node.Tokens.Skip(node.Tokens.Count - 1).ToList(), null));
}
else
{
@@ -221,12 +221,12 @@ public sealed class TypeChecker
_funcReturnTypes.Pop();
}
return new FuncNode(CurrentScope.Module, node.Name, node.ExternSymbol, signature, body);
return new FuncNode(node.Tokens, CurrentScope.Module, node.Name, node.ExternSymbol, signature, body);
}
private GlobalVariableNode CheckGlobalVariable(GlobalVariableSyntax node)
{
return new GlobalVariableNode(CurrentScope.Module, node.Name, CheckExpression(node.Value));
return new GlobalVariableNode(node.Tokens, CurrentScope.Module, node.Name, CheckExpression(node.Value));
}
private AssignmentNode CheckAssignment(AssignmentSyntax statement)
@@ -238,7 +238,7 @@ public sealed class TypeChecker
}
var value = CheckExpression(statement.Value, lValue.Type);
return new AssignmentNode(lValue, value);
return new AssignmentNode(statement.Tokens, lValue, value);
}
private IfNode CheckIf(IfSyntax statement)
@@ -251,7 +251,7 @@ public sealed class TypeChecker
elseStatement = statement.Else.Value.Match<Variant<IfNode, BlockNode>>(elif => CheckIf(elif), el => CheckBlock(el));
}
return new IfNode(condition, body, elseStatement);
return new IfNode(statement.Tokens, condition, body, elseStatement);
}
private ReturnNode CheckReturn(ReturnSyntax statement)
@@ -263,7 +263,7 @@ public sealed class TypeChecker
value = CheckExpression(statement.Value, _funcReturnTypes.Peek());
}
return new ReturnNode(value);
return new ReturnNode(statement.Tokens, value);
}
private StatementNode CheckStatementExpression(StatementExpressionSyntax statement)
@@ -272,8 +272,8 @@ public sealed class TypeChecker
return expression switch
{
FuncCallNode funcCall => new StatementFuncCallNode(funcCall),
StructFuncCallNode structFuncCall => new StatementStructFuncCallNode(structFuncCall),
FuncCallNode funcCall => new StatementFuncCallNode(statement.Tokens, funcCall),
StructFuncCallNode structFuncCall => new StatementStructFuncCallNode(statement.Tokens, structFuncCall),
_ => throw new TypeCheckerException(Diagnostic.Error("Expressions statements can only be function calls").At(statement).Build())
};
}
@@ -301,14 +301,14 @@ public sealed class TypeChecker
CurrentScope.DeclareVariable(new Variable(statement.Name, type, VariableKind.LValue));
return new VariableDeclarationNode(statement.Name, assignmentNode, type);
return new VariableDeclarationNode(statement.Tokens, statement.Name, assignmentNode, type);
}
private WhileNode CheckWhile(WhileSyntax statement)
{
var condition = CheckExpression(statement.Condition, new NubBoolType());
var body = CheckBlock(statement.Body);
return new WhileNode(condition, body);
return new WhileNode(statement.Tokens, condition, body);
}
private FuncSignatureNode CheckFuncSignature(FuncSignatureSyntax statement)
@@ -316,10 +316,10 @@ public sealed class TypeChecker
var parameters = new List<FuncParameterNode>();
foreach (var parameter in statement.Parameters)
{
parameters.Add(new FuncParameterNode(parameter.Name, ResolveType(parameter.Type)));
parameters.Add(new FuncParameterNode(parameter.Tokens, parameter.Name, ResolveType(parameter.Type)));
}
return new FuncSignatureNode(parameters, ResolveType(statement.ReturnType));
return new FuncSignatureNode(statement.Tokens, parameters, ResolveType(statement.ReturnType));
}
private ExpressionNode CheckExpression(ExpressionSyntax node, NubType? expectedType = null)
@@ -343,7 +343,7 @@ public sealed class TypeChecker
MemberAccessSyntax expression => CheckMemberAccess(expression),
StructInitializerSyntax expression => CheckStructInitializer(expression, expectedType),
InterpretBuiltinSyntax expression => CheckExpression(expression.Target) with { Type = ResolveType(expression.Type) },
SizeBuiltinSyntax expression => new SizeBuiltinNode(new NubIntType(false, 64), ResolveType(expression.Type)),
SizeBuiltinSyntax expression => new SizeBuiltinNode(node.Tokens, new NubIntType(false, 64), ResolveType(expression.Type)),
FloatToIntBuiltinSyntax expression => CheckFloatToInt(expression),
_ => throw new ArgumentOutOfRangeException(nameof(node))
};
@@ -357,7 +357,7 @@ public sealed class TypeChecker
{
if (sourceIntType.Signed == targetIntType.Signed && sourceIntType.Width < targetIntType.Width)
{
return new ConvertIntNode(targetIntType, result, sourceIntType, targetIntType);
return new ConvertIntNode(node.Tokens, targetIntType, result, sourceIntType, targetIntType);
}
}
@@ -365,7 +365,7 @@ public sealed class TypeChecker
{
if (sourceFloatType.Width < targetFloatType.Width)
{
return new ConvertFloatNode(targetFloatType, result, sourceFloatType, targetFloatType);
return new ConvertFloatNode(node.Tokens, targetFloatType, result, sourceFloatType, targetFloatType);
}
}
@@ -392,7 +392,7 @@ public sealed class TypeChecker
.Build());
}
return new FloatToIntBuiltinNode(targetIntType, value, sourceFloatType, targetIntType);
return new FloatToIntBuiltinNode(expression.Tokens, targetIntType, value, sourceFloatType, targetIntType);
}
private AddressOfNode CheckAddressOf(AddressOfSyntax expression)
@@ -404,7 +404,7 @@ public sealed class TypeChecker
}
var type = new NubPointerType(target.Type);
return new AddressOfNode(type, lvalue);
return new AddressOfNode(expression.Tokens, type, lvalue);
}
private ArrayIndexAccessNode CheckArrayIndexAccess(ArrayIndexAccessSyntax expression)
@@ -416,7 +416,7 @@ public sealed class TypeChecker
throw new TypeCheckerException(Diagnostic.Error($"Cannot use array indexer on type {target.Type}").At(expression).Build());
}
return new ArrayIndexAccessNode(arrayType.ElementType, target, index);
return new ArrayIndexAccessNode(expression.Tokens, arrayType.ElementType, target, index);
}
private ArrayInitializerNode CheckArrayInitializer(ArrayInitializerSyntax expression)
@@ -424,7 +424,7 @@ public sealed class TypeChecker
var elementType = ResolveType(expression.ElementType);
var type = new NubArrayType(elementType);
var capacity = CheckExpression(expression.Capacity);
return new ArrayInitializerNode(type, capacity, elementType);
return new ArrayInitializerNode(expression.Tokens, type, capacity, elementType);
}
private BinaryExpressionNode CheckBinaryExpression(BinaryExpressionSyntax expression, NubType? expectedType)
@@ -469,7 +469,7 @@ public sealed class TypeChecker
var right = CheckExpression(expression.Right, left.Type);
return new BinaryExpressionNode(new NubBoolType(), left, op, right);
return new BinaryExpressionNode(expression.Tokens, new NubBoolType(), left, op, right);
}
case BinaryOperatorSyntax.GreaterThan:
case BinaryOperatorSyntax.GreaterThanOrEqual:
@@ -488,7 +488,7 @@ public sealed class TypeChecker
var right = CheckExpression(expression.Right, left.Type);
return new BinaryExpressionNode(new NubBoolType(), left, op, right);
return new BinaryExpressionNode(expression.Tokens, new NubBoolType(), left, op, right);
}
case BinaryOperatorSyntax.LogicalAnd:
case BinaryOperatorSyntax.LogicalOr:
@@ -505,7 +505,7 @@ public sealed class TypeChecker
var right = CheckExpression(expression.Right, left.Type);
return new BinaryExpressionNode(new NubBoolType(), left, op, right);
return new BinaryExpressionNode(expression.Tokens, new NubBoolType(), left, op, right);
}
case BinaryOperatorSyntax.Plus:
{
@@ -513,7 +513,7 @@ public sealed class TypeChecker
if (left.Type is NubIntType or NubFloatType or NubStringType or NubCStringType)
{
var right = CheckExpression(expression.Right, left.Type);
return new BinaryExpressionNode(left.Type, left, op, right);
return new BinaryExpressionNode(expression.Tokens, left.Type, left, op, right);
}
throw new TypeCheckerException(Diagnostic
@@ -537,7 +537,7 @@ public sealed class TypeChecker
var right = CheckExpression(expression.Right, left.Type);
return new BinaryExpressionNode(left.Type, left, op, right);
return new BinaryExpressionNode(expression.Tokens, left.Type, left, op, right);
}
case BinaryOperatorSyntax.LeftShift:
case BinaryOperatorSyntax.RightShift:
@@ -556,7 +556,7 @@ public sealed class TypeChecker
var right = CheckExpression(expression.Right, left.Type);
return new BinaryExpressionNode(left.Type, left, op, right);
return new BinaryExpressionNode(expression.Tokens, left.Type, left, op, right);
}
default:
{
@@ -580,7 +580,7 @@ public sealed class TypeChecker
.Build());
}
return new UnaryExpressionNode(operand.Type, UnaryOperator.Negate, operand);
return new UnaryExpressionNode(expression.Tokens, operand.Type, UnaryOperator.Negate, operand);
}
case UnaryOperatorSyntax.Invert:
{
@@ -593,7 +593,7 @@ public sealed class TypeChecker
.Build());
}
return new UnaryExpressionNode(operand.Type, UnaryOperator.Invert, operand);
return new UnaryExpressionNode(expression.Tokens, operand.Type, UnaryOperator.Invert, operand);
}
default:
{
@@ -610,7 +610,7 @@ public sealed class TypeChecker
throw new TypeCheckerException(Diagnostic.Error($"Cannot dereference non-pointer type {target.Type}").At(expression).Build());
}
return new DereferenceNode(pointerType.BaseType, target);
return new DereferenceNode(expression.Tokens, pointerType.BaseType, target);
}
private FuncCallNode CheckFuncCall(FuncCallSyntax expression)
@@ -647,7 +647,7 @@ public sealed class TypeChecker
parameters.Add(parameterExpression);
}
return new FuncCallNode(funcType.ReturnType, accessor, parameters);
return new FuncCallNode(expression.Tokens, funcType.ReturnType, accessor, parameters);
}
private StructFuncCallNode CheckMemberFuncCall(MemberFuncCallSyntax expression)
@@ -691,7 +691,7 @@ public sealed class TypeChecker
parameters.Add(parameterExpression);
}
return new StructFuncCallNode(function.ReturnType, structType.Module, structType.Name, expression.Name, target, parameters);
return new StructFuncCallNode(expression.Tokens, function.ReturnType, structType.Module, structType.Name, expression.Name, target, parameters);
}
throw new TypeCheckerException(Diagnostic
@@ -708,8 +708,8 @@ public sealed class TypeChecker
{
return scopeIdent.Kind switch
{
VariableKind.LValue => new LValueIdentifierNode(scopeIdent.Type, expression.Name),
VariableKind.RValue => new RValueIdentifierNode(scopeIdent.Type, expression.Name),
VariableKind.LValue => new LValueIdentifierNode(expression.Tokens, scopeIdent.Type, expression.Name),
VariableKind.RValue => new RValueIdentifierNode(expression.Tokens, scopeIdent.Type, expression.Name),
_ => throw new ArgumentOutOfRangeException()
};
}
@@ -722,7 +722,7 @@ public sealed class TypeChecker
{
var parameters = function.Signature.Parameters.Select(x => ResolveType(x.Type)).ToList();
var type = new NubFuncType(parameters, ResolveType(function.Signature.ReturnType));
return new FuncIdentifierNode(type, CurrentScope.Module, expression.Name, function.ExternSymbol);
return new FuncIdentifierNode(expression.Tokens, type, CurrentScope.Module, expression.Name, function.ExternSymbol);
}
throw new TypeCheckerException(Diagnostic.Error($"Symbol {expression.Name} not found").At(expression).Build());
@@ -760,7 +760,7 @@ public sealed class TypeChecker
{
var parameters = function.Signature.Parameters.Select(x => ResolveType(x.Type)).ToList();
var type = new NubFuncType(parameters, ResolveType(function.Signature.ReturnType));
return new FuncIdentifierNode(type, expression.Module, expression.Name, function.ExternSymbol);
return new FuncIdentifierNode(expression.Tokens, type, expression.Module, expression.Name, function.ExternSymbol);
}
throw new TypeCheckerException(Diagnostic
@@ -773,9 +773,9 @@ public sealed class TypeChecker
{
return expectedType switch
{
NubCStringType => new CStringLiteralNode(expectedType, expression.Value),
NubStringType => new StringLiteralNode(expectedType, expression.Value),
_ => new CStringLiteralNode(new NubCStringType(), expression.Value)
NubCStringType => new CStringLiteralNode(expression.Tokens, expectedType, expression.Value),
NubStringType => new StringLiteralNode(expression.Tokens, expectedType, expression.Value),
_ => new CStringLiteralNode(expression.Tokens, new NubCStringType(), expression.Value)
};
}
@@ -784,35 +784,35 @@ public sealed class TypeChecker
if (expectedType is NubIntType intType)
{
return intType.Signed
? new IntLiteralNode(intType, Convert.ToInt64(expression.Value, expression.Base))
: new UIntLiteralNode(intType, Convert.ToUInt64(expression.Value, expression.Base));
? new IntLiteralNode(expression.Tokens, intType, Convert.ToInt64(expression.Value, expression.Base))
: new UIntLiteralNode(expression.Tokens, intType, Convert.ToUInt64(expression.Value, expression.Base));
}
if (expectedType is NubFloatType floatType)
{
return floatType.Width switch
{
32 => new Float32LiteralNode(floatType, Convert.ToSingle(Convert.ToInt64(expression.Value, expression.Base))),
64 => new Float64LiteralNode(floatType, Convert.ToDouble(Convert.ToInt64(expression.Value, expression.Base))),
32 => new Float32LiteralNode(expression.Tokens, floatType, Convert.ToSingle(Convert.ToInt64(expression.Value, expression.Base))),
64 => new Float64LiteralNode(expression.Tokens, floatType, Convert.ToDouble(Convert.ToInt64(expression.Value, expression.Base))),
_ => throw new ArgumentOutOfRangeException()
};
}
var type = new NubIntType(true, 64);
return new IntLiteralNode(type, Convert.ToInt64(expression.Value, expression.Base));
return new IntLiteralNode(expression.Tokens, type, Convert.ToInt64(expression.Value, expression.Base));
}
private ExpressionNode CheckFloatLiteral(FloatLiteralSyntax expression, NubType? expectedType)
{
var type = expectedType as NubFloatType ?? new NubFloatType(64);
return type.Width == 32
? new Float32LiteralNode(type, Convert.ToSingle(expression.Value))
: new Float64LiteralNode(type, Convert.ToDouble(expression.Value));
? new Float32LiteralNode(expression.Tokens, type, Convert.ToSingle(expression.Value))
: new Float64LiteralNode(expression.Tokens, type, Convert.ToDouble(expression.Value));
}
private BoolLiteralNode CheckBoolLiteral(BoolLiteralSyntax expression)
{
return new BoolLiteralNode(new NubBoolType(), expression.Value);
return new BoolLiteralNode(expression.Tokens, new NubBoolType(), expression.Value);
}
private ExpressionNode CheckMemberAccess(MemberAccessSyntax expression)
@@ -831,7 +831,7 @@ public sealed class TypeChecker
.Build());
}
return new StructFieldAccessNode(field.Type, target, expression.Member);
return new StructFieldAccessNode(expression.Tokens, field.Type, target, expression.Member);
}
default:
{
@@ -902,7 +902,7 @@ public sealed class TypeChecker
.Build());
}
return new StructInitializerNode(structType, initializers);
return new StructInitializerNode(expression.Tokens, structType, initializers);
}
private BlockNode CheckBlock(BlockSyntax node)
@@ -937,7 +937,7 @@ public sealed class TypeChecker
}
}
return new BlockNode(statements);
return new BlockNode(node.Tokens, statements);
}
}
@@ -947,14 +947,14 @@ public sealed class TypeChecker
{
AssignmentSyntax assignmentStmt => CheckAssignment(assignmentStmt),
BlockSyntax blockStmt => CheckBlock(blockStmt),
BreakSyntax => new BreakNode(),
ContinueSyntax => new ContinueNode(),
BreakSyntax => new BreakNode(statement.Tokens),
ContinueSyntax => new ContinueNode(statement.Tokens),
IfSyntax ifStmt => CheckIf(ifStmt),
ReturnSyntax retStmt => CheckReturn(retStmt),
StatementExpressionSyntax stmtExpr => CheckStatementExpression(stmtExpr),
VariableDeclarationSyntax varDeclStmt => CheckVariableDeclaration(varDeclStmt),
WhileSyntax whileStmt => CheckWhile(whileStmt),
DeferSyntax defer => new DeferNode(CheckStatement(defer.Statement)),
DeferSyntax defer => new DeferNode(statement.Tokens, CheckStatement(defer.Statement)),
_ => throw new ArgumentOutOfRangeException(nameof(statement))
};
}
@@ -1142,7 +1142,7 @@ public sealed class TypeChecker
CurrentScope.DeclareVariable(new Variable("this", structType, VariableKind.RValue));
var fields = templateDef.Fields.Select(CheckStructField).ToList();
var functions = templateDef.Functions.Select(CheckStructFunc).ToList();
Definitions.Add(new StructNode(structTemplate.Module, mangledName, fields, functions));
Definitions.Add(new StructNode(templateDef.Tokens, structTemplate.Module, mangledName, fields, functions));
_checkedTemplateStructs.Add($"{structTemplate.Module}.{mangledName}");
}

View File

@@ -1,4 +1,5 @@
using NubLang.Ast;
using NubLang.Syntax;
namespace NubLang.Generation;
@@ -105,45 +106,45 @@ public class Generator
public string Emit()
{
var header = """
typedef __builtin_va_list va_list;
const string header = """
typedef __builtin_va_list va_list;
#define va_start(ap, last) __builtin_va_start(ap, last)
#define va_arg(ap, type) __builtin_va_arg(ap, type)
#define va_end(ap) __builtin_va_end(ap)
#define va_copy(dest, src) __builtin_va_copy(dest, src)
#define va_start(ap, last) __builtin_va_start(ap, last)
#define va_arg(ap, type) __builtin_va_arg(ap, type)
#define va_end(ap) __builtin_va_end(ap)
#define va_copy(dest, src) __builtin_va_copy(dest, src)
#define NULL ((void*)0)
#define NULL ((void*)0)
typedef unsigned long size_t;
typedef unsigned long uintptr_t;
typedef unsigned long size_t;
typedef unsigned long uintptr_t;
#define offsetof(type, member) __builtin_offsetof(type, member)
#define offsetof(type, member) __builtin_offsetof(type, member)
typedef unsigned char u8;
typedef signed char i8;
typedef unsigned short u16;
typedef signed short i16;
typedef unsigned int u32;
typedef signed int i32;
typedef unsigned long long u64;
typedef signed long long i64;
typedef unsigned char u8;
typedef signed char i8;
typedef unsigned short u16;
typedef signed short i16;
typedef unsigned int u32;
typedef signed int i32;
typedef unsigned long long u64;
typedef signed long long i64;
typedef float f32;
typedef double f64;
typedef float f32;
typedef double f64;
#define I8_C(x) x
#define U8_C(x) x##U
#define I8_C(x) x
#define U8_C(x) x##U
#define I16_C(x) x
#define U16_C(x) x##U
#define I16_C(x) x
#define U16_C(x) x##U
#define I32_C(x) x
#define U32_C(x) x##U
#define I32_C(x) x
#define U32_C(x) x##U
#define I64_C(x) x##LL
#define U64_C(x) x##ULL
""";
#define I64_C(x) x##LL
#define U64_C(x) x##ULL
""";
foreach (var structType in _structTypes)
{
@@ -165,6 +166,7 @@ public class Generator
foreach (var funcNode in _definitions.OfType<FuncNode>())
{
EmitLine(funcNode.Tokens);
appendNewLine = true;
var parameters = funcNode.Signature.Parameters.Count != 0
? string.Join(", ", funcNode.Signature.Parameters.Select(x => MapNameWithType(x.Type, x.Name)))
@@ -183,6 +185,7 @@ public class Generator
{
foreach (var structFuncNode in structNode.Functions)
{
EmitLine(structFuncNode.Tokens);
var parameters = structFuncNode.Signature.Parameters.Count != 0
? string.Join(", ", structFuncNode.Signature.Parameters.Select(x => MapNameWithType(x.Type, x.Name)))
: "void";
@@ -198,6 +201,7 @@ public class Generator
{
if (funcNode.Body == null) continue;
EmitLine(funcNode.Tokens);
var parameters = funcNode.Signature.Parameters.Count != 0
? string.Join(", ", funcNode.Signature.Parameters.Select(x => MapNameWithType(x.Type, x.Name)))
: "void";
@@ -232,6 +236,7 @@ public class Generator
private void EmitStatement(StatementNode statementNode)
{
EmitLine(statementNode.Tokens);
switch (statementNode)
{
case AssignmentNode assignmentNode:
@@ -272,6 +277,16 @@ public class Generator
}
}
private void EmitLine(List<Token> tokens)
{
if (tokens.Count >= 1)
{
var file = tokens[0].Span.FilePath;
var line = tokens[0].Span.Start.Line;
_writer.WriteLine($"#line {line} \"{file}\"");
}
}
private void EmitAssignment(AssignmentNode assignmentNode)
{
var target = EmitExpression(assignmentNode.Target);
@@ -294,18 +309,14 @@ public class Generator
_deferStack.Peek().Add(deferNode);
}
private void EmitIf(IfNode ifNode)
private void EmitIf(IfNode ifNode, bool elseIf = false)
{
var condition = EmitExpression(ifNode.Condition);
_writer.WriteLine($"if ({condition})");
_writer.WriteLine($"{(elseIf ? "else" : "")} if ({condition})");
EmitBlock(ifNode.Body);
ifNode.Else?.Match
(
elseIfNode =>
{
_writer.Write("else ");
EmitIf(elseIfNode);
},
elseIfNode => EmitIf(elseIfNode, true),
elseNode =>
{
_writer.WriteLine("else");