This commit is contained in:
nub31
2025-09-20 19:19:40 +02:00
parent 68f0da8065
commit 6e403a9884
4 changed files with 59 additions and 63 deletions

View File

@@ -467,7 +467,7 @@ public class QBEGenerator
private void EmitBlock(BlockNode block, Scope? scope = null) private void EmitBlock(BlockNode block, Scope? scope = null)
{ {
scope ??= Scope.SubScope(); scope ??= new Scope();
_scopes.Push(scope); _scopes.Push(scope);
foreach (var statement in block.Statements) foreach (var statement in block.Statements)
@@ -1295,12 +1295,6 @@ public class QBEGenerator
return new NubStructType(definition.Module, definition.Name, fieldTypes, functionTypes); return new NubStructType(definition.Module, definition.Name, fieldTypes, functionTypes);
} }
private NubFuncType TypeOfFunc(FuncSignatureNode signature)
{
var parameters = signature.Parameters.Select(x => x.Type).ToList();
return new NubFuncType(parameters, signature.ReturnType);
}
private string TmpName() private string TmpName()
{ {
return $"%.t{++_tmpIndex}"; return $"%.t{++_tmpIndex}";
@@ -1342,16 +1336,10 @@ public class QBEGenerator
} }
} }
// todo(nub31): Parent is not used when getting variables and deferred statements public class Scope
public class Scope(Scope? parent = null)
{ {
public readonly Stack<StatementNode> DeferredStatements = []; public readonly Stack<StatementNode> DeferredStatements = [];
public readonly Stack<Variable> Variables = []; public readonly Stack<Variable> Variables = [];
public Scope SubScope()
{
return new Scope(this);
}
} }
public record Variable(string Name, NubType Type); public record Variable(string Name, NubType Type);

View File

@@ -38,6 +38,4 @@ public record ModuleStruct(bool Exported, string Name, List<ModuleStructField> F
public record ModuleFunctionParameter(string Name, TypeSyntax Type); public record ModuleFunctionParameter(string Name, TypeSyntax Type);
public record ModuleFunction(bool Exported, string Name, string? ExternSymbol, List<ModuleFunctionParameter> Parameters, TypeSyntax ReturnType); public record ModuleFunction(bool Exported, string Name, string? ExternSymbol, List<ModuleFunctionParameter> Parameters, TypeSyntax ReturnType);
public record ModuleTemplateStruct(bool Exported, string? Name);

View File

@@ -70,19 +70,18 @@ public sealed class TypeChecker
} }
} }
private Scope BeginScope(bool root) private void BeginScope(bool root)
{ {
var scope = root var scope = root
? _globalScope.SubScope() ? _globalScope.SubScope()
: _scopes.Peek().SubScope(); : _scopes.Peek().SubScope();
_scopes.Push(scope); _scopes.Push(scope);
return scope;
} }
private Scope EndScope() private void EndScope()
{ {
return _scopes.Pop(); _scopes.Pop();
} }
private StructNode CheckStructDefinition(StructSyntax node) private StructNode CheckStructDefinition(StructSyntax node)
@@ -841,13 +840,24 @@ public sealed class TypeChecker
private bool AlwaysReturns(StatementNode statement) private bool AlwaysReturns(StatementNode statement)
{ {
return statement switch switch (statement)
{ {
ReturnNode => true, case ReturnNode:
BlockNode block => block.Statements.Count != 0 && AlwaysReturns(block.Statements.Last()), return true;
IfNode ifNode => AlwaysReturns(ifNode.Body) && ifNode.Else.TryGetValue(out var elseStatement) ? elseStatement.Match(AlwaysReturns, AlwaysReturns) : true, case BlockNode block:
_ => false return block.Statements.Count != 0 && AlwaysReturns(block.Statements.Last());
}; case IfNode ifNode:
{
if (!AlwaysReturns(ifNode.Body))
{
return false;
}
return !ifNode.Else.TryGetValue(out var elseStatement) || elseStatement.Match(AlwaysReturns, AlwaysReturns);
}
default:
return false;
}
} }
private NubType ResolveType(TypeSyntax type) private NubType ResolveType(TypeSyntax type)

View File

@@ -11,49 +11,49 @@ struct Human
extern "main" func main(args: []cstring): i64 extern "main" func main(args: []cstring): i64
{ {
// let x: ref<Human> = {} let x: ref<Human> = {}
// test(x) test(x)
return 0 return 0
} }
// func test(x: ref<Human>) func test(x: ref<Human>)
// { {
// } }
// struct ref<T> struct ref<T>
// { {
// value: ^T value: ^T
// count: ^u64 count: ^u64
// @oncreate @oncreate
// func on_create() func on_create()
// { {
// puts("on_create") puts("on_create")
// this.value = @interpret(^T, malloc(@size(T))) this.value = @interpret(^T, malloc(@size(T)))
// this.count = @interpret(^u64, malloc(@size(u64))) this.count = @interpret(^u64, malloc(@size(u64)))
// this.count^ = 1 this.count^ = 1
// } }
// @oncopy @oncopy
// func on_copy() func on_copy()
// { {
// puts("on_copy") puts("on_copy")
// this.count^ = this.count^ + 1 this.count^ = this.count^ + 1
// } }
// @ondestroy @ondestroy
// func on_destroy() func on_destroy()
// { {
// puts("on_destroy") puts("on_destroy")
// this.count^ = this.count^ - 1 this.count^ = this.count^ - 1
// if this.count^ <= 0 if this.count^ <= 0
// { {
// puts("free") puts("free")
// free(@interpret(^void, this.value)) free(@interpret(^void, this.value))
// free(@interpret(^void, this.count)) free(@interpret(^void, this.count))
// } }
// } }
// } }