Add support for expression syscalls

This commit is contained in:
nub31
2025-01-26 22:12:40 +01:00
parent 738aa92da5
commit 0169382a77
4 changed files with 33 additions and 15 deletions

View File

@@ -146,23 +146,36 @@ public class Generator
GenerateFuncCall(funcCallStatement.FuncCall, func);
break;
case ReturnNode @return:
if (@return.Value.HasValue)
{
GenerateExpression(@return.Value.Value, func);
}
_builder.AppendLine($" jmp {func.EndLabel}");
GenerateReturn(func, @return);
break;
case SyscallStatementNode syscallStatement:
GenerateSyscall(syscallStatement.Syscall, func);
break;
case VariableAssignmentNode variableAssignment:
throw new NotImplementedException();
GenerateVariableAssignment(func, variableAssignment);
break;
default:
throw new ArgumentOutOfRangeException(nameof(statement));
}
}
private void GenerateReturn(Func func, ReturnNode @return)
{
if (@return.Value.HasValue)
{
GenerateExpression(@return.Value.Value, func);
}
_builder.AppendLine($" jmp {func.EndLabel}");
}
private void GenerateVariableAssignment(Func func, VariableAssignmentNode variableAssignment)
{
GenerateExpression(variableAssignment.Value, func);
var variable = func.ResolveLocalVariable(variableAssignment.Name);
_builder.AppendLine($" mov [rbp - {variable.Offset}], rax");
}
private void GenerateExpression(ExpressionNode expression, Func func)
{
switch (expression)
@@ -180,7 +193,7 @@ public class Generator
GenerateStrlen(strlen, func);
break;
case SyscallExpressionNode syscallExpression:
throw new NotImplementedException();
GenerateSyscall(syscallExpression.Syscall, func);
break;
default:
throw new ArgumentOutOfRangeException(nameof(expression));

View File

@@ -4,13 +4,9 @@ let STD_OUT = 1;
let STD_ERR = 2;
func main() {
write(test());
write("test\n");
}
func test(): String {
return "test";
}
func write(msg: String) {
syscall(SYS_WRITE, STD_OUT, msg, strlen(msg));
func write(msg: String): int64 {
return syscall(SYS_WRITE, STD_OUT, msg, strlen(msg));
}

View File

@@ -129,6 +129,14 @@ public class Parser
return new ReturnNode(value);
}
case Symbol.Let:
{
var name = ExpectIdentifier().Value;
ExpectSymbol(Symbol.Assign);
var value = ParseExpression();
ExpectSymbol(Symbol.Semicolon);
return new VariableAssignmentNode(name, value);
}
default:
{
throw new Exception($"Unexpected symbol {symbol.Symbol}");

View File

@@ -100,6 +100,7 @@ public class ExpressionTyper
private void PopulateVariableAssignment(VariableAssignmentNode variableAssignment)
{
PopulateExpression(variableAssignment.Value);
_variables.Push(new Variable(variableAssignment.Name, variableAssignment.Value.Type));
}
private void PopulateExpression(ExpressionNode expression)
@@ -150,7 +151,7 @@ public class ExpressionTyper
var type = _variables.FirstOrDefault(v => v.Name == identifier.Identifier)?.Type;
if (type == null)
{
throw new Exception($"Identifier {identifier} is not defined");
throw new Exception($"Variable {identifier} is not defined");
}
identifier.Type = type;
}