From 6e6a1a830e61e4dc20bacae42dce298654582990 Mon Sep 17 00:00:00 2001 From: nub31 Date: Sun, 26 Jan 2025 20:44:22 +0100 Subject: [PATCH] Add support for stack parameters --- Nub.Lang/Nub.Lang/Generation/Generator.cs | 27 ++++++++++++++--------- Nub.Lang/Nub.Lang/Input/program.nub | 27 ++++++++++++++++++++++- Nub.Lang/Nub.Lang/Parsing/Parser.cs | 1 + 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/Nub.Lang/Nub.Lang/Generation/Generator.cs b/Nub.Lang/Nub.Lang/Generation/Generator.cs index e0887d5..471b797 100644 --- a/Nub.Lang/Nub.Lang/Generation/Generator.cs +++ b/Nub.Lang/Nub.Lang/Generation/Generator.cs @@ -109,17 +109,16 @@ public class Generator for (var i = 0; i < symbol.Parameters.Count; i++) { - var parameter = symbol.Parameters.ElementAt(i); - + var parameter = symbol.ResolveLocalVariable(symbol.Parameters.ElementAt(i).Name); if (i < registers.Length) { - var variable = symbol.ResolveLocalVariable(parameter.Name); - _builder.AppendLine($" mov [rbp - {variable.Offset}], {registers[i]}"); + _builder.AppendLine($" mov [rbp - {parameter.Offset}], {registers[i]}"); } else { - // TODO: Implement parameters passed on the stack - throw new NotImplementedException(); + var stackOffset = 16 + (i - registers.Length) * 8; + _builder.AppendLine($" mov rax, [rbp + {stackOffset}]"); + _builder.AppendLine($" mov [rbp - {parameter.Offset}], rax"); } } @@ -262,24 +261,30 @@ public class Generator _builder.AppendLine(" call strlen"); } - // TODO: Use stack for more than 6 parameters private void GenerateFuncCall(FuncCall funcCall, Func func) { var symbol = _symbolTable.ResolveFunc(funcCall.Name, funcCall.Parameters.Select(p => p.Type).ToList()); string[] registers = ["rdi", "rsi", "rdx", "rcx", "r8", "r9"]; - foreach (var parameter in funcCall.Parameters) + for (var i = funcCall.Parameters.Count - 1; i >= 0; i--) { - GenerateExpression(parameter, func); + GenerateExpression(funcCall.Parameters.ElementAt(i), func); _builder.AppendLine(" push rax"); } - for (var i = funcCall.Parameters.Count - 1; i >= 0; i--) + var registerParameters = Math.Min(registers.Length, funcCall.Parameters.Count); + var stackParameters = funcCall.Parameters.Count - registerParameters; + + for (var i = 0; i < registerParameters; i++) { _builder.AppendLine($" pop {registers[i]}"); } - + _builder.AppendLine($" call {symbol.Label}"); + if (stackParameters != 0) + { + _builder.AppendLine($" add rsp, {stackParameters}"); + } } private void GenerateSyscall(Syscall syscall, Func func) diff --git a/Nub.Lang/Nub.Lang/Input/program.nub b/Nub.Lang/Nub.Lang/Input/program.nub index aa0891e..f21d41b 100644 --- a/Nub.Lang/Nub.Lang/Input/program.nub +++ b/Nub.Lang/Nub.Lang/Input/program.nub @@ -4,7 +4,32 @@ let STD_OUT = 1; let STD_ERR = 2; func main() { - write("test\n"); + test + ( + "a\n", + "b\n", + "c\n", + "d\n", + "e\n", + "f\n", + "g\n", + "h\n", + "i\n", + "j\n", + ); +} + +func test(a: String, b: String, c: String, d: String, e: String, f: String, g: String, h: String, i: String, j: String) { + write(a); + write(b); + write(c); + write(d); + write(e); + write(f); + write(g); + write(h); + write(i); + write(j); } func write(msg: String) { diff --git a/Nub.Lang/Nub.Lang/Parsing/Parser.cs b/Nub.Lang/Nub.Lang/Parsing/Parser.cs index fa16e61..e2921bd 100644 --- a/Nub.Lang/Nub.Lang/Parsing/Parser.cs +++ b/Nub.Lang/Nub.Lang/Parsing/Parser.cs @@ -56,6 +56,7 @@ public class Parser while (!TryExpectSymbol(Symbol.CloseParen)) { parameters.Add(ParseFuncParameter()); + TryExpectSymbol(Symbol.Comma); } }