while loops working

This commit is contained in:
nub31
2025-01-30 13:37:38 +01:00
parent ea705b9109
commit 8a50278f0f
7 changed files with 54 additions and 36 deletions

View File

@@ -222,6 +222,9 @@ public class Generator
case VariableReassignmentNode variableReassignment: case VariableReassignmentNode variableReassignment:
GenerateVariableReassignment(variableReassignment, func); GenerateVariableReassignment(variableReassignment, func);
break; break;
case WhileNode whileStatement:
GenerateWhile(whileStatement, func);
break;
default: default:
throw new ArgumentOutOfRangeException(nameof(statement)); throw new ArgumentOutOfRangeException(nameof(statement));
} }
@@ -278,6 +281,19 @@ public class Generator
_builder.AppendLine($" mov [rbp - {variable.Offset}], rax"); _builder.AppendLine($" mov [rbp - {variable.Offset}], rax");
} }
private void GenerateWhile(WhileNode whileStatement, LocalFunc func)
{
var startLabel = _labelFactory.Create();
var endLabel = _labelFactory.Create();
_builder.AppendLine($"{startLabel}:");
GenerateExpression(whileStatement.Condition, func);
_builder.AppendLine(" cmp rax, 0");
_builder.AppendLine($" je {endLabel}");
GenerateBlock(whileStatement.Body, func);
_builder.AppendLine($" jmp {startLabel}");
_builder.AppendLine($"{endLabel}:");
}
private void GenerateExpression(ExpressionNode expression, LocalFunc func) private void GenerateExpression(ExpressionNode expression, LocalFunc func)
{ {
switch (expression) switch (expression)
@@ -366,7 +382,7 @@ public class Generator
case DelegateType: case DelegateType:
throw new NotSupportedException($"Comparison on type {type.GetType().Name} is not supported"); throw new NotSupportedException($"Comparison on type {type.GetType().Name} is not supported");
case PrimitiveType: case PrimitiveType:
_builder.AppendLine(" cmp rax, rax"); _builder.AppendLine(" cmp rax, rbx");
break; break;
case StringType: case StringType:
_builder.AppendLine(" mov rdi, rax"); _builder.AppendLine(" mov rdi, rax");

View File

@@ -8,11 +8,12 @@ public class Lexer
{ {
["func"] = Symbol.Func, ["func"] = Symbol.Func,
["extern"] = Symbol.Extern, ["extern"] = Symbol.Extern,
["return"] = Symbol.Return,
["import"] = Symbol.Import, ["import"] = Symbol.Import,
["let"] = Symbol.Let, ["let"] = Symbol.Let,
["if"] = Symbol.If, ["if"] = Symbol.If,
["else"] = Symbol.Else, ["else"] = Symbol.Else,
["while"] = Symbol.While,
["return"] = Symbol.Return,
}; };
private static readonly Dictionary<char[], Symbol> Chians = new() private static readonly Dictionary<char[], Symbol> Chians = new()

View File

@@ -15,6 +15,7 @@ public enum Symbol
Let, Let,
If, If,
Else, Else,
While,
Semicolon, Semicolon,
Colon, Colon,
OpenParen, OpenParen,

View File

@@ -163,25 +163,14 @@ public class Parser
} }
case SymbolToken symbol: case SymbolToken symbol:
{ {
switch (symbol.Symbol) return symbol.Symbol switch
{ {
case Symbol.Return: Symbol.Return => ParseReturn(),
{ Symbol.Let => ParseVariableAssignment(),
return ParseReturn(); Symbol.If => ParseIf(),
} Symbol.While => ParseWhile(),
case Symbol.Let: _ => throw new Exception($"Unexpected symbol {symbol.Symbol}")
{ };
return ParseVariableAssignment();
}
case Symbol.If:
{
return ParseIf();
}
default:
{
throw new Exception($"Unexpected symbol {symbol.Symbol}");
}
}
} }
default: default:
{ {
@@ -228,6 +217,13 @@ public class Parser
return new IfNode(condition, body, elseStatement); return new IfNode(condition, body, elseStatement);
} }
private WhileNode ParseWhile()
{
var condition = ParseExpression();
var body = ParseBlock();
return new WhileNode(condition, body);
}
private ExpressionNode ParseExpression(int precedence = 0) private ExpressionNode ParseExpression(int precedence = 0)
{ {
var left = ParsePrimaryExpression(); var left = ParsePrimaryExpression();

View File

@@ -0,0 +1,7 @@
namespace Nub.Lang.Frontend.Parsing;
public class WhileNode(ExpressionNode condition, BlockNode body) : StatementNode
{
public ExpressionNode Condition { get; } = condition;
public BlockNode Body { get; } = body;
}

View File

@@ -101,6 +101,9 @@ public class ExpressionTyper
case VariableReassignmentNode variableReassignment: case VariableReassignmentNode variableReassignment:
PopulateVariableReassignment(variableReassignment); PopulateVariableReassignment(variableReassignment);
break; break;
case WhileNode whileStatement:
PopulateWhileStatement(whileStatement);
break;
default: default:
throw new ArgumentOutOfRangeException(nameof(statement)); throw new ArgumentOutOfRangeException(nameof(statement));
} }
@@ -155,6 +158,12 @@ public class ExpressionTyper
PopulateExpression(variableReassignment.Value); PopulateExpression(variableReassignment.Value);
} }
private void PopulateWhileStatement(WhileNode whileStatement)
{
PopulateExpression(whileStatement.Condition);
PopulateBlock(whileStatement.Body);
}
private void PopulateExpression(ExpressionNode expression) private void PopulateExpression(ExpressionNode expression)
{ {
switch (expression) switch (expression)

View File

@@ -1,21 +1,9 @@
import "core"; import "core";
let KB = 1024;
let MB = KB * 1024;
let GB = MB * 1024;
let TB = GB * 1024;
func main() { func main() {
println("test"); let i = 1;
println(true); while i <= 10 {
println("uwu");
if strlen("1") == 1 { i = i + 1;
println("1");
} else if false {
println("2");
} else if true {
println("3");
} else {
println("4");
} }
} }