about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/parser.zig38
-rw-r--r--src/tokenizer.zig2
2 files changed, 27 insertions, 13 deletions
diff --git a/src/parser.zig b/src/parser.zig
index d2067a1..64e670e 100644
--- a/src/parser.zig
+++ b/src/parser.zig
@@ -123,7 +123,7 @@ pub const Parser = struct {
         } });
     }
 
-    // Statement    ::= (AssignmentStatement | FunctionCallStatement | IfStatement | WhileStatement | ReturnStatement) SEMICOLON
+    // Statement    ::= (AssignmentStatement | ExternDeclaration | FunctionCallStatement | IfStatement | WhileStatement | ReturnStatement) SEMICOLON
     fn parse_statement(self: *Parser) ParserError!*Node {
         errdefer if (!self.try_context) std.debug.print("Error parsing statement {any}\n", .{self.peek_token()});
 
@@ -131,7 +131,8 @@ pub const Parser = struct {
             self.accept_parse(parse_if_statement) orelse
             self.accept_parse(parse_while_statement) orelse
             self.accept_parse(parse_return_statement) orelse
-            try self.parse_assignment_statement();
+            self.accept_parse(parse_assignment_statement) orelse
+            try self.parse_extern_declaration();
 
         _ = try self.parse_token(tokenizer.TokenType.SEMICOLON);
 
@@ -142,7 +143,7 @@ pub const Parser = struct {
         });
     }
 
-    // AssignmentStatement ::= "let" IDENTIFIER EQUALS (Type | Expression)
+    // AssignmentStatement ::= "let"? IDENTIFIER EQUALS Expression
     fn parse_assignment_statement(self: *Parser) ParserError!*Node {
         errdefer if (!self.try_context) std.debug.print("Error parsing assignment statement {any}\n", .{self.peek_token()});
 
@@ -155,16 +156,6 @@ pub const Parser = struct {
 
         _ = try self.parse_token(tokenizer.TokenType.EQUALS);
 
-        if (self.accept_parse(parse_type)) |typ| {
-            return self.create_node(.{
-                .ASSIGNMENT_STATEMENT = .{
-                    .is_declaration = is_declaration,
-                    .name = try self.arena.dupe(u8, identifier.type.IDENTIFIER),
-                    .expression = @constCast(typ),
-                },
-            });
-        }
-
         const expression = try self.parse_expression();
 
         return self.create_node(.{
@@ -176,6 +167,27 @@ pub const Parser = struct {
         });
     }
 
+    // ExternDeclaration ::= "extern" IDENTIFIER EQUALS Type
+    fn parse_extern_declaration(self: *Parser) ParserError!*Node {
+        errdefer if (!self.try_context) std.debug.print("Error parsing extern declaration {any}\n", .{self.peek_token()});
+
+        _ = try self.parse_token(.EXTERN);
+
+        const identifier = try self.parse_token(tokenizer.TokenType.IDENTIFIER);
+
+        _ = try self.parse_token(tokenizer.TokenType.EQUALS);
+
+        const typ = try self.parse_type();
+
+        return self.create_node(.{
+            .ASSIGNMENT_STATEMENT = .{
+                .is_declaration = true,
+                .name = try self.arena.dupe(u8, identifier.type.IDENTIFIER),
+                .expression = @constCast(typ),
+            },
+        });
+    }
+
     // FunctionCallStatement ::= (IDENTIFIER | FunctionDefinition) LPAREN FunctionArguments? RPAREN
     fn parse_function_call_statement(self: *Parser) ParserError!*Node {
         errdefer if (!self.try_context) std.debug.print("Error parsing function call statement {any}\n", .{self.peek_token()});
diff --git a/src/tokenizer.zig b/src/tokenizer.zig
index f0dcd26..138ad69 100644
--- a/src/tokenizer.zig
+++ b/src/tokenizer.zig
@@ -7,6 +7,7 @@ const TokenizerError = error{
 pub const TokenType = union(enum) {
     // Keywords
     LET: void,
+    EXTERN: void,
     IF: void,
     WHILE: void,
     RETURN: void,
@@ -67,6 +68,7 @@ pub const Tokenizer = struct {
         if (self.offset >= self.buf.len) return null;
 
         if (self.accept_string("let")) return self.create_token(.{ .LET = void{} });
+        if (self.accept_string("extern")) return self.create_token(.{ .EXTERN = void{} });
         if (self.accept_string("if")) return self.create_token(.{ .IF = void{} });
         if (self.accept_string("while")) return self.create_token(.{ .WHILE = void{} });
         if (self.accept_string("return")) return self.create_token(.{ .RETURN = void{} });