module exports and name mangling
This commit is contained in:
@@ -24,13 +24,15 @@ public sealed class Generator(List<TypedNodeDefinitionFunc> functions, ModuleGra
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
struct string {
|
struct nub_core_string
|
||||||
|
{
|
||||||
const char *data;
|
const char *data;
|
||||||
int length;
|
int length;
|
||||||
};
|
};
|
||||||
|
|
||||||
""");
|
""");
|
||||||
|
|
||||||
|
writer.WriteLine();
|
||||||
|
|
||||||
foreach (var typeName in structTypeNames)
|
foreach (var typeName in structTypeNames)
|
||||||
writer.WriteLine($"struct {typeName.Value};");
|
writer.WriteLine($"struct {typeName.Value};");
|
||||||
|
|
||||||
@@ -38,7 +40,14 @@ public sealed class Generator(List<TypedNodeDefinitionFunc> functions, ModuleGra
|
|||||||
|
|
||||||
foreach (var typeName in structTypeNames)
|
foreach (var typeName in structTypeNames)
|
||||||
{
|
{
|
||||||
writer.WriteLine($"struct {typeName.Value}");
|
writer.Write("struct ");
|
||||||
|
|
||||||
|
if (typeName.Key.Packed)
|
||||||
|
{
|
||||||
|
writer.Write("__attribute__((__packed__)) ");
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WriteLine(typeName.Value);
|
||||||
writer.WriteLine("{");
|
writer.WriteLine("{");
|
||||||
using (writer.Indent())
|
using (writer.Indent())
|
||||||
{
|
{
|
||||||
@@ -74,13 +83,12 @@ public sealed class Generator(List<TypedNodeDefinitionFunc> functions, ModuleGra
|
|||||||
|
|
||||||
if (main != null)
|
if (main != null)
|
||||||
{
|
{
|
||||||
writer.WriteLine("int main(int argc, char *argv[])");
|
writer.WriteLine($$"""
|
||||||
writer.WriteLine("{");
|
int main(int argc, char *argv[])
|
||||||
using (writer.Indent())
|
|
||||||
{
|
{
|
||||||
writer.WriteLine($"return {main.GetMangledName()}();");
|
return {{main.GetMangledName()}}();
|
||||||
}
|
}
|
||||||
writer.WriteLine("}");
|
""");
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteLine();
|
writer.WriteLine();
|
||||||
@@ -216,7 +224,7 @@ public sealed class Generator(List<TypedNodeDefinitionFunc> functions, ModuleGra
|
|||||||
TypedNodeExpressionUnary expression => EmitExpressionUnary(expression),
|
TypedNodeExpressionUnary expression => EmitExpressionUnary(expression),
|
||||||
TypedNodeExpressionBoolLiteral expression => expression.Value.Value ? "true" : "false",
|
TypedNodeExpressionBoolLiteral expression => expression.Value.Value ? "true" : "false",
|
||||||
TypedNodeExpressionIntLiteral expression => expression.Value.Value.ToString(),
|
TypedNodeExpressionIntLiteral expression => expression.Value.Value.ToString(),
|
||||||
TypedNodeExpressionStringLiteral expression => $"(struct string){{ \"{expression.Value.Value}\", {expression.Value.Value.Length} }}",
|
TypedNodeExpressionStringLiteral expression => $"(struct nub_core_string){{ \"{expression.Value.Value}\", {expression.Value.Value.Length} }}",
|
||||||
TypedNodeExpressionStructLiteral expression => EmitExpressionStructLiteral(expression),
|
TypedNodeExpressionStructLiteral expression => EmitExpressionStructLiteral(expression),
|
||||||
TypedNodeExpressionMemberAccess expression => EmitExpressionMemberAccess(expression),
|
TypedNodeExpressionMemberAccess expression => EmitExpressionMemberAccess(expression),
|
||||||
TypedNodeExpressionLocalIdent expression => expression.Value.Ident,
|
TypedNodeExpressionLocalIdent expression => expression.Value.Ident,
|
||||||
@@ -302,7 +310,7 @@ public sealed class Generator(List<TypedNodeDefinitionFunc> functions, ModuleGra
|
|||||||
NubTypeSInt type => $"int{type.Width}_t" + (varName != null ? $" {varName}" : ""),
|
NubTypeSInt type => $"int{type.Width}_t" + (varName != null ? $" {varName}" : ""),
|
||||||
NubTypeUInt type => $"uint{type.Width}_t" + (varName != null ? $" {varName}" : ""),
|
NubTypeUInt type => $"uint{type.Width}_t" + (varName != null ? $" {varName}" : ""),
|
||||||
NubTypePointer type => CType(type.To) + (varName != null ? $" *{varName}" : "*"),
|
NubTypePointer type => CType(type.To) + (varName != null ? $" *{varName}" : "*"),
|
||||||
NubTypeString => "struct string" + (varName != null ? $" {varName}" : ""),
|
NubTypeString => "struct nub_core_string" + (varName != null ? $" {varName}" : ""),
|
||||||
NubTypeFunc type => $"{CType(type.ReturnType)} (*{varName})({string.Join(", ", type.Parameters.Select(p => CType(p)))})",
|
NubTypeFunc type => $"{CType(type.ReturnType)} (*{varName})({string.Join(", ", type.Parameters.Select(p => CType(p)))})",
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(node), node, null)
|
_ => throw new ArgumentOutOfRangeException(nameof(node), node, null)
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,40 +21,69 @@ public class ModuleGraph(Dictionary<string, ModuleGraph.Module> modules)
|
|||||||
public sealed class Module(string name)
|
public sealed class Module(string name)
|
||||||
{
|
{
|
||||||
public string Name { get; } = name;
|
public string Name { get; } = name;
|
||||||
private readonly Dictionary<string, NubType> customTypes = new();
|
private readonly Dictionary<string, CustomTypeInfo> customTypes = new();
|
||||||
private readonly Dictionary<string, NubType> identifierTypes = new();
|
private readonly Dictionary<string, IdentifierInfo> identifierTypes = new();
|
||||||
|
|
||||||
public IReadOnlyList<NubType> GetCustomTypes()
|
public IReadOnlyList<NubType> GetCustomTypes()
|
||||||
{
|
{
|
||||||
return customTypes.Values.ToList();
|
return customTypes.Values.Select(x => x.Type).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IReadOnlyDictionary<string, NubType> GetIdentifierTypes()
|
public IReadOnlyDictionary<string, NubType> GetIdentifierTypes()
|
||||||
{
|
{
|
||||||
return identifierTypes;
|
return identifierTypes.ToDictionary(x => x.Key, x => x.Value.Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryResolveCustomType(string name, [NotNullWhen(true)] out NubType? customType)
|
public bool TryResolveCustomType(string name, bool searchPrivate, [NotNullWhen(true)] out NubType? customType)
|
||||||
{
|
{
|
||||||
customType = customTypes.GetValueOrDefault(name);
|
var info = customTypes.GetValueOrDefault(name);
|
||||||
return customType != null;
|
if (info == null)
|
||||||
|
{
|
||||||
|
customType = null;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryResolveIdentifierType(string name, [NotNullWhen(true)] out NubType? identifier)
|
if (info.Exported || searchPrivate)
|
||||||
{
|
{
|
||||||
identifier = identifierTypes.GetValueOrDefault(name);
|
customType = info.Type;
|
||||||
return identifier != null;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddCustomType(string name, NubType type)
|
customType = null;
|
||||||
{
|
return false;
|
||||||
customTypes.Add(name, type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddIdentifier(string name, NubType identifier)
|
public bool TryResolveIdentifierType(string name, bool searchPrivate, [NotNullWhen(true)] out NubType? identifierType)
|
||||||
{
|
{
|
||||||
identifierTypes.Add(name, identifier);
|
var info = identifierTypes.GetValueOrDefault(name);
|
||||||
|
if (info == null)
|
||||||
|
{
|
||||||
|
identifierType = null;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (info.Exported || searchPrivate)
|
||||||
|
{
|
||||||
|
identifierType = info.Type;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
identifierType = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddCustomType(string name, NubType type, bool exported)
|
||||||
|
{
|
||||||
|
customTypes.Add(name, new CustomTypeInfo(type, exported));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddIdentifier(string name, NubType type, bool exported)
|
||||||
|
{
|
||||||
|
identifierTypes.Add(name, new IdentifierInfo(type, exported));
|
||||||
|
}
|
||||||
|
|
||||||
|
private record CustomTypeInfo(NubType Type, bool Exported);
|
||||||
|
private record IdentifierInfo(NubType Type, bool Exported);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Builder
|
public class Builder
|
||||||
@@ -91,7 +120,7 @@ public class ModuleGraph(Dictionary<string, ModuleGraph.Module> modules)
|
|||||||
if (module == null) continue;
|
if (module == null) continue;
|
||||||
|
|
||||||
foreach (var structDef in ast.Definitions.OfType<NodeDefinitionStruct>())
|
foreach (var structDef in ast.Definitions.OfType<NodeDefinitionStruct>())
|
||||||
module.AddCustomType(structDef.Name.Ident, new NubTypeStruct(module.Name, structDef.Name.Ident));
|
module.AddCustomType(structDef.Name.Ident, new NubTypeStruct(module.Name, structDef.Name.Ident, structDef.Packed), structDef.Exported);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Third pass: Resolve struct fields
|
// Third pass: Resolve struct fields
|
||||||
@@ -102,10 +131,10 @@ public class ModuleGraph(Dictionary<string, ModuleGraph.Module> modules)
|
|||||||
|
|
||||||
foreach (var structDef in ast.Definitions.OfType<NodeDefinitionStruct>())
|
foreach (var structDef in ast.Definitions.OfType<NodeDefinitionStruct>())
|
||||||
{
|
{
|
||||||
if (!module.TryResolveCustomType(structDef.Name.Ident, out var customType))
|
if (!module.TryResolveCustomType(structDef.Name.Ident, true, out var customType))
|
||||||
throw new UnreachableException($"{nameof(customType)} should always be registered");
|
throw new UnreachableException($"{nameof(customType)} should always be registered");
|
||||||
|
|
||||||
var fields = structDef.Fields.Select(f => new NubTypeStruct.Field(f.Name.Ident, ResolveType(f.Type))).ToList();
|
var fields = structDef.Fields.Select(f => new NubTypeStruct.Field(f.Name.Ident, ResolveType(f.Type, true))).ToList();
|
||||||
((NubTypeStruct)customType).ResolveFields(fields);
|
((NubTypeStruct)customType).ResolveFields(fields);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,10 +147,10 @@ public class ModuleGraph(Dictionary<string, ModuleGraph.Module> modules)
|
|||||||
|
|
||||||
foreach (var funcDef in ast.Definitions.OfType<NodeDefinitionFunc>())
|
foreach (var funcDef in ast.Definitions.OfType<NodeDefinitionFunc>())
|
||||||
{
|
{
|
||||||
var parameters = funcDef.Parameters.Select(x => ResolveType(x.Type)).ToList();
|
var parameters = funcDef.Parameters.Select(x => ResolveType(x.Type, true)).ToList();
|
||||||
var returnType = ResolveType(funcDef.ReturnType);
|
var returnType = ResolveType(funcDef.ReturnType, true);
|
||||||
var funcType = NubTypeFunc.Get(parameters, returnType);
|
var funcType = NubTypeFunc.Get(parameters, returnType);
|
||||||
module.AddIdentifier(funcDef.Name.Ident, funcType);
|
module.AddIdentifier(funcDef.Name.Ident, funcType, funcDef.Exported);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,14 +159,14 @@ public class ModuleGraph(Dictionary<string, ModuleGraph.Module> modules)
|
|||||||
|
|
||||||
return new ModuleGraph(modules);
|
return new ModuleGraph(modules);
|
||||||
|
|
||||||
NubType ResolveType(NodeType node)
|
NubType ResolveType(NodeType node, bool includePrivate)
|
||||||
{
|
{
|
||||||
return node switch
|
return node switch
|
||||||
{
|
{
|
||||||
NodeTypeBool => NubTypeBool.Instance,
|
NodeTypeBool => NubTypeBool.Instance,
|
||||||
NodeTypeCustom type => ResolveCustomType(type),
|
NodeTypeCustom type => ResolveCustomType(type, includePrivate),
|
||||||
NodeTypeFunc type => NubTypeFunc.Get(type.Parameters.Select(ResolveType).ToList(), ResolveType(type.ReturnType)),
|
NodeTypeFunc type => NubTypeFunc.Get(type.Parameters.Select(x => ResolveType(x, includePrivate)).ToList(), ResolveType(type.ReturnType, includePrivate)),
|
||||||
NodeTypePointer type => NubTypePointer.Get(ResolveType(type.To)),
|
NodeTypePointer type => NubTypePointer.Get(ResolveType(type.To, includePrivate)),
|
||||||
NodeTypeSInt type => NubTypeSInt.Get(type.Width),
|
NodeTypeSInt type => NubTypeSInt.Get(type.Width),
|
||||||
NodeTypeUInt type => NubTypeUInt.Get(type.Width),
|
NodeTypeUInt type => NubTypeUInt.Get(type.Width),
|
||||||
NodeTypeString => NubTypeString.Instance,
|
NodeTypeString => NubTypeString.Instance,
|
||||||
@@ -146,13 +175,13 @@ public class ModuleGraph(Dictionary<string, ModuleGraph.Module> modules)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
NubType ResolveCustomType(NodeTypeCustom type)
|
NubType ResolveCustomType(NodeTypeCustom type, bool includePrivate)
|
||||||
{
|
{
|
||||||
var module = modules.GetValueOrDefault(type.Module.Ident);
|
var module = modules.GetValueOrDefault(type.Module.Ident);
|
||||||
if (module == null)
|
if (module == null)
|
||||||
throw new CompileException(Diagnostic.Error($"Unknown module: {type.Module.Ident}").Build());
|
throw new CompileException(Diagnostic.Error($"Unknown module: {type.Module.Ident}").Build());
|
||||||
|
|
||||||
if (!module.TryResolveCustomType(type.Name.Ident, out var customType))
|
if (!module.TryResolveCustomType(type.Name.Ident, includePrivate, out var customType))
|
||||||
throw new CompileException(Diagnostic.Error($"Unknown custom type: {type.Module.Ident}::{type.Name.Ident}").Build());
|
throw new CompileException(Diagnostic.Error($"Unknown custom type: {type.Module.Ident}::{type.Name.Ident}").Build());
|
||||||
|
|
||||||
return customType;
|
return customType;
|
||||||
|
|||||||
@@ -88,15 +88,17 @@ public sealed class NubTypeStruct : NubType
|
|||||||
{
|
{
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
public string Module { get; }
|
public string Module { get; }
|
||||||
|
public bool Packed { get; }
|
||||||
|
|
||||||
private IReadOnlyList<Field>? _resolvedFields;
|
private IReadOnlyList<Field>? _resolvedFields;
|
||||||
|
|
||||||
public IReadOnlyList<Field> Fields => _resolvedFields ?? throw new InvalidOperationException();
|
public IReadOnlyList<Field> Fields => _resolvedFields ?? throw new InvalidOperationException();
|
||||||
|
|
||||||
public NubTypeStruct(string module, string name)
|
public NubTypeStruct(string module, string name, bool packed)
|
||||||
{
|
{
|
||||||
Module = module;
|
Module = module;
|
||||||
Name = name;
|
Name = name;
|
||||||
|
Packed = packed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResolveFields(IReadOnlyList<Field> fields)
|
public void ResolveFields(IReadOnlyList<Field> fields)
|
||||||
|
|||||||
@@ -43,8 +43,38 @@ public sealed class Parser(string fileName, List<Token> tokens)
|
|||||||
{
|
{
|
||||||
var startIndex = index;
|
var startIndex = index;
|
||||||
|
|
||||||
|
Dictionary<Keyword, TokenKeyword> modifiers = [];
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (Peek() is TokenKeyword keyword)
|
||||||
|
{
|
||||||
|
switch (keyword.Keyword)
|
||||||
|
{
|
||||||
|
case Keyword.Export:
|
||||||
|
Next();
|
||||||
|
modifiers[Keyword.Export] = keyword;
|
||||||
|
break;
|
||||||
|
case Keyword.Packed:
|
||||||
|
Next();
|
||||||
|
modifiers[Keyword.Packed] = keyword;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto modifier_done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modifier_done:
|
||||||
|
|
||||||
if (TryExpectKeyword(Keyword.Func))
|
if (TryExpectKeyword(Keyword.Func))
|
||||||
{
|
{
|
||||||
|
var exported = modifiers.Remove(Keyword.Export);
|
||||||
|
|
||||||
|
foreach (var modifier in modifiers)
|
||||||
|
// todo(nub31): Add to diagnostics instead of throwing
|
||||||
|
throw new CompileException(Diagnostic.Error("Invalid modifier for function").At(fileName, modifier.Value).Build());
|
||||||
|
|
||||||
var name = ExpectIdent();
|
var name = ExpectIdent();
|
||||||
var parameters = new List<NodeDefinitionFunc.Param>();
|
var parameters = new List<NodeDefinitionFunc.Param>();
|
||||||
|
|
||||||
@@ -63,11 +93,18 @@ public sealed class Parser(string fileName, List<Token> tokens)
|
|||||||
|
|
||||||
var body = ParseStatement();
|
var body = ParseStatement();
|
||||||
|
|
||||||
return new NodeDefinitionFunc(TokensFrom(startIndex), name, parameters, body, returnType);
|
return new NodeDefinitionFunc(TokensFrom(startIndex), exported, name, parameters, body, returnType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TryExpectKeyword(Keyword.Struct))
|
if (TryExpectKeyword(Keyword.Struct))
|
||||||
{
|
{
|
||||||
|
var exported = modifiers.Remove(Keyword.Export);
|
||||||
|
var packed = modifiers.Remove(Keyword.Packed);
|
||||||
|
|
||||||
|
foreach (var modifier in modifiers)
|
||||||
|
// todo(nub31): Add to diagnostics instead of throwing
|
||||||
|
throw new CompileException(Diagnostic.Error("Invalid modifier for struct").At(fileName, modifier.Value).Build());
|
||||||
|
|
||||||
var name = ExpectIdent();
|
var name = ExpectIdent();
|
||||||
var fields = new List<NodeDefinitionStruct.Field>();
|
var fields = new List<NodeDefinitionStruct.Field>();
|
||||||
|
|
||||||
@@ -81,7 +118,7 @@ public sealed class Parser(string fileName, List<Token> tokens)
|
|||||||
fields.Add(new NodeDefinitionStruct.Field(TokensFrom(fieldStartIndex), fieldName, fieldType));
|
fields.Add(new NodeDefinitionStruct.Field(TokensFrom(fieldStartIndex), fieldName, fieldType));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new NodeDefinitionStruct(TokensFrom(startIndex), name, fields);
|
return new NodeDefinitionStruct(TokensFrom(startIndex), exported, packed, name, fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new CompileException(Diagnostic.Error("Not a valid definition").At(fileName, Peek()).Build());
|
throw new CompileException(Diagnostic.Error("Not a valid definition").At(fileName, Peek()).Build());
|
||||||
@@ -556,8 +593,9 @@ public abstract class Node(List<Token> tokens)
|
|||||||
|
|
||||||
public abstract class NodeDefinition(List<Token> tokens) : Node(tokens);
|
public abstract class NodeDefinition(List<Token> tokens) : Node(tokens);
|
||||||
|
|
||||||
public sealed class NodeDefinitionFunc(List<Token> tokens, TokenIdent name, List<NodeDefinitionFunc.Param> parameters, NodeStatement body, NodeType returnType) : NodeDefinition(tokens)
|
public sealed class NodeDefinitionFunc(List<Token> tokens, bool exported, TokenIdent name, List<NodeDefinitionFunc.Param> parameters, NodeStatement body, NodeType returnType) : NodeDefinition(tokens)
|
||||||
{
|
{
|
||||||
|
public bool Exported { get; } = exported;
|
||||||
public TokenIdent Name { get; } = name;
|
public TokenIdent Name { get; } = name;
|
||||||
public List<Param> Parameters { get; } = parameters;
|
public List<Param> Parameters { get; } = parameters;
|
||||||
public NodeStatement Body { get; } = body;
|
public NodeStatement Body { get; } = body;
|
||||||
@@ -570,8 +608,10 @@ public sealed class NodeDefinitionFunc(List<Token> tokens, TokenIdent name, List
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class NodeDefinitionStruct(List<Token> tokens, TokenIdent name, List<NodeDefinitionStruct.Field> fields) : NodeDefinition(tokens)
|
public sealed class NodeDefinitionStruct(List<Token> tokens, bool exported, bool packed, TokenIdent name, List<NodeDefinitionStruct.Field> fields) : NodeDefinition(tokens)
|
||||||
{
|
{
|
||||||
|
public bool Exported { get; } = exported;
|
||||||
|
public bool Packed { get; } = packed;
|
||||||
public TokenIdent Name { get; } = name;
|
public TokenIdent Name { get; } = name;
|
||||||
public List<Field> Fields { get; } = fields;
|
public List<Field> Fields { get; } = fields;
|
||||||
|
|
||||||
|
|||||||
@@ -379,12 +379,14 @@ public sealed class Tokenizer(string fileName, string contents)
|
|||||||
{
|
{
|
||||||
"func" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Func),
|
"func" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Func),
|
||||||
"struct" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Struct),
|
"struct" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Struct),
|
||||||
|
"packed" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Packed),
|
||||||
"let" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Let),
|
"let" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Let),
|
||||||
"if" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.If),
|
"if" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.If),
|
||||||
"else" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Else),
|
"else" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Else),
|
||||||
"while" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.While),
|
"while" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.While),
|
||||||
"return" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Return),
|
"return" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Return),
|
||||||
"module" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Module),
|
"module" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Module),
|
||||||
|
"export" => new TokenKeyword(line, startColumn, column - startColumn, Keyword.Export),
|
||||||
"true" => new TokenBoolLiteral(line, startColumn, column - startColumn, true),
|
"true" => new TokenBoolLiteral(line, startColumn, column - startColumn, true),
|
||||||
"false" => new TokenBoolLiteral(line, startColumn, column - startColumn, false),
|
"false" => new TokenBoolLiteral(line, startColumn, column - startColumn, false),
|
||||||
_ => new TokenIdent(line, startColumn, column - startColumn, value)
|
_ => new TokenIdent(line, startColumn, column - startColumn, value)
|
||||||
@@ -523,12 +525,14 @@ public enum Keyword
|
|||||||
{
|
{
|
||||||
Func,
|
Func,
|
||||||
Struct,
|
Struct,
|
||||||
|
Packed,
|
||||||
Let,
|
Let,
|
||||||
If,
|
If,
|
||||||
Else,
|
Else,
|
||||||
While,
|
While,
|
||||||
Return,
|
Return,
|
||||||
Module,
|
Module,
|
||||||
|
Export,
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class TokenKeyword(int line, int column, int length, Keyword keyword) : Token(line, column, length)
|
public sealed class TokenKeyword(int line, int column, int length, Keyword keyword) : Token(line, column, length)
|
||||||
@@ -585,12 +589,14 @@ public static class TokenExtensions
|
|||||||
{
|
{
|
||||||
Keyword.Func => "func",
|
Keyword.Func => "func",
|
||||||
Keyword.Struct => "struct",
|
Keyword.Struct => "struct",
|
||||||
|
Keyword.Packed => "packed",
|
||||||
Keyword.Let => "let",
|
Keyword.Let => "let",
|
||||||
Keyword.If => "if",
|
Keyword.If => "if",
|
||||||
Keyword.Else => "else",
|
Keyword.Else => "else",
|
||||||
Keyword.While => "while",
|
Keyword.While => "while",
|
||||||
Keyword.Return => "return",
|
Keyword.Return => "return",
|
||||||
Keyword.Module => "module",
|
Keyword.Module => "module",
|
||||||
|
Keyword.Export => "export",
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(symbol), symbol, null)
|
_ => throw new ArgumentOutOfRangeException(nameof(symbol), symbol, null)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -291,7 +291,9 @@ public sealed class TypeChecker(string fileName, string moduleName, NodeDefiniti
|
|||||||
if (!moduleGraph.TryResolveModule(expression.Module.Ident, out var module))
|
if (!moduleGraph.TryResolveModule(expression.Module.Ident, out var module))
|
||||||
throw new CompileException(Diagnostic.Error($"Module '{expression.Module.Ident}' not found").At(fileName, expression.Module).Build());
|
throw new CompileException(Diagnostic.Error($"Module '{expression.Module.Ident}' not found").At(fileName, expression.Module).Build());
|
||||||
|
|
||||||
if (!module.TryResolveIdentifierType(expression.Value.Ident, out var identifierType))
|
var includePrivate = expression.Module.Ident == moduleName;
|
||||||
|
|
||||||
|
if (!module.TryResolveIdentifierType(expression.Value.Ident, includePrivate, out var identifierType))
|
||||||
throw new CompileException(Diagnostic.Error($"Identifier '{expression.Module.Ident}::{expression.Value.Ident}' not found").At(fileName, expression.Value).Build());
|
throw new CompileException(Diagnostic.Error($"Identifier '{expression.Module.Ident}::{expression.Value.Ident}' not found").At(fileName, expression.Value).Build());
|
||||||
|
|
||||||
return new TypedNodeExpressionModuleIdent(expression.Tokens, identifierType, expression.Module, expression.Value);
|
return new TypedNodeExpressionModuleIdent(expression.Tokens, identifierType, expression.Module, expression.Value);
|
||||||
@@ -336,7 +338,9 @@ public sealed class TypeChecker(string fileName, string moduleName, NodeDefiniti
|
|||||||
if (!moduleGraph.TryResolveModule(expression.Module.Ident, out var module))
|
if (!moduleGraph.TryResolveModule(expression.Module.Ident, out var module))
|
||||||
throw new CompileException(Diagnostic.Error($"Module '{expression.Module.Ident}' not found").At(fileName, expression.Module).Build());
|
throw new CompileException(Diagnostic.Error($"Module '{expression.Module.Ident}' not found").At(fileName, expression.Module).Build());
|
||||||
|
|
||||||
if (!module.TryResolveCustomType(expression.Name.Ident, out var customType))
|
var includePrivate = expression.Module.Ident == moduleName;
|
||||||
|
|
||||||
|
if (!module.TryResolveCustomType(expression.Name.Ident, includePrivate, out var customType))
|
||||||
throw new CompileException(Diagnostic.Error($"Struct '{expression.Module.Ident}::{expression.Name.Ident}' not found").At(fileName, expression.Name).Build());
|
throw new CompileException(Diagnostic.Error($"Struct '{expression.Module.Ident}::{expression.Name.Ident}' not found").At(fileName, expression.Name).Build());
|
||||||
|
|
||||||
if (customType is not NubTypeStruct structType)
|
if (customType is not NubTypeStruct structType)
|
||||||
@@ -380,7 +384,9 @@ public sealed class TypeChecker(string fileName, string moduleName, NodeDefiniti
|
|||||||
if (!moduleGraph.TryResolveModule(type.Module.Ident, out var module))
|
if (!moduleGraph.TryResolveModule(type.Module.Ident, out var module))
|
||||||
throw new CompileException(Diagnostic.Error($"Module '{type.Module.Ident}' not found").At(fileName, type.Module).Build());
|
throw new CompileException(Diagnostic.Error($"Module '{type.Module.Ident}' not found").At(fileName, type.Module).Build());
|
||||||
|
|
||||||
if (!module.TryResolveCustomType(type.Name.Ident, out var customType))
|
var includePrivate = type.Module.Ident == moduleName;
|
||||||
|
|
||||||
|
if (!module.TryResolveCustomType(type.Name.Ident, includePrivate, out var customType))
|
||||||
throw new CompileException(Diagnostic.Error($"Custom type '{type.Module.Ident}::{type.Name.Ident}' not found").At(fileName, type.Name).Build());
|
throw new CompileException(Diagnostic.Error($"Custom type '{type.Module.Ident}::{type.Name.Ident}' not found").At(fileName, type.Name).Build());
|
||||||
|
|
||||||
return customType;
|
return customType;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
module test
|
module test
|
||||||
|
|
||||||
struct person {
|
export packed struct person {
|
||||||
age: i32
|
age: i32
|
||||||
name: string
|
name: string
|
||||||
}
|
}
|
||||||
|
|
||||||
func do_something(name: string): i32 {
|
export func do_something(name: string): i32 {
|
||||||
return 3
|
return 3
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user