about summary refs log tree commit diff
path: root/src/parser
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser')
-rw-r--r--src/parser/Grammar.mly11
-rw-r--r--src/parser/Lexer.mll11
-rw-r--r--src/parser/Parser.ml23
3 files changed, 38 insertions, 7 deletions
diff --git a/src/parser/Grammar.mly b/src/parser/Grammar.mly
index d8e9ee0..d49c050 100644
--- a/src/parser/Grammar.mly
+++ b/src/parser/Grammar.mly
@@ -5,7 +5,8 @@ open Ast
 %token <string> IDENT
 %token LPR RPR
 %token LBR RBR
-%token ARROW ASTERISK BACKSLASH COLON DOUBLE_COLON COMMA DOT FATARROW UNDERSCORE
+%token ARROW ASSIGN ASTERISK BACKSLASH COLON DOUBLE_COLON COMMA DOT FATARROW UNDERSCORE
+%token DEF
 %token BOOL TRUE FALSE BOOL_ELIM AT
 %token FST SND
 %token TYPE
@@ -17,6 +18,7 @@ open Ast
 %left IDENT LPR APP BACKSLASH FST SND TYPE BOOL TRUE FALSE BOOL_ELIM
 
 %start <Ast.expr> start_expr
+%start <Ast.file> start_file
 
 %%
 
@@ -81,4 +83,11 @@ raw_expr:
 %inline
 expr: e = locate(raw_expr) { e }
 
+item:
+  | DEF; name = ident; COLON; tp = expr; ASSIGN; tm = expr
+    { Def { name; tp; tm } }
+
+file: items = list(item) { items }
+
 start_expr: e = expr; EOF { e }
+start_file: f = file; EOF { f }
diff --git a/src/parser/Lexer.mll b/src/parser/Lexer.mll
index 708bb64..22ae387 100644
--- a/src/parser/Lexer.mll
+++ b/src/parser/Lexer.mll
@@ -11,11 +11,13 @@ let ident = letter+
 rule token =
   parse
   | whitespace { token lexbuf }
+
   | "(" { LPR }
   | ")" { RPR }
   | "[" { LBR }
   | "]" { RBR }
   | "->" { ARROW }
+  | ":=" { ASSIGN }
   | "*" { ASTERISK }
   | "\\" { BACKSLASH }
   | "::" { DOUBLE_COLON }
@@ -24,14 +26,21 @@ rule token =
   | "." { DOT }
   | "=>" { FATARROW }
   | "_" { UNDERSCORE }
-  | "at" { AT }
+
+  | "def" { DEF }
+
   | "fst" { FST }
   | "snd" { SND }
+
   | "type" { TYPE }
+
   | "bool" { BOOL }
   | "true" { TRUE }
   | "false" { FALSE }
   | "bool-elim" { BOOL_ELIM }
+  | "at" { AT }
+
   | ident { IDENT (Lexing.lexeme lexbuf) }
+
   | eof { EOF }
   | (_ as illegal_char) { raise (IllegalCharacter illegal_char) }
diff --git a/src/parser/Parser.ml b/src/parser/Parser.ml
index 88448c9..ae86885 100644
--- a/src/parser/Parser.ml
+++ b/src/parser/Parser.ml
@@ -1,3 +1,9 @@
+let handle_syntax_error ~source ~lexbuf f = try f () with
+  | Lexer.IllegalCharacter illegal_char ->
+    Error.illegal_character ~loc:(Asai.Range.of_lexbuf ~source lexbuf) illegal_char
+  | Grammar.Error ->
+    Error.syntax_error ~loc:(Asai.Range.of_lexbuf ~source lexbuf)
+
 let parse_expr (s : string) : Ast.expr =
   let lexbuf = Lexing.from_string s in
   let string_source : Asai.Range.string_source = {
@@ -6,8 +12,15 @@ let parse_expr (s : string) : Ast.expr =
   } in
   let source = `String string_source in
   Eff.run ~env:source @@ fun () ->
-  try Grammar.start_expr Lexer.token lexbuf with
-  | Lexer.IllegalCharacter illegal_char ->
-    Error.illegal_character ~loc:(Asai.Range.of_lexbuf ~source lexbuf) illegal_char
-  | Grammar.Error ->
-    Error.syntax_error ~loc:(Asai.Range.of_lexbuf ~source lexbuf)
+  handle_syntax_error ~source ~lexbuf @@ fun () ->
+  Grammar.start_expr Lexer.token lexbuf
+
+let parse_file (path : string) : Ast.file =
+  let inchan = try open_in path with
+    | Sys_error msg -> Error.file_open_error ~path ~msg
+  in
+  let lexbuf = Lexing.from_channel inchan in
+  let source = `File path in
+  Eff.run ~env:source @@ fun () ->
+  handle_syntax_error ~source ~lexbuf @@ fun () ->
+  Grammar.start_file Lexer.token lexbuf