diff --git a/Makefile b/Makefile index 4b162e273..19a6c8037 100644 --- a/Makefile +++ b/Makefile @@ -12,4 +12,5 @@ regression: clean: pushd src && make clean && popd + pushd regression && make clean && popd diff --git a/regression/Makefile b/regression/Makefile index 9759b33e7..8ba71b637 100644 --- a/regression/Makefile +++ b/regression/Makefile @@ -9,7 +9,7 @@ BFLAGS = -rectypes -I `ocamlfind -query GT` -I `ocamlfind -query re` -I `ocamlf OFLAGS = $(BFLAGS) all: .depend $(TOPFILE).opt - ./$(TOPFILE).opt > $(TOPFILE).log && diff $(TOPFILE).log orig/$(TOPFILE).log + ./$(TOPFILE).opt > $(TOPFILE).log && diff -a --strip-trailing-cr $(TOPFILE).log orig/$(TOPFILE).log .depend: $(SOURCES) $(OCAMLDEP) $(PXFLAGS) *.ml > .depend @@ -21,7 +21,7 @@ $(TOPFILE).byte: $(SOURCES:.ml=.cmo) $(OCAMLC) -o $(TOPFILE).byte $(BFLAGS) $(LIBS) ostap.cmo Syntax.cmo Embedding.cmo SM.cmo $(SOURCES:.ml=.cmo) clean: - rm -Rf *.cmi *.cmo *.cmx *.annot *.o *.opt *.byte *~ + rm -Rf *.cmi *.cmo *.cmx *.annot *.o *.opt *.byte *~ *.log .depend -include .depend # generic rules diff --git a/src/Driver.ml b/src/Driver.ml new file mode 100644 index 000000000..604223660 --- /dev/null +++ b/src/Driver.ml @@ -0,0 +1,41 @@ +open Ostap + +let parse infile = + let s = Util.read infile in + Util.parse + (object + inherit Matcher.t s + inherit Util.Lexers.decimal s + inherit Util.Lexers.skip [ + Matcher.Skip.whitespaces " \t\n"; + Matcher.Skip.lineComment "--"; + Matcher.Skip.nestedComment "(*" "*)" + ] s + end + ) + (ostap (!(Language.parse) -EOF)) + +let main = + try + let interpret = Sys.argv.(1) = "-i" in + let stack = Sys.argv.(1) = "-s" in + let infile = Sys.argv.(2) in + match parse infile with + | `Ok ((_, stmt) as prog) -> + let rec read acc = + try + let r = read_int () in + Printf.printf "> "; + read (acc @ [r]) + with End_of_file -> acc + in + let input = read [] in + let output = + if interpret + then Language.eval prog input + else SM.eval (SM.compile prog) input + in + List.iter (fun i -> Printf.printf "%d\n" i) output + | `Fail er -> Printf.eprintf "Syntax error: %s\n" er + with Invalid_argument _ -> + Printf.printf "Usage: rc [-i] \n" diff --git a/src/Syntax.ml b/src/Language.ml similarity index 82% rename from src/Syntax.ml rename to src/Language.ml index b493f2f5f..fa86e046a 100644 --- a/src/Syntax.ml +++ b/src/Language.ml @@ -1,8 +1,11 @@ (* Opening a library for generic programming (https://github.com/dboulytchev/GT). The library provides "@type ..." syntax extension and plugins like show, etc. *) -open GT - +open GT + +(* Opening a library for combinator-based syntax analysis *) +open Ostap.Combinators + (* Simple expressions: syntax and semantics *) module Expr = struct @@ -68,6 +71,11 @@ module Expr = | Var x -> st x | Binop (op, x, y) -> to_func op (eval st x) (eval st y) + (* Statement parser *) + ostap ( + parse: empty {failwith "Not implemented yet"} + ) + end (* Simple statements: syntax and sematics *) @@ -96,13 +104,27 @@ module Stmt = | Write e -> (st, i, o @ [Expr.eval st e]) | Assign (x, e) -> (Expr.update x (Expr.eval st e) st, i, o) | Seq (s1, s2) -> eval (eval conf s1) s2 - + + (* Statement parser *) + ostap ( + parse: empty {failwith "Not implemented yet"} + ) + end +(* The top-level definitions *) + +(* The top-level syntax category is statement *) +type t = Stmt.t + (* Top-level evaluator - val eval : int list -> Stmt.t -> int list + eval : t -> int list -> int list - Takes an input stream, a program, and returns the output stream this program calculates - *) -let eval i p = let _, _, o = Stmt.eval (Expr.empty, i, []) p in o + Takes a program and its input stream, and returns the output stream +*) +let eval p i = + let _, _, o = Stmt.eval (Expr.empty, i, []) p in o + +(* Top-level parser *) +let parse = Stmt.parse diff --git a/src/Makefile b/src/Makefile index 203fdf346..5de1b4eda 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,7 +2,7 @@ TOPFILE = rc OCAMLC = ocamlc OCAMLOPT = ocamlopt OCAMLDEP = ocamldep -SOURCES = Syntax.ml Embedding.ml SM.ml +SOURCES = Language.ml Embedding.ml SM.ml Driver.ml LIBS = GT.cma unix.cma re.cma re_emacs.cma re_str.cma CAMLP5 = -pp "camlp5o -I `ocamlfind -query GT.syntax` -I `ocamlfind -query ostap.syntax` pa_ostap.cmo pa_gt.cmo -L `ocamlfind -query GT.syntax`" PXFLAGS = $(CAMLP5) @@ -21,7 +21,7 @@ $(TOPFILE).byte: $(SOURCES:.ml=.cmo) $(OCAMLC) -o $(TOPFILE).byte $(BFLAGS) $(LIBS) ostap.cma $(SOURCES:.ml=.cmo) clean: - rm -Rf *.cmi *.cmo *.cmx *.annot *.o *.opt *.byte *~ + rm -Rf *.cmi *.cmo *.cmx *.annot *.o *.opt *.byte *~ .depend -include .depend # generic rules diff --git a/src/SM.ml b/src/SM.ml index 0b9297ff7..7b4dde9e3 100644 --- a/src/SM.ml +++ b/src/SM.ml @@ -16,7 +16,7 @@ type prg = insn list (* The type for the stack machine configuration: a stack and a configuration from statement interpreter *) -type config = int list * Stmt.config +type config = int list * Language.Stmt.config (* Stack machine interpreter @@ -48,6 +48,7 @@ let run i p = let (_, (_, _, o)) = eval ([], (Expr.empty, i, [])) p in o (* Stack machine compiler val compile : Stmt.t -> prg + val compile : Language.Stmt.t -> prg Takes a program in the source language and returns an equivalent program for the stack machine