Fix array access
This commit is contained in:
@@ -12,6 +12,7 @@ public class Generator
|
||||
private readonly SymbolTable _symbolTable;
|
||||
private readonly StringBuilder _builder;
|
||||
private readonly LabelFactory _labelFactory;
|
||||
private readonly Stack<(string StartLabel, string EndLabel)> _loops;
|
||||
|
||||
public Generator(List<DefinitionNode> definitions)
|
||||
{
|
||||
@@ -19,6 +20,7 @@ public class Generator
|
||||
_builder = new StringBuilder();
|
||||
_labelFactory = new LabelFactory();
|
||||
_symbolTable = new SymbolTable(_labelFactory);
|
||||
_loops = [];
|
||||
|
||||
foreach (var globalVariableDefinition in definitions.OfType<GlobalVariableDefinitionNode>())
|
||||
{
|
||||
@@ -213,6 +215,12 @@ public class Generator
|
||||
case ArrayIndexAssignmentNode arrayIndexAssignment:
|
||||
GenerateArrayIndexAssignment(arrayIndexAssignment, func);
|
||||
break;
|
||||
case BreakNode:
|
||||
GenerateBreak();
|
||||
break;
|
||||
case ContinueNode:
|
||||
GenerateContinue();
|
||||
break;
|
||||
case FuncCallStatementNode funcCallStatement:
|
||||
GenerateFuncCall(funcCallStatement.FuncCall, func);
|
||||
break;
|
||||
@@ -239,6 +247,16 @@ public class Generator
|
||||
}
|
||||
}
|
||||
|
||||
private void GenerateBreak()
|
||||
{
|
||||
_builder.AppendLine($" jmp {_loops.Peek().EndLabel}");
|
||||
}
|
||||
|
||||
private void GenerateContinue()
|
||||
{
|
||||
_builder.AppendLine($" jmp {_loops.Peek().StartLabel}");
|
||||
}
|
||||
|
||||
private void GenerateArrayIndexAssignment(ArrayIndexAssignmentNode arrayIndexAssignment, LocalFunc func)
|
||||
{
|
||||
GenerateExpression(arrayIndexAssignment.Value, func);
|
||||
@@ -303,11 +321,14 @@ public class Generator
|
||||
{
|
||||
var startLabel = _labelFactory.Create();
|
||||
var endLabel = _labelFactory.Create();
|
||||
|
||||
_builder.AppendLine($"{startLabel}:");
|
||||
GenerateExpression(whileStatement.Condition, func);
|
||||
_builder.AppendLine(" cmp rax, 0");
|
||||
_builder.AppendLine($" je {endLabel}");
|
||||
_loops.Push((startLabel, endLabel));
|
||||
GenerateBlock(whileStatement.Body, func);
|
||||
_loops.Pop();
|
||||
_builder.AppendLine($" jmp {startLabel}");
|
||||
_builder.AppendLine($"{endLabel}:");
|
||||
}
|
||||
@@ -627,25 +648,25 @@ public class Generator
|
||||
GenerateExpression(index, func);
|
||||
_builder.AppendLine(" push rax");
|
||||
GenerateIdentifier(identifier, func);
|
||||
_builder.AppendLine(" pop rcx");
|
||||
_builder.AppendLine(" pop rdx");
|
||||
|
||||
// rcx now holds the length of the array which we can use to check bounds
|
||||
_builder.AppendLine(" mov rcx, [rax]");
|
||||
_builder.AppendLine(" cmp rcx, rcx");
|
||||
_builder.AppendLine(" cmp rdx, rcx");
|
||||
if (ZeroBasedIndexing)
|
||||
{
|
||||
_builder.AppendLine(" jge array_out_of_bounds");
|
||||
_builder.AppendLine(" cmp rcx, 0");
|
||||
_builder.AppendLine(" cmp rdx, 0");
|
||||
}
|
||||
else
|
||||
{
|
||||
_builder.AppendLine(" jg array_out_of_bounds");
|
||||
_builder.AppendLine(" cmp rcx, 1");
|
||||
_builder.AppendLine(" cmp rdx, 1");
|
||||
}
|
||||
_builder.AppendLine(" jl array_out_of_bounds");
|
||||
|
||||
_builder.AppendLine(" inc rcx");
|
||||
_builder.AppendLine(" shl rcx, 3");
|
||||
_builder.AppendLine(" add rax, rcx");
|
||||
_builder.AppendLine(" inc rdx");
|
||||
_builder.AppendLine(" shl rdx, 3");
|
||||
_builder.AppendLine(" add rax, rdx");
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,8 @@ public class Lexer
|
||||
["if"] = Symbol.If,
|
||||
["else"] = Symbol.Else,
|
||||
["while"] = Symbol.While,
|
||||
["break"] = Symbol.Break,
|
||||
["continue"] = Symbol.Continue,
|
||||
["return"] = Symbol.Return,
|
||||
["new"] = Symbol.New,
|
||||
};
|
||||
|
||||
@@ -16,6 +16,8 @@ public enum Symbol
|
||||
If,
|
||||
Else,
|
||||
While,
|
||||
Break,
|
||||
Continue,
|
||||
Semicolon,
|
||||
Colon,
|
||||
OpenParen,
|
||||
|
||||
3
Nub.Lang/Nub.Lang/Frontend/Parsing/BreakNode.cs
Normal file
3
Nub.Lang/Nub.Lang/Frontend/Parsing/BreakNode.cs
Normal file
@@ -0,0 +1,3 @@
|
||||
namespace Nub.Lang.Frontend.Parsing;
|
||||
|
||||
public class BreakNode : StatementNode;
|
||||
3
Nub.Lang/Nub.Lang/Frontend/Parsing/ContinueNode.cs
Normal file
3
Nub.Lang/Nub.Lang/Frontend/Parsing/ContinueNode.cs
Normal file
@@ -0,0 +1,3 @@
|
||||
namespace Nub.Lang.Frontend.Parsing;
|
||||
|
||||
public class ContinueNode : StatementNode;
|
||||
@@ -178,6 +178,8 @@ public class Parser
|
||||
Symbol.Let => ParseVariableAssignment(),
|
||||
Symbol.If => ParseIf(),
|
||||
Symbol.While => ParseWhile(),
|
||||
Symbol.Break => ParseBreak(),
|
||||
Symbol.Continue => ParseContinue(),
|
||||
_ => throw new Exception($"Unexpected symbol {symbol.Symbol}")
|
||||
};
|
||||
}
|
||||
@@ -233,6 +235,18 @@ public class Parser
|
||||
return new WhileNode(condition, body);
|
||||
}
|
||||
|
||||
private BreakNode ParseBreak()
|
||||
{
|
||||
ExpectSymbol(Symbol.Semicolon);
|
||||
return new BreakNode();
|
||||
}
|
||||
|
||||
private ContinueNode ParseContinue()
|
||||
{
|
||||
ExpectSymbol(Symbol.Semicolon);
|
||||
return new ContinueNode();
|
||||
}
|
||||
|
||||
private ExpressionNode ParseExpression(int precedence = 0)
|
||||
{
|
||||
var left = ParsePrimaryExpression();
|
||||
|
||||
@@ -86,6 +86,9 @@ public class ExpressionTyper
|
||||
case ArrayIndexAssignmentNode arrayIndexAssignment:
|
||||
PopulateArrayIndexAssignment(arrayIndexAssignment);
|
||||
break;
|
||||
case BreakNode:
|
||||
case ContinueNode:
|
||||
break;
|
||||
case FuncCallStatementNode funcCall:
|
||||
PopulateFuncCallStatement(funcCall);
|
||||
break;
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
import "core";
|
||||
|
||||
func main() {
|
||||
println(69);
|
||||
let some_string = "test";
|
||||
println(some_string);
|
||||
|
||||
let some_array = new Array<int64>(2);
|
||||
some_array[1] = 1;
|
||||
some_array[2] = 2;
|
||||
|
||||
let i = 1;
|
||||
|
||||
println(some_array[1]);
|
||||
println(some_array[2]);
|
||||
|
||||
while i <= arr_size(some_array) {
|
||||
println(some_array[i]);
|
||||
i = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user