diff --git a/example/program.nub b/example/program.nub index 2172256..8dae7c2 100644 --- a/example/program.nub +++ b/example/program.nub @@ -1,6 +1,6 @@ import "core"; -func main() { +global func main() { let x = "test"; puts(x); } diff --git a/lang/Nub.Lang/Backend/Generator.cs b/lang/Nub.Lang/Backend/Generator.cs index 2453837..e4e5a17 100644 --- a/lang/Nub.Lang/Backend/Generator.cs +++ b/lang/Nub.Lang/Backend/Generator.cs @@ -50,7 +50,11 @@ public class Generator { _variables.Clear(); var parameters = node.Parameters.Select(p => $"{QbeTypeName(p.Type)} %{p.Name}"); - _builder.Append("export function "); + if (node.Global) + { + _builder.Append("export "); + } + _builder.Append("function "); if (node.ReturnType.HasValue) { _builder.Append($"{QbeTypeName(node.ReturnType.Value)} "); @@ -113,10 +117,12 @@ public class Generator private void GenerateBreak() { + throw new NotImplementedException(); } private void GenerateContinue() { + throw new NotImplementedException(); } private void GenerateStatementFuncCall(FuncCallStatementNode funcCall) @@ -134,6 +140,7 @@ public class Generator private void GenerateIf(IfNode ifStatement) { + throw new NotImplementedException(); } private void GenerateReturn(ReturnNode @return) @@ -161,6 +168,7 @@ public class Generator private void GenerateWhile(WhileNode whileStatement) { + throw new NotImplementedException(); } private string GenerateExpression(ExpressionNode expression) diff --git a/lang/Nub.Lang/Frontend/Lexing/Lexer.cs b/lang/Nub.Lang/Frontend/Lexing/Lexer.cs index 32e8bdd..a3def22 100644 --- a/lang/Nub.Lang/Frontend/Lexing/Lexer.cs +++ b/lang/Nub.Lang/Frontend/Lexing/Lexer.cs @@ -5,6 +5,7 @@ public class Lexer private static readonly Dictionary Keywords = new() { ["func"] = Symbol.Func, + ["global"] = Symbol.Global, ["extern"] = Symbol.Extern, ["import"] = Symbol.Import, ["let"] = Symbol.Let, diff --git a/lang/Nub.Lang/Frontend/Lexing/SymbolToken.cs b/lang/Nub.Lang/Frontend/Lexing/SymbolToken.cs index 123364a..a73c376 100644 --- a/lang/Nub.Lang/Frontend/Lexing/SymbolToken.cs +++ b/lang/Nub.Lang/Frontend/Lexing/SymbolToken.cs @@ -10,6 +10,7 @@ public enum Symbol Whitespace, Import, Extern, + Global, Func, Return, Let, diff --git a/lang/Nub.Lang/Frontend/Parsing/LocalFuncDefinitionNode.cs b/lang/Nub.Lang/Frontend/Parsing/LocalFuncDefinitionNode.cs index d1e0714..6734a02 100644 --- a/lang/Nub.Lang/Frontend/Parsing/LocalFuncDefinitionNode.cs +++ b/lang/Nub.Lang/Frontend/Parsing/LocalFuncDefinitionNode.cs @@ -1,11 +1,12 @@ namespace Nub.Lang.Frontend.Parsing; -public class LocalFuncDefinitionNode(string name, List parameters, BlockNode body, Optional returnType) : DefinitionNode +public class LocalFuncDefinitionNode(string name, List parameters, BlockNode body, Optional returnType, bool global) : DefinitionNode { public string Name { get; } = name; public List Parameters { get; } = parameters; public BlockNode Body { get; } = body; public Optional ReturnType { get; } = returnType; + public bool Global { get; } = global; public override string ToString() => $"{Name}({string.Join(", ", Parameters.Select(p => p.ToString()))}){(ReturnType.HasValue ? ": " + ReturnType.Value : "")}"; } \ No newline at end of file diff --git a/lang/Nub.Lang/Frontend/Parsing/Parser.cs b/lang/Nub.Lang/Frontend/Parsing/Parser.cs index f6dcd87..2fdf890 100644 --- a/lang/Nub.Lang/Frontend/Parsing/Parser.cs +++ b/lang/Nub.Lang/Frontend/Parsing/Parser.cs @@ -44,6 +44,7 @@ public class Parser return keyword.Symbol switch { Symbol.Func => ParseFuncDefinition(), + Symbol.Global => ParseGlobalFuncDefinition(), Symbol.Extern => ParseExternFuncDefinition(), Symbol.Struct => ParseStruct(), _ => throw new Exception("Unexpected symbol: " + keyword.Symbol) @@ -72,7 +73,33 @@ public class Parser var body = ParseBlock(); - return new LocalFuncDefinitionNode(name.Value, parameters, body, returnType); + return new LocalFuncDefinitionNode(name.Value, parameters, body, returnType, false); + } + + private LocalFuncDefinitionNode ParseGlobalFuncDefinition() + { + ExpectSymbol(Symbol.Func); + var name = ExpectIdentifier(); + List parameters = []; + ExpectSymbol(Symbol.OpenParen); + if (!TryExpectSymbol(Symbol.CloseParen)) + { + while (!TryExpectSymbol(Symbol.CloseParen)) + { + parameters.Add(ParseFuncParameter()); + TryExpectSymbol(Symbol.Comma); + } + } + + var returnType = Optional.Empty(); + if (TryExpectSymbol(Symbol.Colon)) + { + returnType = ParseTypeInstance(); + } + + var body = ParseBlock(); + + return new LocalFuncDefinitionNode(name.Value, parameters, body, returnType, true); } private ExternFuncDefinitionNode ParseExternFuncDefinition() diff --git a/std/baseline/runtime.asm b/std/baseline/runtime.asm index de732f1..90e0941 100644 --- a/std/baseline/runtime.asm +++ b/std/baseline/runtime.asm @@ -1,8 +1,9 @@ global _start -extern main +extern main, gc_init section .text _start: + call gc_init call main mov rax, 60 mov rdi, 0