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
|
let human = alloc human
|
||||||
{
|
{
|
||||||
|
|||||||
Binary file not shown.
@@ -71,8 +71,6 @@ public static class ConsoleColors
|
|||||||
LiteralKind.Bool => Blue,
|
LiteralKind.Bool => Blue,
|
||||||
_ => White
|
_ => White
|
||||||
};
|
};
|
||||||
case ModifierToken:
|
|
||||||
return White;
|
|
||||||
case SymbolToken symbol:
|
case SymbolToken symbol:
|
||||||
switch (symbol.Symbol)
|
switch (symbol.Symbol)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -67,19 +67,19 @@ public partial class QBEGenerator
|
|||||||
|
|
||||||
foreach (var funcDef in _syntaxTree.Definitions.OfType<BoundLocalFunc>())
|
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();
|
_writer.NewLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (_anonymousFunctions.TryDequeue(out var anon))
|
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();
|
_writer.NewLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var (impl, name) in _implFunctions)
|
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();
|
_writer.NewLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,7 +347,7 @@ public partial class QBEGenerator
|
|||||||
return "l";
|
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();
|
_variables.Clear();
|
||||||
_variableScopes.Clear();
|
_variableScopes.Clear();
|
||||||
@@ -356,12 +356,7 @@ public partial class QBEGenerator
|
|||||||
|
|
||||||
var builder = new StringBuilder();
|
var builder = new StringBuilder();
|
||||||
|
|
||||||
if (exported)
|
builder.Append("export function ");
|
||||||
{
|
|
||||||
builder.Append("export ");
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.Append("function ");
|
|
||||||
if (returnType is not NubVoidType)
|
if (returnType is not NubVoidType)
|
||||||
{
|
{
|
||||||
builder.Append(FuncQBETypeName(returnType) + ' ');
|
builder.Append(FuncQBETypeName(returnType) + ' ');
|
||||||
@@ -503,7 +498,7 @@ public partial class QBEGenerator
|
|||||||
|
|
||||||
private string LocalFuncName(BoundLocalFunc funcDef)
|
private string LocalFuncName(BoundLocalFunc funcDef)
|
||||||
{
|
{
|
||||||
return funcDef.Exported ? $"${funcDef.Name}" : $"${funcDef.Namespace}_{funcDef.Name}";
|
return $"${funcDef.Namespace}_{funcDef.Name}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ExternFuncName(BoundExternFunc funcDef)
|
private string ExternFuncName(BoundExternFunc funcDef)
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ public sealed class Binder
|
|||||||
|
|
||||||
var body = BindBlock(node.Body);
|
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)
|
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 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);
|
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 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);
|
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)
|
public Parser(IEnumerable<Token> tokens)
|
||||||
{
|
{
|
||||||
_namespace = "global";
|
_namespace = "default";
|
||||||
_tokens = tokens;
|
_tokens = tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ public sealed class Parser
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
definitions.Add(ParseTopLevel());
|
definitions.Add(ParseDefinition());
|
||||||
}
|
}
|
||||||
catch (ParseException ex)
|
catch (ParseException ex)
|
||||||
{
|
{
|
||||||
@@ -50,20 +50,15 @@ public sealed class Parser
|
|||||||
return new SyntaxTree(_namespace, definitions, _diagnostics);
|
return new SyntaxTree(_namespace, definitions, _diagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DefinitionSyntax ParseTopLevel()
|
private DefinitionSyntax ParseDefinition()
|
||||||
{
|
{
|
||||||
var startIndex = _tokenIndex;
|
var startIndex = _tokenIndex;
|
||||||
List<ModifierToken> modifiers = [];
|
|
||||||
|
|
||||||
while (TryExpectModifier(out var modifier))
|
|
||||||
{
|
|
||||||
modifiers.Add(modifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
var keyword = ExpectSymbol();
|
var keyword = ExpectSymbol();
|
||||||
var node = keyword.Symbol switch
|
var node = keyword.Symbol switch
|
||||||
{
|
{
|
||||||
Symbol.Func => ParseFunc(startIndex, modifiers),
|
Symbol.Extern => ParseExtern(startIndex),
|
||||||
|
Symbol.Func => ParseFunc(startIndex),
|
||||||
Symbol.Struct => ParseStruct(startIndex),
|
Symbol.Struct => ParseStruct(startIndex),
|
||||||
Symbol.Trait => ParseTrait(startIndex),
|
Symbol.Trait => ParseTrait(startIndex),
|
||||||
Symbol.Impl => ParseImplementation(startIndex),
|
Symbol.Impl => ParseImplementation(startIndex),
|
||||||
@@ -74,19 +69,52 @@ public sealed class Parser
|
|||||||
.Build())
|
.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;
|
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();
|
var name = ExpectIdentifier();
|
||||||
List<FuncParameterSyntax> parameters = [];
|
List<FuncParameterSyntax> parameters = [];
|
||||||
@@ -110,32 +138,9 @@ public sealed class Parser
|
|||||||
var returnType = TryExpectSymbol(Symbol.Colon) ? ParseType() : new NubVoidType();
|
var returnType = TryExpectSymbol(Symbol.Colon) ? ParseType() : new NubVoidType();
|
||||||
_functionReturnType = returnType;
|
_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 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)
|
private StructSyntax ParseStruct(int startIndex)
|
||||||
@@ -657,7 +662,7 @@ public sealed class Parser
|
|||||||
catch (ParseException ex)
|
catch (ParseException ex)
|
||||||
{
|
{
|
||||||
_diagnostics.Add(ex.Diagnostic);
|
_diagnostics.Add(ex.Diagnostic);
|
||||||
RecoverToNextStatement();
|
Next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -805,19 +810,6 @@ public sealed class Parser
|
|||||||
return false;
|
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)
|
private bool TryExpectIdentifier([NotNullWhen(true)] out IdentifierToken? identifier)
|
||||||
{
|
{
|
||||||
if (Peek() is { Value: IdentifierToken identifierToken })
|
if (Peek() is { Value: IdentifierToken identifierToken })
|
||||||
@@ -851,23 +843,7 @@ public sealed class Parser
|
|||||||
while (Peek().HasValue)
|
while (Peek().HasValue)
|
||||||
{
|
{
|
||||||
var token = Peek().Value;
|
var token = Peek().Value;
|
||||||
if (token is SymbolToken { Symbol: Symbol.Func or Symbol.Struct or Symbol.Trait or Symbol.Impl } or ModifierToken)
|
if (token is SymbolToken { Symbol: Symbol.Extern or Symbol.Func or Symbol.Struct or Symbol.Trait or Symbol.Impl })
|
||||||
{
|
|
||||||
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
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,17 +24,6 @@ public enum LiteralKind
|
|||||||
Bool
|
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 class SymbolToken(SourceSpan span, Symbol symbol) : Token(span)
|
||||||
{
|
{
|
||||||
public Symbol Symbol { get; } = symbol;
|
public Symbol Symbol { get; } = symbol;
|
||||||
@@ -80,5 +69,6 @@ public enum Symbol
|
|||||||
Calls,
|
Calls,
|
||||||
Trait,
|
Trait,
|
||||||
Impl,
|
Impl,
|
||||||
For
|
For,
|
||||||
|
Extern
|
||||||
}
|
}
|
||||||
@@ -22,12 +22,7 @@ public sealed class Tokenizer
|
|||||||
["trait"] = Symbol.Trait,
|
["trait"] = Symbol.Trait,
|
||||||
["impl"] = Symbol.Impl,
|
["impl"] = Symbol.Impl,
|
||||||
["for"] = Symbol.For,
|
["for"] = Symbol.For,
|
||||||
};
|
["extern"] = Symbol.Extern
|
||||||
|
|
||||||
private static readonly Dictionary<string, Modifier> Modifiers = new()
|
|
||||||
{
|
|
||||||
["export"] = Modifier.Export,
|
|
||||||
["extern"] = Modifier.Extern,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly Dictionary<char[], Symbol> Chians = new()
|
private static readonly Dictionary<char[], Symbol> Chians = new()
|
||||||
@@ -129,11 +124,6 @@ public sealed class Tokenizer
|
|||||||
return new SymbolToken(CreateSpan(startIndex), keywordSymbol);
|
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")
|
if (buffer is "true" or "false")
|
||||||
{
|
{
|
||||||
return new LiteralToken(CreateSpan(startIndex), LiteralKind.Bool, buffer);
|
return new LiteralToken(CreateSpan(startIndex), LiteralKind.Bool, buffer);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
.globl _start
|
.globl _start
|
||||||
_start:
|
_start:
|
||||||
mov rdi, rsp
|
mov rdi, rsp
|
||||||
call main
|
call default_main
|
||||||
mov rdi, rax
|
mov rdi, rax
|
||||||
mov rax, 60
|
mov rax, 60
|
||||||
syscall
|
syscall
|
||||||
|
|||||||
Reference in New Issue
Block a user