Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions regression/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
TESTS=test001 test002 test012 test013 test003 test004 test005 test006 test007 test008 test009 test010 test011 test014 test015 test016 test017 test018
TESTS=test001 test002 test003 test004 test005 test006 test007 test008 test012 test013

# test019 test020 test021 test022 test023 test024 test025 test026
# More expressions:
# test003 test004 test005 test006 test007 test008

# Later:
# test009 test010 test 11
# test014 test015 test016 test017 test018 test019 test020 test021 test022 test023 test024 test025 test026
# test027 test028 test029 test030

.PHONY: check $(TESTS)
Expand Down
42 changes: 27 additions & 15 deletions src/Interpret.ml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,25 @@ module Expr =

open Expr

let rec eval expr st =
let rec eval expr st =
let eval' e = eval e st in
match expr with
| Var x -> st x
| Const z -> z
| Add (x, y) -> eval' x + eval' y
| Mul (x, y) -> eval' x * eval' y
| Var x -> st x
| Const z -> z
| Binop ("+", x, y) -> eval' x + eval' y
| Binop ("-", x, y) -> eval' x - eval' y
| Binop ("*", x, y) -> eval' x * eval' y
| Binop ("/", x, y) -> eval' x / eval' y
| Binop ("%", x, y) -> (eval' x) mod (eval' y)
| Binop ("<", x, y) -> if (eval' x) < (eval' y) then 1 else 0
| Binop ("<=", x, y) -> if (eval' x) <= (eval' y) then 1 else 0
| Binop (">", x, y) -> if (eval' x) > (eval' y) then 1 else 0
| Binop (">=", x, y) -> if (eval' x) >= (eval' y) then 1 else 0
| Binop ("==", x, y) -> if (eval' x) == (eval' y) then 1 else 0
| Binop ("!=", x, y) -> if (eval' x) <> (eval' y) then 1 else 0
| Binop ("&&", x, y) -> if ((eval' x) <> 0) && ((eval' y) <> 0) then 1 else 0
| Binop ("!!", x, y) -> if ((eval' x) <> 0) || ((eval' y) <> 0) then 1 else 0


end

Expand All @@ -22,27 +34,27 @@ module Stmt =

open Stmt

(* State update primitive *)
let update st x v = fun y -> if y = x then v else st y
(* State update primitive *)
let update st x v = fun y -> if y = x then v else st y

