This commit is contained in:
nub31
2025-05-05 22:55:15 +02:00
parent c3502fe68a
commit bdf82f99e7
5 changed files with 85 additions and 34 deletions

View File

@@ -1,12 +1,14 @@
import "c"; import "c";
struct Human {
age: int64;
name: string;
}
global func main() { global func main() {
let x = true; printName();
while x {
if (true) {
puts("level 1");
}
puts("level 2");
break;
} }
func printName(human: Human) {
puts(human.name);
} }

View File

@@ -8,7 +8,7 @@ public class Generator
private readonly List<DefinitionNode> _definitions; private readonly List<DefinitionNode> _definitions;
private readonly StringBuilder _builder = new(); private readonly StringBuilder _builder = new();
private readonly Dictionary<string, int> _prefixIndexes = new(); private readonly Dictionary<string, int> _prefixIndexes = new();
private readonly Dictionary<string, string> _variables = new(); private readonly Dictionary<string, Variable> _variables = new();
private readonly List<string> _strings = []; private readonly List<string> _strings = [];
private readonly Stack<string> _breakLabels = new(); private readonly Stack<string> _breakLabels = new();
private readonly Stack<string> _continueLabels = new(); private readonly Stack<string> _continueLabels = new();
@@ -21,9 +21,16 @@ public class Generator
public string Generate() public string Generate()
{ {
foreach (var structDefinition in _definitions.OfType<StructDefinitionNode>())
{
GenerateStructDefinition(structDefinition);
_builder.AppendLine();
}
foreach (var funcDefinition in _definitions.OfType<LocalFuncDefinitionNode>()) foreach (var funcDefinition in _definitions.OfType<LocalFuncDefinitionNode>())
{ {
GenerateFuncDefinition(funcDefinition); GenerateFuncDefinition(funcDefinition);
_builder.AppendLine();
} }
for (var i = 0; i < _strings.Count; i++) for (var i = 0; i < _strings.Count; i++)
@@ -47,13 +54,22 @@ public class Generator
return "w"; return "w";
} }
throw new Exception($"Invalid qbe type {type}"); return $":{type.Name}";
} }
private void GenerateFuncDefinition(LocalFuncDefinitionNode node) private void GenerateFuncDefinition(LocalFuncDefinitionNode node)
{ {
_variables.Clear(); _variables.Clear();
var parameters = node.Parameters.Select(p => $"{QbeTypeName(p.Type)} %{p.Name}");
foreach (var parameter in node.Parameters)
{
_variables.Add(parameter.Name, new Variable
{
Identifier = $"%{parameter.Name}",
Type = parameter.Type
});
}
if (node.Global) if (node.Global)
{ {
_builder.Append("export "); _builder.Append("export ");
@@ -68,7 +84,7 @@ public class Generator
_builder.Append('$'); _builder.Append('$');
_builder.Append(node.Name); _builder.Append(node.Name);
_builder.AppendLine($"({string.Join(", ", parameters)}) {{"); _builder.AppendLine($"({string.Join(", ", node.Parameters.Select(p => $"{QbeTypeName(p.Type)} %{p.Name}"))}) {{");
_builder.AppendLine("@start"); _builder.AppendLine("@start");
GenerateBlock(node.Body); GenerateBlock(node.Body);
if (!node.ReturnType.HasValue) if (!node.ReturnType.HasValue)
@@ -79,6 +95,12 @@ public class Generator
_builder.AppendLine("}"); _builder.AppendLine("}");
} }
private void GenerateStructDefinition(StructDefinitionNode structDefinition)
{
var fields = structDefinition.Fields.Select(f => QbeTypeName(f.Type));
_builder.AppendLine($"type :{structDefinition.Name} = {{ {string.Join(", ", fields)} }}");
}
private void GenerateBlock(BlockNode block) private void GenerateBlock(BlockNode block)
{ {
foreach (var statement in block.Statements.Where(_ => _codeIsReachable)) foreach (var statement in block.Statements.Where(_ => _codeIsReachable))
@@ -167,6 +189,7 @@ public class Generator
GenerateBlock GenerateBlock
); );
} }
_builder.AppendLine($"@{endLabel}"); _builder.AppendLine($"@{endLabel}");
} }
@@ -185,12 +208,22 @@ public class Generator
private void GenerateVariableAssignment(VariableAssignmentNode variableAssignment) private void GenerateVariableAssignment(VariableAssignmentNode variableAssignment)
{ {
_variables[variableAssignment.Name] = GenerateExpression(variableAssignment.Value); var result = GenerateExpression(variableAssignment.Value);
_variables[variableAssignment.Name] = new Variable
{
Identifier = result,
Type = variableAssignment.Value.Type
};
} }
private void GenerateVariableReassignment(VariableReassignmentNode variableReassignment) private void GenerateVariableReassignment(VariableReassignmentNode variableReassignment)
{ {
_variables[variableReassignment.Name] = GenerateExpression(variableReassignment.Value); var result = GenerateExpression(variableReassignment.Value);
_variables[variableReassignment.Name] = new Variable
{
Identifier = result,
Type = variableReassignment.Value.Type
};
} }
private void GenerateWhile(WhileNode whileStatement) private void GenerateWhile(WhileNode whileStatement)
@@ -237,7 +270,16 @@ public class Generator
private string GenerateStructMemberAccessor(StructMemberAccessorNode structMemberAccessor) private string GenerateStructMemberAccessor(StructMemberAccessorNode structMemberAccessor)
{ {
throw new NotImplementedException(); var type = _variables.First(x => x.Key == structMemberAccessor.Fields[0]).Value.Type;
var def = _definitions.OfType<StructDefinitionNode>().FirstOrDefault(s => s.Name == type.Name);
if (def == null)
{
throw new Exception("def is null");
}
throw new NotImplementedException("Not finished yet");
return $"load{QbeTypeName(structMemberAccessor.Type)} ";
} }
private string GenerateBinaryExpression(BinaryExpressionNode binaryExpression) private string GenerateBinaryExpression(BinaryExpressionNode binaryExpression)
@@ -247,7 +289,7 @@ public class Generator
private string GenerateIdentifier(IdentifierNode identifier) private string GenerateIdentifier(IdentifierNode identifier)
{ {
return _variables[identifier.Identifier]; return _variables[identifier.Identifier].Identifier;
} }
private string GenerateLiteral(LiteralNode literal) private string GenerateLiteral(LiteralNode literal)
@@ -300,4 +342,11 @@ public class Generator
_prefixIndexes[prefix] = index + 1; _prefixIndexes[prefix] = index + 1;
return $"{prefix}_{index}"; return $"{prefix}_{index}";
} }
private class Variable
{
public required string Identifier { get; init; }
public required NubType Type { get; init; }
} }
}

