From 84f80a0d049fc1faef7a345895e665f14508fe25 Mon Sep 17 00:00:00 2001 From: Hiroshi Sakurai Date: Wed, 11 Feb 2015 05:02:03 +0900 Subject: [PATCH] added ref --- scala/mincaml2js.scala | 7 ++++++- src/Makefile | 2 +- src/emit.ml | 1 + src/lexer.mll | 2 ++ src/parser.mly | 5 ++++- src2/Makefile | 2 +- src2/parser.ml | 4 ++++ src3/Makefile | 2 +- src3/emit.ml | 1 + test/ref.ml | 8 ++++++++ 10 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 test/ref.ml diff --git a/scala/mincaml2js.scala b/scala/mincaml2js.scala index eec0435..d4f4e28 100644 --- a/scala/mincaml2js.scala +++ b/scala/mincaml2js.scala @@ -174,6 +174,7 @@ object parse extends RegexParsers { def sub: Parser[E] = "-." ~> app ^^ { a => EPre("-", a) } | "-" ~> app ^^ { a => EPre("-", a) } | + "!" ~> app ^^ { a => EBin(a,".", EVar("ref")) } | app def app: Parser[E] = @@ -199,6 +200,9 @@ object parse extends RegexParsers { } case a ~ b ~ None => b.foldLeft(a) { case (a, b) => EGet(a, EStr(b)) } } | + simple_exp ~ (":=" ~> let) ^^ { + case a ~ b => EPut(a, EStr("ref"), b) + } | simple_exp def apply(str: String) = { @@ -354,6 +358,7 @@ object cnv { oc.printf("function print_int(n) { console._stdout.write(\"\"+n);}\n") oc.printf("var print_string = print_int;\n"); oc.printf("function makeArray(n,v) { var a = []; for(var i = 0; i < n; i++) a[i] = v; return a; }\n") + oc.printf("function ref(n) { return {ref:n}; }\n") oc.printf("var abs_float = Math.abs;\n") oc.printf("var sqrt = Math.sqrt;\n") oc.printf("var sin = Math.sin;\n") @@ -382,7 +387,7 @@ object main extends App { object test extends App { val tests = List( - "record", "string", "as", "list1", "match", "begin", "print", "sum-tail", "gcd", "sum", "fib", "ack", "even-odd", + "ref", "record", "string", "as", "list1", "match", "begin", "print", "sum-tail", "gcd", "sum", "fib", "ack", "even-odd", "adder", "funcomp", "cls-rec", "cls-bug", "cls-bug2", "shuffle", "spill", "spill2", "spill3", "join-stack", "join-stack2", "join-stack3", "join-reg", "join-reg2", "non-tail-if", "non-tail-if2", diff --git a/src/Makefile b/src/Makefile index 54b2611..9e6c24b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -11,7 +11,7 @@ clean:: nobackup SOURCES = syntax.ml parser.mly lexer.mll to_if.ml emit.ml main.ml -TESTS = record string as list1 match begin print sum-tail gcd sum fib ack even-odd \ +TESTS = ref record string as list1 match begin print sum-tail gcd sum fib ack even-odd \ adder funcomp cls-rec cls-bug cls-bug2 \ shuffle spill spill2 spill3 join-stack join-stack2 join-stack3 \ join-reg join-reg2 non-tail-if non-tail-if2 \ diff --git a/src/emit.ml b/src/emit.ml index 4bfa366..86dde4d 100644 --- a/src/emit.ml +++ b/src/emit.ml @@ -43,6 +43,7 @@ let f oc ast = Printf.fprintf oc "function print_int(n) { console._stdout.write(\"\"+n);}\n"; Printf.fprintf oc "var print_string = print_int;\n"; Printf.fprintf oc "function makeArray(n,v) { var a = []; for(var i = 0; i < n; i++) a[i] = v; return a; }\n"; + Printf.fprintf oc "function ref(n) { return {ref:n}; }\n"; Printf.fprintf oc "var abs_float = Math.abs;\n"; Printf.fprintf oc "var sqrt = Math.sqrt;\n"; Printf.fprintf oc "var sin = Math.sin;\n"; diff --git a/src/lexer.mll b/src/lexer.mll index f35337d..dec5e6b 100644 --- a/src/lexer.mll +++ b/src/lexer.mll @@ -61,6 +61,8 @@ rule token = parse | "Array.create" { ARRAY_CREATE } | '.' { DOT } | "<-" { LESS_MINUS } +| ":=" { COLON_EQUAL } +| '!' { EXCLAM } | ';' { SEMICOLON } | eof { EOF } | '"' ([^ '"' '\\'] | '\\' _)* '"' { let s = Lexing.lexeme lexbuf in STRING(String.sub s 1 ((String.length s)-2))} diff --git a/src/parser.mly b/src/parser.mly index 28bf0db..66954c6 100644 --- a/src/parser.mly +++ b/src/parser.mly @@ -39,12 +39,13 @@ open Syntax %token TYPE OF SEMISEMI AST %token LBRACK RBRACK CONS AT AS %token MUTABLE LBRACE RBRACE COLON +%token EXCLAM COLON_EQUAL %token EOF %right prec_let %right SEMICOLON CONS AT AS %right prec_if -%right LESS_MINUS +%right LESS_MINUS COLON_EQUAL %left COMMA %left EQUAL LESS_GREATER LESS GREATER LESS_EQUAL GREATER_EQUAL %left PLUS MINUS PLUS_DOT MINUS_DOT @@ -92,6 +93,7 @@ exp: | Float(f) -> Float(-.f) | e -> Pre("-", e) } +| EXCLAM exp %prec prec_unary_minus { Bin($2,".",Var "ref") } | exp CONS exp { CApp("Cons", Tuple[$1; $3]) } | exp AT exp { App(Var "concat", [$1; $3]) } | exp AS IDENT { Bin($1, "as", Var $3) } @@ -133,6 +135,7 @@ exp: | LET LBRACE fields RBRACE EQUAL exp IN exp { Match($6, [Rec $3, None, $8]) } | simple_exp DOT LPAREN exp RPAREN LESS_MINUS exp { Put($1, $4, $7) } | simple_exp DOT IDENT LESS_MINUS exp { Put($1, Str $3, $5) } +| simple_exp COLON_EQUAL exp { Put($1, Str "ref", $3) } | exp SEMICOLON exp { Let(Syntax.gentmp (), $1, $3) } | ARRAY_CREATE simple_exp simple_exp %prec prec_app { Array($2, $3) } | error diff --git a/src2/Makefile b/src2/Makefile index 776f874..9b8e2e4 100644 --- a/src2/Makefile +++ b/src2/Makefile @@ -1,5 +1,5 @@ RESULT = mincaml -TESTS = record string as list1 match begin print sum-tail gcd sum fib ack even-odd \ +TESTS = ref record string as list1 match begin print sum-tail gcd sum fib ack even-odd \ adder funcomp cls-rec cls-bug cls-bug2 \ shuffle spill spill2 spill3 join-stack join-stack2 join-stack3 \ join-reg join-reg2 non-tail-if non-tail-if2 \ diff --git a/src2/parser.ml b/src2/parser.ml index 101a5c9..8c0851e 100644 --- a/src2/parser.ml +++ b/src2/parser.ml @@ -192,6 +192,7 @@ and sub i = i |> ( | Float(f) -> Float (-. f) | a -> Pre("-", a) )) <|> + ((str "!" >> app) >>> (fun a -> Bin(a, ".", Var "ref") )) <|> app ) and app i = i |> ( @@ -222,6 +223,9 @@ and dot i = i |> ( end | ((a, b), None) -> List.fold_left (fun a b -> Get(a, Str b) ) a b )) <|> + (simple_exp <~> (str ":=" >> _let) >>> ( + fun (a,b) -> Put(a, Str "ref", b) + )) <|> simple_exp ) and start i = i |> (exp << skip) diff --git a/src3/Makefile b/src3/Makefile index 198ca0d..317574d 100644 --- a/src3/Makefile +++ b/src3/Makefile @@ -1,6 +1,6 @@ .PHONY: clean all default RESULT = mincaml -TESTS = record string as list1 match begin print sum-tail gcd sum fib ack even-odd \ +TESTS = ref record string as list1 match begin print sum-tail gcd sum fib ack even-odd \ adder funcomp cls-rec cls-bug cls-bug2 \ shuffle spill spill2 spill3 join-stack join-stack2 join-stack3 \ join-reg join-reg2 non-tail-if non-tail-if2 \ diff --git a/src3/emit.ml b/src3/emit.ml index 0c28970..f41150b 100644 --- a/src3/emit.ml +++ b/src3/emit.ml @@ -70,6 +70,7 @@ let f oc ast = Printf.fprintf oc "function print_int(n) { console._stdout.write(\"\"+n);}\n"; Printf.fprintf oc "var print_string = print_int;\n"; Printf.fprintf oc "function makeArray(n,v) { var a = []; for(var i = 0; i < n; i++) a[i] = v; return a; }\n"; + Printf.fprintf oc "function ref(n) { return {ref:n}; }\n"; Printf.fprintf oc "var abs_float = Math.abs;\n"; Printf.fprintf oc "var sqrt = Math.sqrt;\n"; Printf.fprintf oc "var sin = Math.sin;\n"; diff --git a/test/ref.ml b/test/ref.ml new file mode 100644 index 0000000..a52f644 --- /dev/null +++ b/test/ref.ml @@ -0,0 +1,8 @@ +let a = ref 5 in +let b = !a in +print_int b; +a := b + 1; +print_int(!a); +a := !a + 1; +print_int(!a); +print_newline() \ No newline at end of file