Commits

Anonymous committed c657bdb

parser

Comments (0)

Files changed (5)

 =====
 
 	$ ./minruby sample/test.rb
+
+
+実装した事
+========
+
+	- min_ruby のパース
+
+
+min_rubyにある構文
+================
+
+	- メソッド定義
+	- クラス定義
+	- 関数呼び出し
+	- フィールド参照
+	- 変数代入
+	- if式
+	- リテラル(数値、真偽値)
+	- 四則演算
+	- 大小比較
+	- bool演算
+
+
+min_rubyにまだないもの
+====================
+	
+	- 文字, 文字列, 配列
+	- 正規表現
+	- ブロック構文
+	- 範囲リテラル
+	- シンボル
+	- 省略可能な引数
+	- 引数カッコの省略
+	- インスタンス変数
+	- 継承
+	- モジュール
 open Genlex
 
 let lexer =
-  Genlex.make_lexer ["def"; "end"; "lambda"; "if"; "else"; "class"; "return";
-		     "("; ")"; "."; ","; "+"; "-"; "*"; "/"; "<="; ">="; "<"; ">"; "="; "&&"; "||"; "\n"]
+  Genlex.make_lexer ["def"; "end"; "lambda"; "if"; "then"; "else"; "class"; "return"; "("; ")"; "."; ",";
+		     "+"; "-"; "*"; "/"; "=="; "<="; ">="; "<"; ">"; "="; "&&"; "||"; "\n"]
+		     
 
+(* debug用 *)
 let stoken = function
   | Kwd s -> "kwd(" ^ s ^ ")"
   | Ident s -> "ident(" ^ s ^ ")"
 let main =
   let ch = open_in Sys.argv.(1) in
   let tstream = Lexer.lexer (Stream.of_channel ch) in
-  let rec local store =
-    try local (Stream.next tstream :: store) with
+  let rec read_iter store =
+    try read_iter (Stream.next tstream :: store) with
     | Stream.Failure -> List.rev store
     | Stream.Error msg -> p "stream error: %s\n" msg; List.rev store
   in
-  match Parser.parse (local []) with
-  | Inl (e, ts) ->
-      if List.length ts = 0 then begin
-	p "=== main: parse success! ===\n";
-	ignore (Eval.eval Stdlib.init_ctx (e :> Stdlib.state list))
-      end else 
-	List.iter (p "token: %s\n" $ stoken) ts
-  | Inr msg ->
-      p "main: parse err: %s\n" msg
+  let ast = Parser.parse (read_iter []) in
+  (*Eval.eval Stdlib.init_ctx (ast :> Stdlib.state list)*)
+  ast
   | _ -> Inr "mul_op"
 
 let rel_op = function
-  | Kwd "="  :: ts -> Inl (`Eq, ts)
+  | Kwd "==" :: ts -> Inl (`Eq, ts)
   | Kwd "<=" :: ts -> Inl (`Le, ts)
   | Kwd ">=" :: ts -> Inl (`Ge, ts)
   | Kwd "<"  :: ts -> Inl (`Lt, ts)
 
 
 let sep_many delim p =
-  p >>= fun x1 -> many (kwd delim >> p) >>= fun xs -> return (x1::xs)
+  (p >>= fun x1 -> many (kwd delim >> p) >>= fun xs -> return (x1::xs))
+  <|>
+  (return [])
 
 let rec expr : expr parser = fun code ->
   begin
     many (mul_op >>= fun mop -> factor() >>= fun f -> return(mop, f)) >>=
     (return $ List.fold_left (fun mtm (mop,fac) -> `Mtm (mop, fac, mtm)) (`MFac (f1)))
   end code
-and factor () = fun code ->
-begin
+and factor () =
   (literal >>= fun l -> return (`FLit l))
     <|> (kwd "(" >> expr >>= fun e -> kwd ")" >> return (`FExp e))
-end code
 
-and arguments () = fun code ->
-begin
-  kwd "(" >> sep_many "," expr >>= fun args -> kwd ")" >> return args
-end code
+and arguments () =
+  (kwd "(" >> sep_many "," expr >>= fun args -> kwd ")" >> return args)
 
 
 type st = [
     `TExpr of expr | `TAssign of string * expr | `TDef of string * string list * st list
   | `TClass of string * st list ]
 (**
-   ʸ(statement) �Υѡ�����
+   (statement) のパーサー
 **)
 let rec state : st parser = fun code ->
   begin
-    (* ����ʸ *)
+    (* 代入文 *)
     (ident >>= fun vname -> kwd "=" >> expr >>= fun e -> return (`TAssign (vname, e)))
     <|>
-    (* �᥽�å���� *)
+    (* メソッド定義 *)
     (kwd "def" >> ident >>= fun fname -> kwd "(" >> sep_many "," ident >>= fun argnames ->
       kwd ")" >> many state >>= fun fbody -> kwd "end" >> return (`TDef (fname, argnames, fbody)))
     <|>
-    (* ���饹��� *)
+    (* クラス定義 *)
     (kwd "class" >> ident >>= fun class_name -> many state >>= fun states -> kwd "end" >> return (`TClass (class_name, states)))
     <|>
     (expr >>= fun e -> return (`TExpr e))
   end code
 
-let parse = many state
+let parse code =
+  match (many state) code with
+  | Inl (states, []) ->
+      p "=== parse success! ===\n";
+      states
+  | Inl (states, ts) ->
+      List.iter (p "token: %s\n" $ stoken) ts;
+      states
+  | Inr msg ->
+      failwith @@ "parse err: " ^ msg
+
+
-puts (5)
-(*
-putStr (hoge)
 class C
-  def ff (hoge, foo)
-    3
+  def f (x, y)
+    if (4 * x == 4 || 3 * (y+2) >= 6+1) then
+      true
+    else
+      false
+    end
+  end
+  
+  def g ()
+    f (0, 1)
   end
 end
-def f (x)
-  1 + 2
+
+class D
+  def foo ()
+    puts 5
+  end
 end
 
-*)
+def fib (n)
+  if n <= 2 then
+    0
+  else
+    (fib (n - 1)) + (fib (n - 2))
+  end
+end
+
+puts (fib (3))