update runtime tok look for main in defult namespace
This commit is contained in:
@@ -22,7 +22,7 @@ impl printable for human
|
||||
}
|
||||
}
|
||||
|
||||
export func main(args: []cstring): i64
|
||||
func main(args: []cstring): i64
|
||||
{
|
||||
let human = alloc human
|
||||
{
|
||||
|
||||
Binary file not shown.
@@ -71,8 +71,6 @@ public static class ConsoleColors
|
||||
LiteralKind.Bool => Blue,
|
||||
_ => White
|
||||
};
|
||||
case ModifierToken:
|
||||
return White;
|
||||
case SymbolToken symbol:
|
||||
switch (symbol.Symbol)
|
||||
{
|
||||
|
||||
@@ -67,19 +67,19 @@ public partial class QBEGenerator
|
||||
|
||||
foreach (var funcDef in _syntaxTree.Definitions.OfType<BoundLocalFunc>())
|
||||
{
|
||||
EmitFuncDefinition(funcDef, LocalFuncName(funcDef), funcDef.Parameters, funcDef.ReturnType, funcDef.Body, funcDef.Exported);
|
||||
EmitFuncDefinition(funcDef, LocalFuncName(funcDef), funcDef.Parameters, funcDef.ReturnType, funcDef.Body);
|
||||
_writer.NewLine();
|
||||
}
|
||||
|
||||
while (_anonymousFunctions.TryDequeue(out var anon))
|
||||
{
|
||||
EmitFuncDefinition(anon.Func, anon.Name, anon.Func.Parameters, anon.Func.ReturnType, anon.Func.Body, false);
|
||||
EmitFuncDefinition(anon.Func, anon.Name, anon.Func.Parameters, anon.Func.ReturnType, anon.Func.Body);
|
||||
_writer.NewLine();
|
||||
}
|
||||
|
||||
foreach (var (impl, name) in _implFunctions)
|
||||
{
|
||||
EmitFuncDefinition(impl, name, impl.Parameters, impl.ReturnType, impl.Body, false);
|
||||
EmitFuncDefinition(impl, name, impl.Parameters, impl.ReturnType, impl.Body);
|
||||
_writer.NewLine();
|
||||
}
|
||||
|
||||
@@ -347,7 +347,7 @@ public partial class QBEGenerator
|
||||
return "l";
|
||||
}
|
||||
|
||||
private void EmitFuncDefinition(BoundNode debugNode, string name, List<BoundFuncParameter> parameters, NubType returnType, BoundBlock body, bool exported)
|
||||
private void EmitFuncDefinition(BoundNode debugNode, string name, List<BoundFuncParameter> parameters, NubType returnType, BoundBlock body)
|
||||
{
|
||||
_variables.Clear();
|
||||
_variableScopes.Clear();
|
||||
@@ -356,12 +356,7 @@ public partial class QBEGenerator
|
||||
|
||||
var builder = new StringBuilder();
|
||||
|
||||
if (exported)
|
||||
{
|
||||
builder.Append("export ");
|
||||
}
|
||||
|
||||
builder.Append("function ");
|
||||
builder.Append("export function ");
|
||||
if (returnType is not NubVoidType)
|
||||
{
|
||||
builder.Append(FuncQBETypeName(returnType) + ' ');
|
||||
@@ -503,7 +498,7 @@ public partial class QBEGenerator
|
||||
|
||||
private string LocalFuncName(BoundLocalFunc funcDef)
|
||||
{
|
||||
return funcDef.Exported ? $"${funcDef.Name}" : $"${funcDef.Namespace}_{funcDef.Name}";
|
||||
return $"${funcDef.Namespace}_{funcDef.Name}";
|
||||
}
|
||||
|
||||
private string ExternFuncName(BoundExternFunc funcDef)
|
||||
|
||||
@@ -144,7 +144,7 @@ public sealed class Binder
|
||||
|
||||
var body = BindBlock(node.Body);
|
||||
|
||||
return new BoundLocalFunc(node.Tokens, node.Namespace, node.Name, parameters, body, node.ReturnType, node.Exported);
|
||||
return new BoundLocalFunc(node.Tokens, node.Namespace, node.Name, parameters, body, node.ReturnType);
|
||||
}
|
||||
|
||||
private BoundBlock BindBlock(BlockSyntax node)
|
||||
|
||||
@@ -9,7 +9,7 @@ public abstract record BoundDefinitionMember(IEnumerable<Token> Tokens) : BoundN
|
||||
|
||||
public record BoundFuncParameter(IEnumerable<Token> Tokens, string Name, NubType Type) : BoundDefinitionMember(Tokens);
|
||||
|
||||
public record BoundLocalFunc(IEnumerable<Token> Tokens, string Namespace, string Name, List<BoundFuncParameter> Parameters, BoundBlock Body, NubType ReturnType, bool Exported) : BoundDefinition(Tokens, Namespace);
|
||||
public record BoundLocalFunc(IEnumerable<Token> Tokens, string Namespace, string Name, List<BoundFuncParameter> Parameters, BoundBlock Body, NubType ReturnType) : BoundDefinition(Tokens, Namespace);
|
||||
|
||||
public record BoundExternFunc(IEnumerable<Token> Tokens, string Namespace, string Name, string CallName, List<BoundFuncParameter> Parameters, NubType ReturnType) : BoundDefinition(Tokens, Namespace);
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ public abstract record DefinitionMemberSyntax(IEnumerable<Token> Tokens) : Synta
|
||||
|
||||
public record FuncParameterSyntax(IEnumerable<Token> Tokens, string Name, NubType Type) : DefinitionMemberSyntax(Tokens);
|
||||
|
||||
public record LocalFuncSyntax(IEnumerable<Token> Tokens, string Namespace, string Name, List<FuncParameterSyntax> Parameters, BlockSyntax Body, NubType ReturnType, bool Exported) : DefinitionSyntax(Tokens, Namespace);
|
||||
public record LocalFuncSyntax(IEnumerable<Token> Tokens, string Namespace, string Name, List<FuncParameterSyntax> Parameters, BlockSyntax Body, NubType ReturnType) : DefinitionSyntax(Tokens, Namespace);
|
||||
|
||||
public record ExternFuncSyntax(IEnumerable<Token> Tokens, string Namespace, string Name, string CallName, List<FuncParameterSyntax> Parameters, NubType ReturnType) : DefinitionSyntax(Tokens, Namespace);
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ public sealed class Parser
|
||||
|
||||
public Parser(IEnumerable<Token> tokens)
|
||||
{
|
||||
_namespace = "global";
|
||||
_namespace = "default";
|
||||
_tokens = tokens;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public sealed class Parser
|
||||
{
|
||||
try
|
||||
{
|
||||
definitions.Add(ParseTopLevel());
|
||||
definitions.Add(ParseDefinition());
|
||||
}
|
||||
catch (ParseException ex)
|
||||
{
|
||||
@@ -50,20 +50,15 @@ public sealed class Parser
|
||||
return new SyntaxTree(_namespace, definitions, _diagnostics);
|
||||
}
|
||||
|
||||
private DefinitionSyntax ParseTopLevel()
|
||||
private DefinitionSyntax ParseDefinition()
|
||||
{
|
||||
var startIndex = _tokenIndex;
|
||||
List<ModifierToken> modifiers = [];
|
||||
|
||||
while (TryExpectModifier(out var modifier))
|
||||
{
|
||||
modifiers.Add(modifier);
|
||||
}
|
||||
|
||||
var keyword = ExpectSymbol();
|
||||
var node = keyword.Symbol switch
|
||||
{
|
||||
Symbol.Func => ParseFunc(startIndex, modifiers),
|
||||
Symbol.Extern => ParseExtern(startIndex),
|
||||
Symbol.Func => ParseFunc(startIndex),
|
||||
Symbol.Struct => ParseStruct(startIndex),
|
||||
Symbol.Trait => ParseTrait(startIndex),
|
||||
Symbol.Impl => ParseImplementation(startIndex),
|
||||
@@ -74,19 +69,52 @@ public sealed class Parser
|
||||
.Build())
|
||||
};
|
||||
|
||||
if (modifiers.Count != 0)
|
||||
{
|
||||
throw new ParseException(Diagnostic
|
||||
.Error($"Invalid modifiers: {string.Join(", ", modifiers.Select(x => x.Modifier))}")
|
||||
.WithHelp($"Remove the following modifiers: {modifiers.Select(x => x.Modifier)}'")
|
||||
.At(SourceSpan.Merge(modifiers.Select(x => x.Span)))
|
||||
.Build());
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
private DefinitionSyntax ParseFunc(int startIndex, List<ModifierToken> modifiers)
|
||||
private DefinitionSyntax ParseExtern(int startIndex)
|
||||
{
|
||||
var keyword = ExpectSymbol();
|
||||
return keyword.Symbol switch
|
||||
{
|
||||
Symbol.Func => ParseExternFunc(startIndex),
|
||||
_ => throw new ParseException(Diagnostic.Error($"Unexpected symbol {keyword.Symbol} after extern declaration").At(keyword).Build())
|
||||
};
|
||||
}
|
||||
|
||||
private ExternFuncSyntax ParseExternFunc(int startIndex)
|
||||
{
|
||||
var name = ExpectIdentifier();
|
||||
List<FuncParameterSyntax> parameters = [];
|
||||
|
||||
ExpectSymbol(Symbol.OpenParen);
|
||||
|
||||
while (!TryExpectSymbol(Symbol.CloseParen))
|
||||
{
|
||||
parameters.Add(ParseFuncParameter());
|
||||
|
||||
if (!TryExpectSymbol(Symbol.Comma) && Peek().TryGetValue(out var token) && token is not SymbolToken { Symbol: Symbol.CloseParen })
|
||||
{
|
||||
_diagnostics.Add(Diagnostic
|
||||
.Warning("Missing comma between function parameters")
|
||||
.WithHelp("Add a ',' to separate parameters")
|
||||
.At(token)
|
||||
.Build());
|
||||
}
|
||||
}
|
||||
|
||||
var returnType = TryExpectSymbol(Symbol.Colon) ? ParseType() : new NubVoidType();
|
||||
var callName = name.Value;
|
||||
|
||||
if (TryExpectSymbol(Symbol.Calls))
|
||||
{
|
||||
callName = ExpectIdentifier().Value;
|
||||
}
|
||||
|
||||
return new ExternFuncSyntax(GetTokens(startIndex), _namespace, name.Value, callName, parameters, returnType);
|
||||
}
|
||||
|
||||
private LocalFuncSyntax ParseFunc(int startIndex)
|
||||
{
|
||||
var name = ExpectIdentifier();
|
||||
List<FuncParameterSyntax> parameters = [];
|
||||
@@ -110,32 +138,9 @@ public sealed class Parser
|
||||
var returnType = TryExpectSymbol(Symbol.Colon) ? ParseType() : new NubVoidType();
|
||||
_functionReturnType = returnType;
|
||||
|
||||
var isExtern = modifiers.RemoveAll(x => x.Modifier == Modifier.Extern) > 0;
|
||||
if (isExtern)
|
||||
{
|
||||
if (modifiers.Count != 0)
|
||||
{
|
||||
throw new ParseException(Diagnostic
|
||||
.Error($"Invalid modifier for extern function: {modifiers[0].Modifier}")
|
||||
.WithHelp($"Extern functions cannot use the '{modifiers[0].Modifier}' modifier")
|
||||
.At(modifiers[0])
|
||||
.Build());
|
||||
}
|
||||
|
||||
var callName = name.Value;
|
||||
|
||||
if (TryExpectSymbol(Symbol.Calls))
|
||||
{
|
||||
callName = ExpectIdentifier().Value;
|
||||
}
|
||||
|
||||
return new ExternFuncSyntax(GetTokens(startIndex), _namespace, name.Value, callName, parameters, returnType);
|
||||
}
|
||||
|
||||
var body = ParseBlock();
|
||||
var exported = modifiers.RemoveAll(x => x.Modifier == Modifier.Export) > 0;
|
||||
|
||||
return new LocalFuncSyntax(GetTokens(startIndex), _namespace, name.Value, parameters, body, returnType, exported);
|
||||
return new LocalFuncSyntax(GetTokens(startIndex), _namespace, name.Value, parameters, body, returnType);
|
||||
}
|
||||
|
||||
private StructSyntax ParseStruct(int startIndex)
|
||||
@@ -657,7 +662,7 @@ public sealed class Parser
|
||||
catch (ParseException ex)
|
||||
{
|
||||
_diagnostics.Add(ex.Diagnostic);
|
||||
RecoverToNextStatement();
|
||||
Next();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -805,19 +810,6 @@ public sealed class Parser
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool TryExpectModifier([NotNullWhen(true)] out ModifierToken? modifier)
|
||||
{
|
||||
if (Peek() is { Value: ModifierToken modifierToken })
|
||||
{
|
||||
modifier = modifierToken;
|
||||
Next();
|
||||
return true;
|
||||
}
|
||||
|
||||
modifier = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool TryExpectIdentifier([NotNullWhen(true)] out IdentifierToken? identifier)
|
||||
{
|
||||
if (Peek() is { Value: IdentifierToken identifierToken })
|
||||
@@ -851,23 +843,7 @@ public sealed class Parser
|
||||
while (Peek().HasValue)
|
||||
{
|
||||
var token = Peek().Value;
|
||||
if (token is SymbolToken { Symbol: Symbol.Func or Symbol.Struct or Symbol.Trait or Symbol.Impl } or ModifierToken)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Next();
|
||||
}
|
||||
}
|
||||
|
||||
private void RecoverToNextStatement()
|
||||
{
|
||||
while (Peek().TryGetValue(out var token))
|
||||
{
|
||||
if (token is SymbolToken { Symbol: Symbol.CloseBrace } or IdentifierToken or SymbolToken
|
||||
{
|
||||
Symbol: Symbol.Return or Symbol.If or Symbol.While or Symbol.Let or Symbol.Break or Symbol.Continue
|
||||
})
|
||||
if (token is SymbolToken { Symbol: Symbol.Extern or Symbol.Func or Symbol.Struct or Symbol.Trait or Symbol.Impl })
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -24,17 +24,6 @@ public enum LiteralKind
|
||||
Bool
|
||||
}
|
||||
|
||||
public class ModifierToken(SourceSpan span, Modifier modifier) : Token(span)
|
||||
{
|
||||
public Modifier Modifier { get; } = modifier;
|
||||
}
|
||||
|
||||
public enum Modifier
|
||||
{
|
||||
Extern,
|
||||
Export
|
||||
}
|
||||
|
||||
public class SymbolToken(SourceSpan span, Symbol symbol) : Token(span)
|
||||
{
|
||||
public Symbol Symbol { get; } = symbol;
|
||||
@@ -80,5 +69,6 @@ public enum Symbol
|
||||
Calls,
|
||||
Trait,
|
||||
Impl,
|
||||
For
|
||||
For,
|
||||
Extern
|
||||
}
|
||||
@@ -22,12 +22,7 @@ public sealed class Tokenizer
|
||||
["trait"] = Symbol.Trait,
|
||||
["impl"] = Symbol.Impl,
|
||||
["for"] = Symbol.For,
|
||||
};
|
||||
|
||||
private static readonly Dictionary<string, Modifier> Modifiers = new()
|
||||
{
|
||||
["export"] = Modifier.Export,
|
||||
["extern"] = Modifier.Extern,
|
||||
["extern"] = Symbol.Extern
|
||||
};
|
||||
|
||||
private static readonly Dictionary<char[], Symbol> Chians = new()
|
||||
@@ -129,11 +124,6 @@ public sealed class Tokenizer
|
||||
return new SymbolToken(CreateSpan(startIndex), keywordSymbol);
|
||||
}
|
||||
|
||||
if (Modifiers.TryGetValue(buffer, out var modifer))
|
||||
{
|
||||
return new ModifierToken(CreateSpan(startIndex), modifer);
|
||||
}
|
||||
|
||||
if (buffer is "true" or "false")
|
||||
{
|
||||
return new LiteralToken(CreateSpan(startIndex), LiteralKind.Bool, buffer);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
.globl _start
|
||||
_start:
|
||||
mov rdi, rsp
|
||||
call main
|
||||
call default_main
|
||||
mov rdi, rax
|
||||
mov rax, 60
|
||||
syscall
|
||||
|
||||
Reference in New Issue
Block a user