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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
35 changes: 0 additions & 35 deletions Driver.ml

This file was deleted.

5 changes: 5 additions & 0 deletions Kirill_Klimuk_2304/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/Driver
/Driver.cmi
/Driver.cmo
/Expr.cmi
/Expr.cmo
34 changes: 34 additions & 0 deletions Kirill_Klimuk_2304/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
MKDIR ?= mkdir -vp
CP ?= cp

OB=ocamlbuild -cflag -g -no-hygiene -use-ocamlfind -plugin-tag "package(str)" -classic-display
ifdef OBV
OB += -verbose 6
endif

BYTE_TARGETS=src/rc.byte
NATIVE_TARGETS=src/rc.native

.PHONY: all clean runtime checkTests checkETests checkDETests

.DEFAULT_GOAL: all

all: main runtime

runtime:
cd runtime && make all && cd ..

main:
$(OB) -Is src $(BYTE_TARGETS) $(NATIVE_TARGETS)

checkTests:
cd regression && make check && cd ..

checkETests:
cd regression && cd expressions && make check && cd .. && cd ..

checkDETests:
cd regression && cd deep-expressions && make check && cd .. && cd ..

clean:
cd runtime && make clean && cd .. && cd regression && make clean && cd .. && $(RM) -r _build *.log *.native *.byte
29 changes: 29 additions & 0 deletions Kirill_Klimuk_2304/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Dependencies:

`$ opam pin add GT https://github.com/Kakadu/GT.git -n -y`

`$ opam install camlp5 -y`

`$ opam install GT ocamlfind -y`

Build & use:

`$ make`

`$ gcc -m32 -c runtime.c`

`$ RUNTIME=. ./compiler file.expr`

`$ ./file`

If make fails with an error which states that GT.Syntax.All cannot be found, make sure you initialized and configured opam:

`$ opam init`

``$ eval `opam config env` ``

Ostap library:

`$ opam pin add ostap https://github.com/dboulytchev/ostap.git -n -y`

`$ opam install ostap -y`
4 changes: 4 additions & 0 deletions Kirill_Klimuk_2304/_tags
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
true: debug, rectypes

