From 1676806ef023dfdc776470fd99fd0c13a00190f3 Mon Sep 17 00:00:00 2001 From: nub31 Date: Fri, 16 May 2025 21:27:27 +0200 Subject: [PATCH] explicit variable types --- example/program.nub | 7 ++----- src/compiler/Nub.Lang/Backend/Generator.cs | 20 +++++++++++++++++-- .../Nub.Lang/Frontend/Parsing/Parser.cs | 9 ++++++++- .../Parsing/VariableAssignmentNode.cs | 3 ++- .../Frontend/Typing/ExpressionTyper.cs | 2 +- 5 files changed, 31 insertions(+), 10 deletions(-) diff --git a/example/program.nub b/example/program.nub index 8f3a332..eb398cf 100644 --- a/example/program.nub +++ b/example/program.nub @@ -2,10 +2,7 @@ import c global func main(argc: i64, argv: i64) { printf("args: %d, starts at %p\n", argc, argv) - test(12.1) - return 23 -} -func test(a: f64) { - printf("%f\n", a) + x: i8 = 320000 + printf("%d\n", x) } \ No newline at end of file diff --git a/src/compiler/Nub.Lang/Backend/Generator.cs b/src/compiler/Nub.Lang/Backend/Generator.cs index f45d86a..9e72769 100644 --- a/src/compiler/Nub.Lang/Backend/Generator.cs +++ b/src/compiler/Nub.Lang/Backend/Generator.cs @@ -14,6 +14,7 @@ public class Generator private readonly Stack _breakLabels = new(); private readonly Stack _continueLabels = new(); private bool _codeIsReachable = true; + private LocalFuncDefinitionNode? _currentFuncDefininition; public Generator(List definitions) { @@ -217,6 +218,7 @@ public class Generator private void GenerateFuncDefinition(LocalFuncDefinitionNode node) { + _currentFuncDefininition = node; _variables.Clear(); if (node.Global) @@ -288,6 +290,7 @@ public class Generator } _builder.AppendLine("}"); + _currentFuncDefininition = null; } private void GenerateStructDefinition(StructDefinitionNode structDefinition) @@ -433,8 +436,14 @@ public class Generator { if (@return.Value.HasValue) { + if (!_currentFuncDefininition!.ReturnType.HasValue) + { + throw new Exception("Cannot return a value when function does not have a return value"); + } + var result = GenerateExpression(@return.Value.Value); - _builder.AppendLine($" ret {result}"); + var converted = GenerateTypeConversion(result, @return.Value.Value.Type, _currentFuncDefininition.ReturnType.Value); + _builder.AppendLine($" ret {converted}"); } else { @@ -445,10 +454,17 @@ public class Generator private void GenerateVariableAssignment(VariableAssignmentNode variableAssignment) { var result = GenerateExpression(variableAssignment.Value); + var variableType = variableAssignment.Value.Type; + + if (variableAssignment.ExplicitType.HasValue) + { + result = GenerateTypeConversion(result, variableType, variableAssignment.ExplicitType.Value); + variableType = variableAssignment.ExplicitType.Value; + } _variables[variableAssignment.Name] = new Variable { Identifier = result, - Type = variableAssignment.Value.Type + Type = variableType }; } diff --git a/src/compiler/Nub.Lang/Frontend/Parsing/Parser.cs b/src/compiler/Nub.Lang/Frontend/Parsing/Parser.cs index 280926b..952efed 100644 --- a/src/compiler/Nub.Lang/Frontend/Parsing/Parser.cs +++ b/src/compiler/Nub.Lang/Frontend/Parsing/Parser.cs @@ -157,7 +157,14 @@ public class Parser case Symbol.Assign: { var value = ParseExpression(); - return new VariableAssignmentNode(identifier.Value, value); + return new VariableAssignmentNode(identifier.Value, Optional.Empty(), value); + } + case Symbol.Colon: + { + var type = ParseType(); + ExpectSymbol(Symbol.Assign); + var value = ParseExpression(); + return new VariableAssignmentNode(identifier.Value,type, value); } default: { diff --git a/src/compiler/Nub.Lang/Frontend/Parsing/VariableAssignmentNode.cs b/src/compiler/Nub.Lang/Frontend/Parsing/VariableAssignmentNode.cs index e76cb63..2964d04 100644 --- a/src/compiler/Nub.Lang/Frontend/Parsing/VariableAssignmentNode.cs +++ b/src/compiler/Nub.Lang/Frontend/Parsing/VariableAssignmentNode.cs @@ -1,7 +1,8 @@ namespace Nub.Lang.Frontend.Parsing; -public class VariableAssignmentNode(string name, ExpressionNode value) : StatementNode +public class VariableAssignmentNode(string name, Optional explicitType, ExpressionNode value) : StatementNode { public string Name { get; } = name; + public Optional ExplicitType { get; } = explicitType; public ExpressionNode Value { get; } = value; } \ No newline at end of file diff --git a/src/compiler/Nub.Lang/Frontend/Typing/ExpressionTyper.cs b/src/compiler/Nub.Lang/Frontend/Typing/ExpressionTyper.cs index 14e2f64..09fb4b3 100644 --- a/src/compiler/Nub.Lang/Frontend/Typing/ExpressionTyper.cs +++ b/src/compiler/Nub.Lang/Frontend/Typing/ExpressionTyper.cs @@ -143,7 +143,7 @@ public class ExpressionTyper private void PopulateVariableAssignment(VariableAssignmentNode variableAssignment) { PopulateExpression(variableAssignment.Value); - _variables.Push(new Variable(variableAssignment.Name, variableAssignment.Value.Type)); + _variables.Push(new Variable(variableAssignment.Name, variableAssignment.ExplicitType.HasValue ? variableAssignment.ExplicitType.Value : variableAssignment.Value.Type)); } private void PopulateVariableReassignment(VariableAssignmentNode variableAssignment)