let rec eval stmt ((st, input, output) as conf) =
match stmt with
| Skip -> conf
| Assign (x, e) -> (update st x (Expr.eval e st), input, output)
| Read x ->
let z :: input' = input in
(update st x z, input', output)
| Read x ->
let z :: input' = input in
(update st x z, input', output)
| Write e -> (st, input, output @ [Expr.eval e st])
| Seq (s1, s2) -> eval s1 conf |> eval s2
| Seq (s1, s2) -> eval s1 conf |> eval s2

end

module Program =
struct

let eval p input =
let (_, _, output) =
Stmt.eval p ((fun _ -> failwith "undefined variable"), input, [])
let eval p input =
let (_, _, output) =
Stmt.eval p ((fun _ -> failwith "undefined variable"), input, [])
in
output

Expand Down
30 changes: 25 additions & 5 deletions src/Language.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,31 @@ module Expr =
type t =
| Var of string
| Const of int
| Add of t * t
| Mul of t * t
| Binop of string * t * t

ostap (
ostap(
parse: expr0;
expr0: h:expr1 t:(-"!!" expr1)*{
List.fold_left(fun e op ->Binop("!!", e, op)) h t};
expr1: h:expr2 t:(-"&&" expr2)*{
List.fold_left(fun e op ->Binop("&&", e, op)) h t};
expr2: h:expr3 t:(("==" | "!=" | "<=" | "<" | ">=" | ">")expr3)?{
match t with
| None -> h
| Some (op, y) -> Binop(Ostap.Matcher.Token.repr op, h, y)
};
expr3: h:expr4 t:(("+" | "-") expr4)*{
List.fold_left(fun e (op, y) -> Binop(Ostap.Matcher.Token.repr op, e, y)) h t};
expr4: h: prim t:(("*" | "/" | "%") prim)*{
List.fold_left(fun e (op, y) -> Binop(Ostap.Matcher.Token.repr op, e, y)) h t};
prim:
n:DECIMAL {Const n}
| e:IDENT {Var e}
| -"(" parse -")"
)
end

(* ostap (
parse: x:mull "+" y:parse {Add (x,y)} | mull;
mull : x:prim "*" y:mull {Mul (x,y)} | prim;
prim :
Expand All @@ -17,7 +38,7 @@ module Expr =
| -"(" parse -")"
)

end
end*)

(* AST statements/commands *)
module Stmt =
Expand Down Expand Up @@ -51,4 +72,3 @@ module Program =
let parse = Stmt.parse

end

59 changes: 50 additions & 9 deletions src/StackMachine.ml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ module Instr =
| ST of string
| ADD
| MUL
| SUB
| DIV
| MOD
| LT
| LE
| GT
| GE
| EQ
| NEQ
| AND
| OR

end

Expand Down Expand Up @@ -41,12 +52,32 @@ module Interpret =
| LD x -> (st x :: stack, st, input, output)
| ST x -> let z :: stack' = stack in
(stack', update st x z, input, output)
| _ -> let y :: x :: stack' = stack in
((match i with ADD -> (+) | _ -> ( * )) x y :: stack',
st,
input,
output
)
| ADD -> let y :: x :: stack' = stack in
((x + y):: stack', st, input, output)
| MUL -> let y :: x :: stack' = stack in
((x * y):: stack', st, input, output)
| SUB -> let y :: x :: stack' = stack in
((x - y):: stack', st, input, output)
| DIV -> let y :: x :: stack' = stack in
((x / y):: stack', st, input, output)
| MOD -> let y :: x :: stack' = stack in
((x mod y):: stack', st, input, output)
| LT -> let y :: x :: stack' = stack in
((if x < y then 1 else 0):: stack', st, input, output)
| LE -> let y :: x :: stack' = stack in
((if x <= y then 1 else 0):: stack', st, input, output)
| GT -> let y :: x :: stack' = stack in
((if x > y then 1 else 0):: stack', st, input, output)
| GE -> let y :: x :: stack' = stack in
((if x >= y then 1 else 0):: stack', st, input, output)
| EQ -> let y :: x :: stack' = stack in
((if x == y then 1 else 0):: stack', st, input, output)
| NEQ -> let y :: x :: stack' = stack in
((if x <> y then 1 else 0):: stack', st, input, output)
| AND -> let y :: x :: stack' = stack in
((if (x <> 0) && (y <> 0) then 1 else 0):: stack', st, input, output)
| OR -> let y :: x :: stack' = stack in
((if (x <> 0) || (y <> 0) then 1 else 0):: stack', st, input, output)
)
in
let (_, _, _, output) =
Expand All @@ -72,8 +103,19 @@ module Compile =
let rec compile = function
| Var x -> [LD x]
| Const n -> [PUSH n]
| Add (x, y) -> (compile x) @ (compile y) @ [ADD]
| Mul (x, y) -> (compile x) @ (compile y) @ [MUL]
| Binop ("+", x, y) -> (compile x) @ (compile y) @ [ADD]
| Binop ("-", x, y) -> (compile x) @ (compile y) @ [SUB]
| Binop ("*", x, y) -> (compile x) @ (compile y) @ [MUL]
| Binop ("/", x, y) -> (compile x) @ (compile y) @ [DIV]
| Binop ("%", x, y) -> (compile x) @ (compile y) @ [MOD]
| Binop ("<", x, y) -> (compile x) @ (compile y) @ [LT]
| Binop ("<=", x, y) -> (compile x) @ (compile y) @ [LE]
| Binop (">", x, y) -> (compile x) @ (compile y) @ [GT]
| Binop (">=", x, y) -> (compile x) @ (compile y) @ [GE]
| Binop ("==", x, y) -> (compile x) @ (compile y) @ [EQ]
| Binop ("!=", x, y) -> (compile x) @ (compile y) @ [NEQ]
| Binop ("&&", x, y) -> (compile x) @ (compile y) @ [AND]
| Binop ("!!", x, y) -> (compile x) @ (compile y) @ [OR]

end

Expand All @@ -99,4 +141,3 @@ module Compile =
end

end

Loading