<src/*.ml>: syntax(camlp5o), package(ostap.syntax)
<src/*.native> or <src/*.byte>: package(re,ostap,GT)
6 changes: 6 additions & 0 deletions Kirill_Klimuk_2304/runtime/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
all:
gcc -m64 -c runtime.c

clean:
rm -f runtime.o *~

14 changes: 14 additions & 0 deletions Kirill_Klimuk_2304/runtime/runtime.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# include <stdio.h>

long lread () {
long d;
printf ("> ");
fflush (stdout);
scanf ("%ld", &d);
return d;
}

void lwrite (long n) {
printf ("%ld\n", n);
fflush (stdout);
}
51 changes: 51 additions & 0 deletions Kirill_Klimuk_2304/src/Driver.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
open Language
open Expr
open Stmt
open Ostap

let parse filename =
let s = Util.read filename in
Util.parse
(object
inherit Matcher.t s
inherit Util.Lexers.ident ["read"; "write"; "skip"; "if"; "while"; "for"; "repeat"] s
inherit Util.Lexers.decimal s
inherit Util.Lexers.skip [
Matcher.Skip.whitespaces " \t\r\n";
Matcher.Skip.lineComment "--";
Matcher.Skip.nestedComment "(*" "*)"
] s
end)
(ostap (!(Stmt.parse) -EOF))

let main =
try
let interpret = Sys.argv.(1) = "-i" in
let stack = Sys.argv.(1) = "-s" in
let to_compile = not (interpret || stack) in
let infile = Sys.argv.(if not to_compile then 2 else 1) in
match parse infile with
| `Ok prog ->
if to_compile
then
let basename = Filename.chop_suffix infile ".expr" in
ignore @@ X64.build prog basename
else
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 Interpret.Program.eval prog input
else StackMachine.Interpret.run (StackMachine.Compile.Program.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 | -s] <input file.expr>\n"

48 changes: 48 additions & 0 deletions Kirill_Klimuk_2304/src/Interpret.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
open Language

(* Interpreter for expressions *)
module Expr =
struct

open Expr

let rec eval expr st =
let eval' e = eval e st in
match expr with
| Var x -> st x
| Const z -> z
| Bin (f, x, y) -> (operation_to_func f) (eval' x) (eval' y)
end

(* Interpreter for statements *)
module Stmt =
struct

open Stmt

(* 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)
| Write e -> (st, input, output @ [Expr.eval e st])
| Seq (s1, s2) -> eval s1 conf |> eval s2
| IfElse (e, s1, s2) -> if (Expr.eval e st) == 1 then eval s1 conf else eval s2 conf
| WhileDo (e, s) -> if (Expr.eval e st) == 1 then eval s conf |> eval stmt else conf
| RepeatUntil (s,e) -> eval s conf |> eval (WhileDo(Bin("==",e,Const 0),s))
end

module Program =
struct

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

end
103 changes: 103 additions & 0 deletions Kirill_Klimuk_2304/src/Language.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
open Ostap.Util
(* AST for expressions *)
module Expr =
struct

type t =
| Var of string
| Const of int
| Bin of string * t * t

let rec expr_parse s =
expr id
[|
(*Bool 0/1*)
`Nona , [ostap ("!!"), (fun x y -> Bin ("||", x, y))];
`Nona , [ostap ("&&"), (fun x y -> Bin ("&&", x, y))];
(*Bool Arith*)
`Nona, [ostap ("=="), (fun x y -> Bin ("==", x, y));
ostap ("!="), (fun x y -> Bin ("!=", x, y));
ostap ("<="), (fun x y -> Bin ("<=", x, y));
ostap (">="), (fun x y -> Bin (">=", x, y));
ostap ("<"), (fun x y -> Bin ("<", x, y));
ostap (">"), (fun x y -> Bin (">", x, y))];
(*Arith*)
`Lefta, [ostap ("+"), (fun x y -> Bin ("+", x, y));
ostap ("-"), (fun x y -> Bin ("-", x, y))];

`Lefta, [ostap ("*"), (fun x y -> Bin ("*", x, y));
ostap ("/"), (fun x y -> Bin ("/", x, y));
ostap ("%"), (fun x y -> Bin ("%", x, y))];

|]
expr' s
and
ostap (
expr':
n:DECIMAL {Const n}
| e:IDENT {Var e}
| -"(" expr_parse -")")


let operation_to_func f = match f with
| "+" -> fun x y -> x + y
| "*" -> fun x y -> x * y
| "-" -> fun x y -> x - y
| "/" -> fun x y -> x / y
| "%" -> fun x y -> x mod y
(* Bool expressions with arith. operands*)
| "==" -> fun x y -> if x == y then 1 else 0
| "!=" -> fun x y -> if x != y then 1 else 0
| ">=" -> fun x y -> if x >= y then 1 else 0
| ">" -> fun x y -> if x > y then 1 else 0
| "<" -> fun x y -> if x < y then 1 else 0
| "<=" -> fun x y -> if x <=y then 1 else 0
(* Bool expressions with 0/1 operands*)
| "&&" -> fun x y -> if (x != 0 && y != 0) then 1 else 0
| "||" -> fun x y -> if (x == 0 && y == 0) then 0 else 1
| f -> failwith (Printf.sprintf "Fail on operation %s" f)
end

(* AST statements/commands *)
module Stmt =
struct

type t =
| Skip
| Assign of string * Expr.t
| Read of string
| Write of Expr.t
| Seq of t * t
| IfElse of Expr.t * t * t
| WhileDo of Expr.t * t
| RepeatUntil of t * Expr.t

let expr = Expr.expr_parse

ostap (
simp: x:IDENT ":=" e:expr {Assign (x, e)}
| %"read" "(" x:IDENT ")" {Read x}
| %"write" "(" e:expr ")" {Write e}
| %"skip" {Skip}
| %"if" e: expr "then" s1: parse "fi" {IfElse (e,s1,Skip)}
| %"if" e: expr "then" s1: parse "else" s2: parse "fi" {IfElse (e,s1,s2)}
| %"while" e: expr "do" s: parse "od" {WhileDo (e,s)}
| %"for" a: simp "," e: expr "," ai: simp "do" s: parse "od" {Seq (a, WhileDo (e, Seq (s, ai)))}
| %"repeat" s: parse "until" e: expr {RepeatUntil (s,e)};

parse:
s:simp ";" d:parse {Seq (s,d)}
| simp
)

end

module Program =
struct

type t = Stmt.t

let parse = Stmt.parse

end

Loading