while loops working
This commit is contained in:
@@ -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");
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ public enum Symbol
|
|||||||
Let,
|
Let,
|
||||||
If,
|
If,
|
||||||
Else,
|
Else,
|
||||||
|
While,
|
||||||
Semicolon,
|
Semicolon,
|
||||||
Colon,
|
Colon,
|
||||||
OpenParen,
|
OpenParen,
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
7
Nub.Lang/Nub.Lang/Frontend/Parsing/WhileNode.cs
Normal file
7
Nub.Lang/Nub.Lang/Frontend/Parsing/WhileNode.cs
Normal 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;
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
|||||||
@@ -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");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user