diff --git a/Nub.Lang/Nub.Lang/Generation/Generator.cs b/Nub.Lang/Nub.Lang/Generation/Generator.cs index 6702c23..44341b5 100644 --- a/Nub.Lang/Nub.Lang/Generation/Generator.cs +++ b/Nub.Lang/Nub.Lang/Generation/Generator.cs @@ -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)); diff --git a/Nub.Lang/Nub.Lang/Input/program.nub b/Nub.Lang/Nub.Lang/Input/program.nub index 64b3f58..fa028af 100644 --- a/Nub.Lang/Nub.Lang/Input/program.nub +++ b/Nub.Lang/Nub.Lang/Input/program.nub @@ -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)); } \ No newline at end of file diff --git a/Nub.Lang/Nub.Lang/Parsing/Parser.cs b/Nub.Lang/Nub.Lang/Parsing/Parser.cs index 0252c57..7a9451f 100644 --- a/Nub.Lang/Nub.Lang/Parsing/Parser.cs +++ b/Nub.Lang/Nub.Lang/Parsing/Parser.cs @@ -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}"); diff --git a/Nub.Lang/Nub.Lang/Typing/ExpressionTyper.cs b/Nub.Lang/Nub.Lang/Typing/ExpressionTyper.cs index 1b5f80a..1f43595 100644 --- a/Nub.Lang/Nub.Lang/Typing/ExpressionTyper.cs +++ b/Nub.Lang/Nub.Lang/Typing/ExpressionTyper.cs @@ -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; }