aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fibonacci.hgn9
-rw-r--r--src/Lexer.zig6
-rw-r--r--src/parse.zig35
3 files changed, 28 insertions, 22 deletions
diff --git a/fibonacci.hgn b/fibonacci.hgn
index 00c0638..01d9333 100644
--- a/fibonacci.hgn
+++ b/fibonacci.hgn
@@ -1,8 +1,9 @@
-let a = 0
-let b = 1
-let n = read_int(0)
+a := 0
+b := 1
+n := 10
+# n := read_int(0)
while n > 0 {
- let c = a + b
+ c := a + b
a = b
b = c
n = n - 1
diff --git a/src/Lexer.zig b/src/Lexer.zig
index 4665379..4b664fe 100644
--- a/src/Lexer.zig
+++ b/src/Lexer.zig
@@ -13,6 +13,7 @@ pub const Token = struct {
plus,
minus,
equal,
+ colon,
invalid,
eof,
identifier,
@@ -22,7 +23,6 @@ pub const Token = struct {
right_angle_equal,
// Keywords
- let,
@"if",
@"else",
@"while",
@@ -34,6 +34,7 @@ pub const Location = struct {
end: usize,
pub fn combine(a: Location, b: Location) Location {
+ if (a.start == b.start and a.end == b.end) return a;
std.debug.assert(a.end <= b.start);
return .{ .start = @min(a.start, b.start), .end = @max(a.end, b.end) };
}
@@ -83,6 +84,7 @@ fn getNext(self: *Self) Token {
'+' => self.create(.plus),
'-' => self.create(.minus),
'=' => self.create(.equal),
+ ':' => self.create(.colon),
'<' => if (self.eatIfEqual('='))
self.create(.left_angle_equal)
else
@@ -135,7 +137,7 @@ fn identifierOrKeyword(self: *Self) Token {
}
const value = self.source[self.start..self.pos];
return self.create(switch (std.meta.stringToEnum(Token.Type, value) orelse .invalid) {
- .let, .@"if", .@"else", .@"while" => |t| t,
+ .@"if", .@"else", .@"while" => |t| t,
else => .identifier,
});
}
diff --git a/src/parse.zig b/src/parse.zig
index 26f32e9..bd6b000 100644
--- a/src/parse.zig
+++ b/src/parse.zig
@@ -64,9 +64,9 @@ pub const Stmt = struct {
return switch (self.type) {
.expr => |expr| writer.print("{}", .{fmt(expr, source, indent)}),
.block => |b| writer.print("{}", .{fmt(b, source, indent)}),
- .assign_var => |assign_var| writer.print("{s}{s} = {}", .{
- if (assign_var.is_decl) "let " else "",
+ .assign_var => |assign_var| writer.print("{s} {s} {}", .{
assign_var.ident.getIdent(source),
+ if (assign_var.is_decl) ":=" else "=",
fmt(assign_var.value, source, indent),
}),
.@"while" => |@"while"| try writer.print("while {} {}", .{
@@ -149,7 +149,13 @@ pub const Expr = struct {
}
};
-const ParseError = error{ OutOfMemory, ExpectedRightParen, UnexpectedToken, InvalidAssignTarget };
+const ParseError = error{
+ OutOfMemory,
+ ExpectedRightParen,
+ UnexpectedToken,
+ InvalidAssignTarget,
+ ExprStatementMustBeCall,
+};
pub fn file(allocator: Allocator, lexer: *Lexer) !Block {
var stmts: std.ArrayList(Stmt) = .init(allocator);
@@ -177,16 +183,6 @@ fn block(allocator: Allocator, lexer: *Lexer) !Block {
fn statement(allocator: Allocator, lexer: *Lexer) ParseError!Stmt {
switch (lexer.peek().type) {
- .let => {
- const let = lexer.next();
- const ident = try mustEat(lexer, .identifier);
- _ = try mustEat(lexer, .equal);
- const value = try expression(allocator, lexer);
- return .{
- .loc = let.loc.combine(value.loc),
- .type = .{ .assign_var = .{ .ident = ident.loc, .is_decl = true, .value = value } },
- };
- },
.left_curly => {
const b = try block(allocator, lexer);
return .{
@@ -208,7 +204,12 @@ fn statement(allocator: Allocator, lexer: *Lexer) ParseError!Stmt {
},
else => {
const lhs = try expression(allocator, lexer);
- if (lexer.peek().type == .equal) {
+
+ const colon = if (lexer.peek().type == .colon)
+ try mustEat(lexer, .colon)
+ else
+ null;
+ if (colon != null or lexer.peek().type == .equal) {
_ = try mustEat(lexer, .equal);
const value = try expression(allocator, lexer);
if (lhs.type != .identifier) {
@@ -216,9 +217,11 @@ fn statement(allocator: Allocator, lexer: *Lexer) ParseError!Stmt {
return error.InvalidAssignTarget;
}
return .{
- .loc = lhs.loc,
- .type = .{ .assign_var = .{ .ident = lhs.loc, .is_decl = false, .value = value } },
+ .loc = lhs.loc.combine(value.loc),
+ .type = .{ .assign_var = .{ .ident = lhs.loc, .is_decl = colon != null, .value = value } },
};
+ } else if (lhs.type != .call) {
+ return error.ExprStatementMustBeCall;
}
return .{
.loc = lhs.loc,