shithub: martian9

Download patch

ref: 98dd156dfa4ec242fa2ffd07d288805f468d5f28
parent: 668000f1422b8a401415e3adf9458eec98b44bca
author: smazga <[email protected]>
date: Mon Aug 10 14:06:58 EDT 2020

working on the let function

--- a/env.ml
+++ b/env.ml
@@ -1,6 +1,8 @@
 module T = Types.Types
 module Data = Map.Make (String)
 
+exception Runtime_error of string
+
 type env =
   { outer : env option
   ; data : Types.m9type Data.t ref
@@ -31,6 +33,6 @@
   | T.Symbol { T.value = key } ->
     (match find env sym with
     | Some found_env -> Data.find key !(found_env.data)
-    | None -> raise (Invalid_argument ("unknown symbol '" ^ key ^ "'")))
+    | None -> raise (Runtime_error ("unknown symbol '" ^ key ^ "'")))
   | _ -> raise (Invalid_argument "get: not a symbol")
 ;;
--- a/m9.ml
+++ b/m9.ml
@@ -56,11 +56,13 @@
     let sub_env = Env.make (Some env) in
     let rec bind_pairs = function
       | sym :: expr :: more ->
+         (print_endline (Printer.print sym true));
         Env.set sub_env sym (eval expr sub_env);
         bind_pairs more
-      | [ _ ] -> raise (Invalid_argument "missing 'let' body")
+      | x::[] -> raise (Reader.Syntax_error ("missing 'let' bindings (" ^ (Printer.print x true) ^ ")"))
       | [] -> ()
     in
+    print_endline ("bind_pairs:body: " ^ (Printer.print body true));
     bind_pairs bindings;
     eval body sub_env
   | T.List
@@ -81,7 +83,7 @@
             Env.set sub_env name arg;
             bind_args names args
           | [], [] -> ()
-          | _ -> raise (Invalid_argument "wrong parameter count for lambda")
+          | _ -> raise (Reader.Syntax_error "wrong parameter count for lambda")
         in
         bind_args arg_names args;
         eval expr sub_env)
@@ -98,7 +100,7 @@
     (match eval_ast ast env with
     | T.List { T.value = T.Proc { T.value = f } :: args } -> f args
     | _ as x ->
-      raise (Invalid_argument ("\"" ^ Printer.print x true ^ "\" not a function")))
+      raise (Reader.Syntax_error ("\"" ^ Printer.print x true ^ "\" not a function")))
   | _ -> eval_ast ast env
 ;;
 
--- a/notes.org
+++ b/notes.org
@@ -1,4 +1,5 @@
 * First things:
+** (let) doesn't work at all
 ** TODO need an "unspecified" type?
 ** TODO (display) should return unspecified
 ** TODO implement (pair)
--- a/reader.ml
+++ b/reader.ml
@@ -1,5 +1,7 @@
 module T = Types.Types
 
+exception Syntax_error of string
+
 let token_re =
   Str.regexp "~@\\|[][{}()'`~^@]\\|\"\\(\\\\.\\|[^\"]\\)*\"?\\|;.*\\|[^][  \n{}('\"`,;)]*"
 ;;
@@ -96,8 +98,7 @@
   let reader = read_form tokens in
   { form = Types.list [ Types.symbol sym; reader.form ]; tokens = reader.tokens }
 
-and read_hash all_tokens =
-  print_endline "read_hash";
+and read_vector all_tokens =
   match all_tokens with
   | [] -> raise End_of_file
   | token :: tokens ->
@@ -105,9 +106,7 @@
     | "(" ->
       let list_reader = read_list ")" { list_form = []; tokens } in
       { form = Types.vector list_reader.list_form; tokens = list_reader.tokens }
-    | _ as x ->
-      print_endline ("subtoken: " ^ x);
-      read_form tokens)
+    | _ -> read_form tokens)
 
 and read_form all_tokens =
   match all_tokens with
@@ -116,9 +115,7 @@
     (match token with
     | "'" -> read_quote "quote" tokens
     | "`" -> read_quote "quasiquote" tokens
-    | "#" ->
-      print_endline ("read_form:token: " ^ token);
-      read_hash tokens
+    | "#" -> read_vector tokens
     | "#|" ->
       let list_reader = read_list "|#" { list_form = []; tokens } in
       { form = T.Comment; tokens = list_reader.tokens }