global variables
This commit is contained in:
@@ -68,11 +68,11 @@ public sealed class Generator(List<TypedNodeDefinitionFunc> functions, ModuleGra
|
|||||||
if (!functions.Any(x => x.GetMangledName() == SymbolNameGen.Exported(module.Name, name, type)))
|
if (!functions.Any(x => x.GetMangledName() == SymbolNameGen.Exported(module.Name, name, type)))
|
||||||
writer.Write("extern ");
|
writer.Write("extern ");
|
||||||
|
|
||||||
writer.WriteLine($"{CType(fn.ReturnType)} {SymbolNameGen.Exported(module.Name, name, type)}({string.Join(", ", fn.Parameters.Select(p => CType(p)))});");
|
writer.WriteLine($"{CType(fn.ReturnType, SymbolNameGen.Exported(module.Name, name, type))}({string.Join(", ", fn.Parameters.Select(p => CType(p)))});");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
writer.WriteLine($"{CType(type)} {SymbolNameGen.Exported(module.Name, name, type)};");
|
writer.WriteLine($"{CType(type, SymbolNameGen.Exported(module.Name, name, type))};");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,8 +116,7 @@ public class ModuleGraph(Dictionary<string, ModuleGraph.Module> modules)
|
|||||||
// Second pass: Register struct types without fields
|
// Second pass: Register struct types without fields
|
||||||
foreach (var ast in asts)
|
foreach (var ast in asts)
|
||||||
{
|
{
|
||||||
var module = astModuleCache.GetValueOrDefault(ast);
|
var module = astModuleCache[ast];
|
||||||
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, structDef.Packed), structDef.Exported);
|
module.AddCustomType(structDef.Name.Ident, new NubTypeStruct(module.Name, structDef.Name.Ident, structDef.Packed), structDef.Exported);
|
||||||
@@ -126,15 +125,14 @@ public class ModuleGraph(Dictionary<string, ModuleGraph.Module> modules)
|
|||||||
// Third pass: Resolve struct fields
|
// Third pass: Resolve struct fields
|
||||||
foreach (var ast in asts)
|
foreach (var ast in asts)
|
||||||
{
|
{
|
||||||
var module = astModuleCache.GetValueOrDefault(ast);
|
var module = astModuleCache[ast];
|
||||||
if (module == null) continue;
|
|
||||||
|
|
||||||
foreach (var structDef in ast.Definitions.OfType<NodeDefinitionStruct>())
|
foreach (var structDef in ast.Definitions.OfType<NodeDefinitionStruct>())
|
||||||
{
|
{
|
||||||
if (!module.TryResolveCustomType(structDef.Name.Ident, true, 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, true))).ToList();
|
var fields = structDef.Fields.Select(f => new NubTypeStruct.Field(f.Name.Ident, ResolveType(f.Type, module.Name))).ToList();
|
||||||
((NubTypeStruct)customType).ResolveFields(fields);
|
((NubTypeStruct)customType).ResolveFields(fields);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,16 +140,21 @@ public class ModuleGraph(Dictionary<string, ModuleGraph.Module> modules)
|
|||||||
// Fourth pass: Register identifiers
|
// Fourth pass: Register identifiers
|
||||||
foreach (var ast in asts)
|
foreach (var ast in asts)
|
||||||
{
|
{
|
||||||
var module = astModuleCache.GetValueOrDefault(ast);
|
var module = astModuleCache[ast];
|
||||||
if (module == null) continue;
|
|
||||||
|
|
||||||
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, true)).ToList();
|
var parameters = funcDef.Parameters.Select(x => ResolveType(x.Type, module.Name)).ToList();
|
||||||
var returnType = ResolveType(funcDef.ReturnType, true);
|
var returnType = ResolveType(funcDef.ReturnType, module.Name);
|
||||||
var funcType = NubTypeFunc.Get(parameters, returnType);
|
var funcType = NubTypeFunc.Get(parameters, returnType);
|
||||||
module.AddIdentifier(funcDef.Name.Ident, funcType, funcDef.Exported);
|
module.AddIdentifier(funcDef.Name.Ident, funcType, funcDef.Exported);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var globalVariable in ast.Definitions.OfType<NodeDefinitionGlobalVariable>())
|
||||||
|
{
|
||||||
|
var type = ResolveType(globalVariable.Type, module.Name);
|
||||||
|
module.AddIdentifier(globalVariable.Name.Ident, type, globalVariable.Exported);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (diagnostics.Any(x => x.Severity == DiagnosticSeverity.Error))
|
if (diagnostics.Any(x => x.Severity == DiagnosticSeverity.Error))
|
||||||
@@ -159,14 +162,14 @@ public class ModuleGraph(Dictionary<string, ModuleGraph.Module> modules)
|
|||||||
|
|
||||||
return new ModuleGraph(modules);
|
return new ModuleGraph(modules);
|
||||||
|
|
||||||
NubType ResolveType(NodeType node, bool includePrivate)
|
NubType ResolveType(NodeType node, string currentModule)
|
||||||
{
|
{
|
||||||
return node switch
|
return node switch
|
||||||
{
|
{
|
||||||
NodeTypeBool => NubTypeBool.Instance,
|
NodeTypeBool => NubTypeBool.Instance,
|
||||||
NodeTypeCustom type => ResolveCustomType(type, includePrivate),
|
NodeTypeCustom type => ResolveCustomType(type, currentModule),
|
||||||
NodeTypeFunc type => NubTypeFunc.Get(type.Parameters.Select(x => ResolveType(x, includePrivate)).ToList(), ResolveType(type.ReturnType, includePrivate)),
|
NodeTypeFunc type => NubTypeFunc.Get(type.Parameters.Select(x => ResolveType(x, currentModule)).ToList(), ResolveType(type.ReturnType, currentModule)),
|
||||||
NodeTypePointer type => NubTypePointer.Get(ResolveType(type.To, includePrivate)),
|
NodeTypePointer type => NubTypePointer.Get(ResolveType(type.To, currentModule)),
|
||||||
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,
|
||||||
@@ -175,12 +178,14 @@ public class ModuleGraph(Dictionary<string, ModuleGraph.Module> modules)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
NubType ResolveCustomType(NodeTypeCustom type, bool includePrivate)
|
NubType ResolveCustomType(NodeTypeCustom type, string currentModule)
|
||||||
{
|
{
|
||||||
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());
|
||||||
|
|
||||||
|
var includePrivate = currentModule == type.Module.Ident;
|
||||||
|
|
||||||
if (!module.TryResolveCustomType(type.Name.Ident, includePrivate, 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());
|
||||||
|
|
||||||
|
|||||||
@@ -121,6 +121,21 @@ public sealed class Parser(string fileName, List<Token> tokens)
|
|||||||
return new NodeDefinitionStruct(TokensFrom(startIndex), exported, packed, name, fields);
|
return new NodeDefinitionStruct(TokensFrom(startIndex), exported, packed, name, fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TryExpectKeyword(Keyword.Let))
|
||||||
|
{
|
||||||
|
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 global variable").At(fileName, modifier.Value).Build());
|
||||||
|
|
||||||
|
var name = ExpectIdent();
|
||||||
|
ExpectSymbol(Symbol.Colon);
|
||||||
|
var type = ParseType();
|
||||||
|
|
||||||
|
return new NodeDefinitionGlobalVariable(TokensFrom(startIndex), exported, name, type);
|
||||||
|
}
|
||||||
|
|
||||||
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -622,6 +637,13 @@ public sealed class NodeDefinitionStruct(List<Token> tokens, bool exported, bool
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed class NodeDefinitionGlobalVariable(List<Token> tokens, bool exported, TokenIdent name, NodeType type) : NodeDefinition(tokens)
|
||||||
|
{
|
||||||
|
public bool Exported { get; } = exported;
|
||||||
|
public TokenIdent Name { get; } = name;
|
||||||
|
public NodeType Type { get; } = type;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract class NodeStatement(List<Token> tokens) : Node(tokens);
|
public abstract class NodeStatement(List<Token> tokens) : Node(tokens);
|
||||||
|
|
||||||
public sealed class NodeStatementBlock(List<Token> tokens, List<NodeStatement> statements) : NodeStatement(tokens)
|
public sealed class NodeStatementBlock(List<Token> tokens, List<NodeStatement> statements) : NodeStatement(tokens)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
module main
|
module main
|
||||||
|
|
||||||
|
let global: i32
|
||||||
|
|
||||||
func main(): i32 {
|
func main(): i32 {
|
||||||
let x: i32 = 23
|
let x: i32 = 23
|
||||||
x = 24
|
x = 24
|
||||||
@@ -23,5 +25,8 @@ func main(): i32 {
|
|||||||
|
|
||||||
x = test::do_something(me.name)
|
x = test::do_something(me.name)
|
||||||
test::do_something(me.name)
|
test::do_something(me.name)
|
||||||
return x
|
|
||||||
|
main::global = 123
|
||||||
|
|
||||||
|
return main::global
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user