diff --git a/regression/Makefile b/regression/Makefile index 659731508..9759b33e7 100644 --- a/regression/Makefile +++ b/regression/Makefile @@ -15,10 +15,10 @@ all: .depend $(TOPFILE).opt $(OCAMLDEP) $(PXFLAGS) *.ml > .depend $(TOPFILE).opt: $(SOURCES:.ml=.cmx) - $(OCAMLOPT) -o $(TOPFILE).opt $(OFLAGS) $(LIBS:.cma=.cmxa) ostap.cmx Expr.cmx Embedding.cmx $(SOURCES:.ml=.cmx) + $(OCAMLOPT) -o $(TOPFILE).opt $(OFLAGS) $(LIBS:.cma=.cmxa) ostap.cmx Syntax.cmx Embedding.cmx SM.cmx $(SOURCES:.ml=.cmx) $(TOPFILE).byte: $(SOURCES:.ml=.cmo) - $(OCAMLC) -o $(TOPFILE).byte $(BFLAGS) $(LIBS) ostap.cmo Expr.cmo Embedding.cmo $(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 *~ diff --git a/regression/common.ml b/regression/common.ml index 833088773..b44940b1d 100644 --- a/regression/common.ml +++ b/regression/common.ml @@ -1,5 +1,5 @@ open GT -open Expr +open Syntax.Expr open Embedding let state ps = List.fold_right (fun (x, v) s -> update x v s) ps empty diff --git a/src/Embedding.ml b/src/Embedding.ml index 5946027df..912173252 100644 --- a/src/Embedding.ml +++ b/src/Embedding.ml @@ -4,14 +4,14 @@ open GT (* Opening the substrate module for convenience. *) -open Expr +open Syntax (* Shortcuts for leaf constructors *) -let ( ! ) x = Var x -let ( !? ) n = Const n +let ( ! ) x = Expr.Var x +let ( !? ) n = Expr.Const n (* Implementation of operators *) -let binop op x y = Binop (op, x, y) +let binop op x y = Expr.Binop (op, x, y) let ( + ) = binop "+" let ( - ) = binop "-" @@ -27,14 +27,15 @@ let ( != ) = binop "!=" let ( && ) = binop "&&" let ( || ) = binop "!!" +let ( =:= ) x e = Stmt.Assign (x, e) +let read x = Stmt.Read x +let write e = Stmt.Write e +let (|>) x y = Stmt.Seq (x, y) + (* Some predefined names for variables *) let x = !"x" let y = !"y" let z = !"z" let t = !"t" -(* Voila; comment this out before submitting the solution *) -let _ = - List.iter (fun e -> Printf.printf "eval s (%s) = %d\n" (show(expr) e) (eval s e)) [x+y*z- !?3; t-z+y && x] - diff --git a/src/Expr.ml b/src/Expr.ml deleted file mode 100644 index 886a4ec7b..000000000 --- a/src/Expr.ml +++ /dev/null @@ -1,54 +0,0 @@ -(* Simple expressions: syntax and semantics *) - -(* Opening a library for generic programming (https://github.com/dboulytchev/GT). - The library provides "@type ..." syntax extension and plugins like show, etc. -*) -open GT - -(* The type for the expression. Note, in regular OCaml there is no "@type..." - notation, it came from GT. -*) -@type expr = - (* integer constant *) | Const of int - (* variable *) | Var of string - (* binary operator *) | Binop of string * expr * expr with show - -(* Available binary operators: - !! --- disjunction - && --- conjunction - ==, !=, <=, <, >=, > --- comparisons - +, - --- addition, subtraction - *, /, % --- multiplication, division, reminder -*) - -(* State: a partial map from variables to integer values. *) -type state = string -> int - -(* Empty state: maps every variable into nothing. *) -let empty = fun x -> failwith (Printf.sprintf "Undefined variable %s" x) - -(* Update: non-destructively "modifies" the state s by binding the variable x - to value v and returns the new state. -*) -let update x v s = fun y -> if x = y then v else s y - -(* An example of a non-trivial state: *) -let s = update "x" 1 @@ update "y" 2 @@ update "z" 3 @@ update "t" 4 empty - -(* Some testing; comment this definition out when submitting the solution. *) -let _ = - List.iter - (fun x -> - try Printf.printf "%s=%d\n" x @@ s x - with Failure s -> Printf.printf "%s\n" s - ) ["x"; "a"; "y"; "z"; "t"; "b"] - -(* Expression evaluator - - val eval : state -> expr -> int - - Takes a state and an expression, and returns the value of the expression in - the given state. -*) -let eval = failwith "Not implemented yet" - diff --git a/src/Makefile b/src/Makefile index bd97f82fd..203fdf346 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,7 +2,7 @@ TOPFILE = rc OCAMLC = ocamlc OCAMLOPT = ocamlopt OCAMLDEP = ocamldep -SOURCES = Expr.ml Embedding.ml +SOURCES = Syntax.ml Embedding.ml SM.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) diff --git a/src/SM.ml b/src/SM.ml new file mode 100644 index 000000000..230ec974a --- /dev/null +++ b/src/SM.ml @@ -0,0 +1,35 @@ +open GT + +(* The type for the stack machine instructions *) +@type insn = +(* binary operator *) | BINOP of string +(* read to stack *) | READ +(* write from stack *) | WRITE +(* load a variable to the stack *) | LD of string +(* store a variable from the stack *) | ST of string with show + +(* The type for the stack machine program *) +type prg = insn list + +(* The type for the stack machine configuration: a stack and a configuration from statement + interpreter + *) +type config = int list * Syntax.Stmt.config + +(* Stack machine interpreter + + val eval : config -> prg -> config + + Takes a configuration and a program, and returns a configuration as a result + *) +let eval _ = failwith "Not yet implemented" + +(* Stack machine compiler + + val compile : Syntax.Stmt.t -> prg + + Takes a program in the source language and returns an equivalent program for the + stack machine + *) + +let compile _ = failwith "Not yet implemented" diff --git a/src/Syntax.ml b/src/Syntax.ml new file mode 100644 index 000000000..9701f0951 --- /dev/null +++ b/src/Syntax.ml @@ -0,0 +1,70 @@ +(* Opening a library for generic programming (https://github.com/dboulytchev/GT). + The library provides "@type ..." syntax extension and plugins like show, etc. +*) +open GT + +(* Simple expressions: syntax and semantics *) +module Expr = + struct + + (* The type for expressions. Note, in regular OCaml there is no "@type..." + notation, it came from GT. + *) + @type t = + (* integer constant *) | Const of int + (* variable *) | Var of string + (* binary operator *) | Binop of string * t * t with show + + (* Available binary operators: + !! --- disjunction + && --- conjunction + ==, !=, <=, <, >=, > --- comparisons + +, - --- addition, subtraction + *, /, % --- multiplication, division, reminder + *) + + (* State: a partial map from variables to integer values. *) + type state = string -> int + + (* Empty state: maps every variable into nothing. *) + let empty = fun x -> failwith (Printf.sprintf "Undefined variable %s" x) + + (* Update: non-destructively "modifies" the state s by binding the variable x + to value v and returns the new state. + *) + let update x v s = fun y -> if x = y then v else s y + + (* Expression evaluator + + val eval : state -> t -> int + + Takes a state and an expression, and returns the value of the expression in + the given state. + *) + let eval _ = failwith "Not implemented yet" + + end + +(* Simple statements: syntax and sematics *) +module Stmt = + struct + + (* The type for statements *) + @type t = + (* read into the variable *) | Read of string + (* write the value of an expression *) | Write of Expr.t + (* assignment *) | Assign of string * Expr.t + (* composition *) | Seq of t * t with show + + (* The type of configuration: a state, an input stream, an output stream *) + type config = Expr.state * int list * int list + + (* Statement evaluator + + val eval : config -> t -> config + + Takes a configuration and a statement, and returns another configuration + *) + let eval _ = failwith "Not implemented yet" + + end