View File

@@ -1,7 +1,7 @@
namespace Nub.Lang.Frontend.Parsing; namespace Nub.Lang.Frontend.Parsing;
public class StructDefinitionNode(string name, List<StructField> members) : DefinitionNode public class StructDefinitionNode(string name, List<StructField> fields) : DefinitionNode
{ {
public string Name { get; } = name; public string Name { get; } = name;
public List<StructField> Members { get; } = members; public List<StructField> Fields { get; } = fields;
} }

View File

@@ -1,6 +1,6 @@
namespace Nub.Lang.Frontend.Parsing; namespace Nub.Lang.Frontend.Parsing;
public class StructMemberAccessorNode(List<string> members) : ExpressionNode public class StructMemberAccessorNode(List<string> fields) : ExpressionNode
{ {
public List<string> Members { get; } = members; public List<string> Fields { get; } = fields;
} }

View File

@@ -43,7 +43,7 @@ public class ExpressionTyper
foreach (var @class in _structDefinitions) foreach (var @class in _structDefinitions)
{ {
foreach (var variable in @class.Members) foreach (var variable in @class.Fields)
{ {
if (variable.Value.HasValue) if (variable.Value.HasValue)
{ {
@@ -265,37 +265,37 @@ public class ExpressionTyper
// TODO: Fix this ugly ass code // TODO: Fix this ugly ass code
private void GenerateStructMemberAccessorNode(StructMemberAccessorNode structMemberAccessor) private void GenerateStructMemberAccessorNode(StructMemberAccessorNode structMemberAccessor)
{ {
var variable = _variables.FirstOrDefault(v => v.Name == structMemberAccessor.Members[0]); var variable = _variables.FirstOrDefault(v => v.Name == structMemberAccessor.Fields[0]);
if (variable == null) if (variable == null)
{ {
throw new Exception($"Variable {structMemberAccessor.Members[0]} is not defined"); throw new Exception($"Variable {structMemberAccessor.Fields[0]} is not defined");
} }
var definition = _structDefinitions.FirstOrDefault(sd => sd.Name == variable.Type.Name); var definition = _structDefinitions.FirstOrDefault(sd => sd.Name == variable.Type.Name);
if (definition == null) if (definition == null)
{ {
throw new Exception($"Struct {structMemberAccessor.Members[0]} is not defined"); throw new Exception($"Struct {structMemberAccessor.Fields[0]} is not defined");
} }
for (var i = 1; i < structMemberAccessor.Members.Count - 1; i++) for (var i = 1; i < structMemberAccessor.Fields.Count - 1; i++)
{ {
var member = definition.Members.FirstOrDefault(m => m.Name == structMemberAccessor.Members[i]); var member = definition.Fields.FirstOrDefault(m => m.Name == structMemberAccessor.Fields[i]);
if (member == null) if (member == null)
{ {
throw new Exception($"Member {structMemberAccessor.Members[i]} does not exist on struct {definition.Name}"); throw new Exception($"Member {structMemberAccessor.Fields[i]} does not exist on struct {definition.Name}");
} }
definition = _structDefinitions.FirstOrDefault(sd => sd.Name == member.Type.Name); definition = _structDefinitions.FirstOrDefault(sd => sd.Name == member.Type.Name);
if (definition == null) if (definition == null)
{ {
throw new Exception($"Struct {structMemberAccessor.Members[i]} is not defined"); throw new Exception($"Struct {structMemberAccessor.Fields[i]} is not defined");
} }
} }
var tmp = definition.Members.FirstOrDefault(m => m.Name == structMemberAccessor.Members.Last()); var tmp = definition.Fields.FirstOrDefault(m => m.Name == structMemberAccessor.Fields.Last());
if (tmp == null) if (tmp == null)
{ {
throw new Exception($"Member {structMemberAccessor.Members.Last()} does not exist on struct {definition.Name}"); throw new Exception($"Member {structMemberAccessor.Fields.Last()} does not exist on struct {definition.Name}");
} }
structMemberAccessor.Type = tmp.Type; structMemberAccessor.Type = tmp.Type;