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); GenerateFuncCall(funcCallStatement.FuncCall, func);
break; break;
case ReturnNode @return: case ReturnNode @return:
if (@return.Value.HasValue) GenerateReturn(func, @return);
{
GenerateExpression(@return.Value.Value, func);
}
_builder.AppendLine($" jmp {func.EndLabel}");
break; break;
case SyscallStatementNode syscallStatement: case SyscallStatementNode syscallStatement:
GenerateSyscall(syscallStatement.Syscall, func); GenerateSyscall(syscallStatement.Syscall, func);
break; break;
case VariableAssignmentNode variableAssignment: case VariableAssignmentNode variableAssignment:
throw new NotImplementedException(); GenerateVariableAssignment(func, variableAssignment);
break; break;
default: default:
throw new ArgumentOutOfRangeException(nameof(statement)); 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) private void GenerateExpression(ExpressionNode expression, Func func)
{ {
switch (expression) switch (expression)
@@ -180,7 +193,7 @@ public class Generator
GenerateStrlen(strlen, func); GenerateStrlen(strlen, func);
break; break;
case SyscallExpressionNode syscallExpression: case SyscallExpressionNode syscallExpression:
throw new NotImplementedException(); GenerateSyscall(syscallExpression.Syscall, func);
break; break;
default: default:
throw new ArgumentOutOfRangeException(nameof(expression)); throw new ArgumentOutOfRangeException(nameof(expression));

View File

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

View File

@@ -129,6 +129,14 @@ public class Parser
return new ReturnNode(value); 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: default:
{ {
throw new Exception($"Unexpected symbol {symbol.Symbol}"); throw new Exception($"Unexpected symbol {symbol.Symbol}");

View File

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