aboutsummaryrefslogtreecommitdiff
path: root/src/parse.zig
diff options
context:
space:
mode:
authorMathias Magnusson <mathias@magnusson.space>2025-07-30 16:30:48 +0200
committerMathias Magnusson <mathias@magnusson.space>2025-07-30 16:30:48 +0200
commit69ecbca927d963311469f4634c002553d0c99bd4 (patch)
treec241e07e6c8238057d4d04b987cb393894382ebf /src/parse.zig
parent132a8da9a41a6303d40c8ec936a31c9481581cbe (diff)
downloadhuginn-69ecbca927d963311469f4634c002553d0c99bd4.tar.gz
implement return expressions
Diffstat (limited to 'src/parse.zig')
-rw-r--r--src/parse.zig28
1 files changed, 21 insertions, 7 deletions
diff --git a/src/parse.zig b/src/parse.zig
index 3ecb93b..d8b4d15 100644
--- a/src/parse.zig
+++ b/src/parse.zig
@@ -109,6 +109,7 @@ pub const Expr = struct {
identifier,
@"if": If,
proc: Proc,
+ @"return": Return,
pub const BinOp = struct {
lhs: *const Expr,
@@ -153,6 +154,10 @@ pub const Expr = struct {
body: Block,
param: ?Location,
};
+
+ pub const Return = struct {
+ value: *const Expr,
+ };
};
fn format(self: Expr, writer: anytype, source: []const u8, indent: usize) !void {
@@ -174,9 +179,8 @@ pub const Expr = struct {
try writer.print(" else {}", .{fmt(@"else", source, indent)});
}
},
- .proc => |proc| {
- try writer.print("proc() {}", .{fmt(proc.body, source, indent)});
- },
+ .proc => |proc| try writer.print("proc() {}", .{fmt(proc.body, source, indent)}),
+ .@"return" => |ret| try writer.print("return {}", .{fmt(ret.value, source, indent)}),
}
}
};
@@ -186,7 +190,7 @@ const ParseError = error{
ExpectedRightParen,
UnexpectedToken,
InvalidAssignTarget,
- ExprStatementMustBeCallOrIf,
+ InvalidExprStatement,
};
pub fn file(allocator: Allocator, lexer: *Lexer) !File {
@@ -258,8 +262,8 @@ fn parseStatement(allocator: Allocator, lexer: *Lexer) ParseError!Stmt {
.loc = lhs.loc.combine(value.loc),
.type = .{ .assign_var = .{ .ident = lhs.loc, .is_decl = colon != null, .value = value } },
};
- } else if (lhs.type != .call and lhs.type != .@"if") {
- return error.ExprStatementMustBeCallOrIf;
+ } else if (lhs.type != .call and lhs.type != .@"if" and lhs.type != .@"return") {
+ return error.InvalidExprStatement;
}
return .{
.loc = lhs.loc,
@@ -270,7 +274,17 @@ fn parseStatement(allocator: Allocator, lexer: *Lexer) ParseError!Stmt {
}
fn expression(allocator: Allocator, lexer: *Lexer) ParseError!*Expr {
- return parseProc(allocator, lexer);
+ return parseReturn(allocator, lexer);
+}
+
+fn parseReturn(allocator: Allocator, lexer: *Lexer) ParseError!*Expr {
+ if (lexer.peek().type != .@"return") return parseProc(allocator, lexer);
+ const ret = try mustEat(lexer, .@"return");
+ const val = try parseProc(allocator, lexer);
+ return allocate(Expr, allocator, .{
+ .loc = ret.loc.combine(val.loc),
+ .type = .{ .@"return" = .{ .value = val } },
+ });
}
fn parseProc(allocator: Allocator, lexer: *Lexer) ParseError!*Expr {