Update hw5 to a newer version.
Signed-off-by: jmug <u.g.a.mariano@gmail.com>
This commit is contained in:
parent
b24a264f7e
commit
9224001a22
262 changed files with 2575 additions and 1442 deletions
2
hw5/.ocamlformat
Normal file
2
hw5/.ocamlformat
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
profile = janestreet
|
||||
version = 0.26.1
|
||||
1
hw5/.ocamlinit
Normal file
1
hw5/.ocamlinit
Normal file
|
|
@ -0,0 +1 @@
|
|||
#use_output "dune top";;
|
||||
31
hw5/Makefile
31
hw5/Makefile
|
|
@ -1,26 +1,27 @@
|
|||
INCLUDES= util,x86,grading,ll
|
||||
LIBS = unix,str
|
||||
SUBMIT := frontend.ml typechecker.ml team.txt
|
||||
SUBMIT := $(shell cat submit_zip_contents.txt)
|
||||
HWNAME := hw5
|
||||
TIMESTAMP := $(shell /bin/date "+%Y-%m-%d-%H:%M:%S")
|
||||
ZIPNAME := $(HWNAME)-submit-$(TIMESTAMP).zip
|
||||
|
||||
HWNAME := hw05
|
||||
ZIPNAME := $(HWNAME)-submit.zip
|
||||
.PHONY: all oatc test clean zip
|
||||
|
||||
all: oatc
|
||||
|
||||
all: main.native
|
||||
oatc:
|
||||
dune build
|
||||
@cp bin/main.exe oatc
|
||||
|
||||
.PHONY: test
|
||||
test: main.native
|
||||
./main.native --test
|
||||
test: oatc
|
||||
./oatc --test
|
||||
|
||||
.PHONY: main.native
|
||||
main.native:
|
||||
ocamlbuild -pkg num -Is $(INCLUDES) -libs $(LIBS) main.native -use-menhir -yaccflag --explain
|
||||
utop:
|
||||
dune utop
|
||||
|
||||
zip: $(SUBMIT)
|
||||
zip '$(ZIPNAME)' $(SUBMIT)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
ocamlbuild -clean
|
||||
rm -rf output a.out
|
||||
dune clean
|
||||
rm -rf oatc ocamlbin bin/main.exe
|
||||
|
||||
#
|
||||
|
|
|
|||
69
hw5/README
69
hw5/README
|
|
@ -1,69 +0,0 @@
|
|||
Using main.native for testing:
|
||||
|
||||
* To run the automated test harness do:
|
||||
- on OS X: ./main.native --test
|
||||
- on Linux: ./main.native -linux --test
|
||||
|
||||
* To compile ll files using the 341 backend:
|
||||
./main.native path/to/foo.ll
|
||||
|
||||
- creates output/foo.s backend assembly code
|
||||
- creates output/foo.o assembled object file
|
||||
- creates a.out linked executable
|
||||
|
||||
NOTE: by default the .s and .o files are created in
|
||||
a directory called output, and the filenames are
|
||||
chosen so that multiple runs of the compiler will
|
||||
not overwrite previous outputs. foo.ll will be
|
||||
compiled first to foo.s then foo_1.s, foo_2.s, etc.
|
||||
|
||||
|
||||
* To compile ll files using the clang backend:
|
||||
./main.native --clang path/to/foo.ll
|
||||
|
||||
* Useful flags:
|
||||
|
||||
--print-ll
|
||||
echoes the ll program to the terminal
|
||||
|
||||
--print-x86
|
||||
echoes the resulting .s file to the terminal
|
||||
|
||||
--simulate-x86
|
||||
runs the resulting .s file through the reference
|
||||
x86 simulator and outputs the result to the console
|
||||
|
||||
--execute-x86
|
||||
runs the resulting a.out file natively
|
||||
(applies to either the 341 backend or clang-compiled code)
|
||||
|
||||
-v
|
||||
generates verbose output, showing which commands are used
|
||||
for linking, etc.
|
||||
|
||||
-op <dirname>
|
||||
change the output path [DEFAULT=output]
|
||||
|
||||
-o
|
||||
change the generated executable's name [DEFAULT=a.out]
|
||||
|
||||
-S
|
||||
stop after generating .s files
|
||||
|
||||
-c
|
||||
stop after generating .o files
|
||||
|
||||
-h or --help
|
||||
display the list of options
|
||||
|
||||
* Example uses:
|
||||
|
||||
Run the test case /programs/factrect.ll using the 341 backend:
|
||||
|
||||
|
||||
./main.native --execute-x86 programs/factrect.ll
|
||||
--------------------------------------------------------------- Executing: a.out
|
||||
* a.out returned 120
|
||||
|
||||
|
||||
Run the test
|
||||
73
hw5/README.md
Normal file
73
hw5/README.md
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
# HW5: Oat v.2 -- Typechecking Structs, Function Pointers, and Subtyping
|
||||
|
||||
Quick Start:
|
||||
|
||||
1. clone this repository using `git clone`
|
||||
2. open the folder in VSCode
|
||||
3. start an OCaml sandbox terminal
|
||||
4. run `make test` from the command line
|
||||
5. open `bin/frontend.ml`
|
||||
|
||||
See the general toolchain and project instructions on the course web site. The
|
||||
course web pages have a link to the html version of the homework instructions.
|
||||
|
||||
|
||||
Using ``oatc``
|
||||
--------------
|
||||
|
||||
``oatc`` acts like the clang compiler. Given several .oat, .ll, .c, and .o
|
||||
files, it will compile the .oat and .ll files to .s files (using the cs131
|
||||
frontend and backend) and then combine the results with the .c and .o files to
|
||||
produce an executable named a.out. You can also compile the .ll files using
|
||||
clang instead of the cs131 backend, which can be useful for testing
|
||||
purposes.
|
||||
|
||||
|
||||
* To run the automated test harness do:
|
||||
|
||||
./oatc --test
|
||||
|
||||
* To compile oat files using the 131 backend:
|
||||
|
||||
./oatc path/to/foo.oat
|
||||
|
||||
- creates output/foo.ll frontend ll code
|
||||
- creates output/foo.s backend assembly code
|
||||
- creates output/foo.o assembled object file
|
||||
- creates a.out linked executable
|
||||
|
||||
NOTE: by default the .s and .o files are created in
|
||||
a directory called output, and the filenames are
|
||||
chosen so that multiple runs of the compiler will
|
||||
not overwrite previous outputs. foo.ll will be
|
||||
compiled first to foo.s then foo_1.s, foo_2.s, etc.
|
||||
|
||||
* To compile oat files using the clang backend:
|
||||
|
||||
./oatc --clang path/to/foo.oat
|
||||
|
||||
* Useful flags:
|
||||
|
||||
| Flag | Description |
|
||||
|-------------------|---------------------------------------------------------------------------------------------------|
|
||||
| --print-oat | pretty prints the Oat abstract syntax to the terminal |
|
||||
| --print-ll | echoes the ll program to the terminal |
|
||||
| --print-x86 | echoes the resulting .s file to the terminal |
|
||||
| --interpret-ll | runs the ll file through the reference interpreter and outputs the results to the console |
|
||||
| --execute-x86 | runs the resulting a.out file natively (applies to either the 131 backend or clang-compiled code) |
|
||||
| --clang | compiles to assembly using clang, not the 131 backend |
|
||||
| -v | generates verbose output, showing which commands are used for linking, etc. |
|
||||
| -op ``<dirname>`` | change the output path [DEFAULT=output] |
|
||||
| -o | change the generated executable's name [DEFAULT=a.out] |
|
||||
| -S | stop after generating .s files |
|
||||
| -c | stop after generating .o files |
|
||||
| -h or --help | display the list of options |
|
||||
|
||||
|
||||
* Example uses:
|
||||
|
||||
Run the test case hw4programs/fact.oat using the 131 backend:
|
||||
|
||||
./oatc --execute-x86 hw4programs/fact.oat bin/runtime.c
|
||||
120--------------------------------------------------------------- Executing: a.out
|
||||
* a.out returned 0
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
module Range = Util.Range
|
||||
|
||||
type 'a node = { elt : 'a; loc : Range.t }
|
||||
|
||||
|
|
@ -52,7 +53,8 @@ type exp =
|
|||
| CStr of string
|
||||
| Id of id
|
||||
| CArr of ty * exp node list
|
||||
| NewArr of ty * exp node * id * exp node
|
||||
| NewArr of ty * exp node
|
||||
| NewArrInit of ty * exp node * id * exp node
|
||||
| Index of exp node * exp node
|
||||
| Length of exp node
|
||||
| CStruct of id * (id * exp node) list
|
||||
|
|
@ -112,10 +112,13 @@ and print_exp_aux level fmt e =
|
|||
| Id id -> print_id_aux fmt id
|
||||
| Index (e,i) -> print_exp_aux this_level fmt e; pps "["; print_exp_aux 0 fmt i; pps "]"
|
||||
| Call (e, es) -> print_exp_aux this_level fmt e; print_exps_aux "(" ")" fmt es
|
||||
| NewArr (ty, e1, u, e2) ->
|
||||
| NewArr(ty, e1) ->
|
||||
pps "new"; print_ty_aux fmt ty;
|
||||
pps "["; print_exp_aux this_level fmt e1; pps "]"
|
||||
| NewArrInit (ty, e1, u, e2) ->
|
||||
pps "new"; print_ty_aux fmt ty;
|
||||
pps "["; print_exp_aux this_level fmt e1;
|
||||
pps "{"; pps u; pps "->"; print_exp_aux this_level fmt e2
|
||||
pps "] {"; pps u; pps "->"; print_exp_aux this_level fmt e2; pps "}"
|
||||
| Bop (o,l,r) ->
|
||||
pp_open_box fmt 0;
|
||||
print_exp_aux this_level fmt l;
|
||||
|
|
@ -322,6 +325,8 @@ let string_of_exp (e:exp node) : string = string_of (print_exp_aux 0) e
|
|||
let print_ty (t:ty) : unit = print print_ty_aux t
|
||||
let string_of_ty (t:ty) : string = string_of print_ty_aux t
|
||||
|
||||
let string_of_ret_ty (r:ret_ty) : string = string_of print_ret_ty_aux r
|
||||
|
||||
(* AST to ML *)
|
||||
|
||||
let sp = Printf.sprintf
|
||||
|
|
@ -406,7 +411,9 @@ let rec ml_string_of_exp_aux (e: exp) : string =
|
|||
| Call (e, exps) -> sp "Call (%s, %s)"
|
||||
(ml_string_of_exp e)
|
||||
(ml_string_of_list ml_string_of_exp exps)
|
||||
| NewArr (t,e1,u,e2) -> sp "NewArr (%s,%s,%s,%s)"
|
||||
| NewArr (t,e1) -> sp "NewArr (%s,%s)"
|
||||
(ml_string_of_ty t) (ml_string_of_exp e1)
|
||||
| NewArrInit (t,e1,u,e2) -> sp "NewArrInit (%s,%s,%s,%s)"
|
||||
(ml_string_of_ty t) (ml_string_of_exp e1) (ml_string_of_id u) (ml_string_of_exp e2)
|
||||
| Proj(exp, id) -> sp "Proj (%s,%s)" (ml_string_of_exp exp) (ml_string_of_id id)
|
||||
| Bop (b, e1, e2) -> sp "Bop (%s,%s,%s)"
|
||||
|
|
@ -3,6 +3,8 @@
|
|||
open Ll
|
||||
open X86
|
||||
|
||||
module Platform = Util.Platform
|
||||
|
||||
(* Overview ----------------------------------------------------------------- *)
|
||||
|
||||
(* We suggest that you spend some time understinging this entire file and
|
||||
|
|
@ -1,4 +1,8 @@
|
|||
open Printf
|
||||
|
||||
module Platform = Util.Platform
|
||||
module Range = Util.Range
|
||||
|
||||
open Platform
|
||||
|
||||
(* configuration flags ------------------------------------------------------ *)
|
||||
|
|
@ -142,7 +146,7 @@ let process_files files =
|
|||
if (List.length files) > 0 then begin
|
||||
List.iter process_file files;
|
||||
( if !assemble && !link then
|
||||
Platform.link (List.rev !link_files@["runtime.c"]) !executable_filename );
|
||||
Platform.link (List.rev !link_files) !executable_filename );
|
||||
( if !assemble && !link && !execute_x86 then
|
||||
let ret = run_executable "" !executable_filename in
|
||||
print_banner @@ Printf.sprintf "Executing: %s" !executable_filename;
|
||||
29
hw5/bin/dune
Normal file
29
hw5/bin/dune
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
(library
|
||||
(name oat)
|
||||
(modules driver backend frontend lexer parser ast astlib typechecker tctxt)
|
||||
(libraries str num util x86 ll))
|
||||
|
||||
(ocamllex lexer)
|
||||
(menhir (modules parser))
|
||||
|
||||
(env
|
||||
(dev
|
||||
(flags
|
||||
(:standard -g -w "+a-4-7-9-26-27-29-30-32..42-44-45-48-50-60-66..70")
|
||||
)))
|
||||
|
||||
(executable
|
||||
(public_name main)
|
||||
(name main)
|
||||
(modules main)
|
||||
(promote (until-clean))
|
||||
(libraries
|
||||
; OCaml standard libraries
|
||||
; project libraries
|
||||
str
|
||||
num
|
||||
util
|
||||
x86
|
||||
ll
|
||||
studenttests
|
||||
gradedtests))
|
||||
|
|
@ -99,10 +99,10 @@ module TypeCtxt = struct
|
|||
| h :: t -> if h.fieldName = f then Some i else index_of f t (i + 1)
|
||||
|
||||
(* Return the index of a field in the struct. *)
|
||||
let index_of_field_opt st f (c : t) =
|
||||
let index_of_field_opt (st:Ast.id) (f:Ast.id) (c : t) : (int option) =
|
||||
index_of f (List.assoc st c) 0
|
||||
|
||||
let index_of_field st f c =
|
||||
let index_of_field (st:Ast.id) (f:Ast.id) (c:t) : int =
|
||||
match index_of_field_opt st f c with
|
||||
| None -> failwith "index_of_field: Not found"
|
||||
| Some x -> x
|
||||
|
|
@ -112,7 +112,7 @@ module TypeCtxt = struct
|
|||
let fields = lookup st c in
|
||||
match index_of f fields 0 with
|
||||
| None -> failwith "no such field"
|
||||
| Some x -> List.(nth fields x).ftyp, Int64.of_int x
|
||||
| Some x -> List.(nth fields x).ftyp, Int64.of_int x
|
||||
end
|
||||
|
||||
(* compiling OAT types ------------------------------------------------------ *)
|
||||
|
|
@ -166,7 +166,7 @@ let gensym : string -> string =
|
|||
let c = ref 0 in
|
||||
fun (s:string) -> incr c; Printf.sprintf "_%s%d" s (!c)
|
||||
|
||||
(* Amount of space an Oat type takes when stored in the satck, in bytes.
|
||||
(* Amount of space an Oat type takes when stored in the stack, in bytes.
|
||||
Note that since structured values are manipulated by reference, all
|
||||
Oat values take 8 bytes on the stack.
|
||||
*)
|
||||
|
|
@ -175,7 +175,7 @@ let size_oat_ty (t : Ast.ty) = 8L
|
|||
|
||||
|
||||
|
||||
(* Generate code to allocate an array of source type TRef (RArray t) of the
|
||||
(* Generate code to allocate a zero-initialized array of source type TRef (RArray t) of the
|
||||
given size. Note "size" is an operand whose value can be computed at
|
||||
runtime *)
|
||||
let oat_alloc_array ct (t:Ast.ty) (size:Ll.operand) : Ll.ty * operand * stream =
|
||||
|
|
@ -195,7 +195,7 @@ let oat_alloc_array ct (t:Ast.ty) (size:Ll.operand) : Ll.ty * operand * stream =
|
|||
|
||||
- make sure to calculate the correct amount of space to allocate!
|
||||
*)
|
||||
let oat_alloc_struct ct (id:Ast.id) : Ll.ty * operand * stream =
|
||||
let oat_alloc_struct (ct:TypeCtxt.t) (id:Ast.id) : Ll.ty * operand * stream =
|
||||
failwith "TODO: oat_alloc_struct"
|
||||
|
||||
|
||||
|
|
@ -243,6 +243,17 @@ let rec cmp_exp (tc : TypeCtxt.t) (c:Ctxt.t) (exp:Ast.exp node) : Ll.ty * Ll.ope
|
|||
>:: G(gid, (str_typ, GString s))
|
||||
>:: I(uid, Gep(Ptr str_typ, Gid gid, [Const 0L; Const 0L;]))
|
||||
|
||||
| Ast.Bop (Ast.Eq as bop, e1, e2)
|
||||
| Ast.Bop (Ast.Neq as bop, e1, e2) ->
|
||||
(* Polymorphic equality operations *)
|
||||
(* Allow any type for the first operand, and cast
|
||||
the second operand to the type of the first. *)
|
||||
let _, _, ret_ty = typ_of_binop bop in
|
||||
let ll_t, op1, code1 = cmp_exp tc c e1 in
|
||||
let op2, code2 = cmp_exp_as tc c e2 ll_t in
|
||||
let ans_id = gensym "bop" in
|
||||
cmp_ty tc ret_ty, Id ans_id, code1 >@ code2 >:: I(ans_id, cmp_binop ll_t bop op1 op2)
|
||||
|
||||
| Ast.Bop (bop, e1, e2) ->
|
||||
let t, _, ret_ty = typ_of_binop bop in
|
||||
let ll_t = cmp_ty tc t in
|
||||
|
|
@ -271,7 +282,7 @@ let rec cmp_exp (tc : TypeCtxt.t) (c:Ctxt.t) (exp:Ast.exp node) : Ll.ty * Ll.ope
|
|||
| _ -> failwith "broken invariant: identifier not a pointer"
|
||||
end
|
||||
|
||||
(* ARRAY TASK: complete this case to compilet the length(e) expression.
|
||||
(* ARRAY TASK: complete this case to compile the length(e) expression.
|
||||
The emitted code should yield the integer stored as part
|
||||
of the array struct representation.
|
||||
*)
|
||||
|
|
@ -295,12 +306,17 @@ let rec cmp_exp (tc : TypeCtxt.t) (c:Ctxt.t) (exp:Ast.exp node) : Ll.ty * Ll.ope
|
|||
let ind = gensym "ind" in
|
||||
s >@ elt_code >@ lift
|
||||
[ ind, Gep(arr_ty, arr_op, [Const 0L; Const 1L; i64_op_of_int i ])
|
||||
; "", Store(ll_elt_ty, elt_op, Id ind) ]
|
||||
; gensym "store", Store(ll_elt_ty, elt_op, Id ind) ]
|
||||
in
|
||||
let ind_code = List.(fold_left add_elt [] @@ mapi (fun i e -> i, e) cs) in
|
||||
arr_ty, arr_op, alloc_code >@ ind_code
|
||||
|
||||
(* ARRAY TASK: Modify the compilation of the NewArr construct to implement the
|
||||
| Ast.NewArr (elt_ty, e) ->
|
||||
let _, size_op, size_code = cmp_exp tc c e in
|
||||
let arr_ty, arr_op, alloc_code = oat_alloc_array tc elt_ty size_op in
|
||||
arr_ty, arr_op, size_code >@ alloc_code
|
||||
|
||||
(* ARRAY TASK: Modify the compilation of the NewArrInit construct to implement the
|
||||
initializer:
|
||||
- the initializer is a loop that uses id as the index
|
||||
- each iteration of the loop the code evaluates e2 and assigns it
|
||||
|
|
@ -310,7 +326,7 @@ let rec cmp_exp (tc : TypeCtxt.t) (c:Ctxt.t) (exp:Ast.exp node) : Ll.ty * Ll.ope
|
|||
you could write the loop using abstract syntax and then call cmp_stmt to
|
||||
compile that into LL code...
|
||||
*)
|
||||
| Ast.NewArr (elt_ty, e1, id, e2) ->
|
||||
| Ast.NewArrInit (elt_ty, e1, id, e2) ->
|
||||
let _, size_op, size_code = cmp_exp tc c e1 in
|
||||
let arr_ty, arr_op, alloc_code = oat_alloc_array tc elt_ty size_op in
|
||||
arr_ty, arr_op, size_code >@ alloc_code
|
||||
|
|
@ -333,7 +349,10 @@ let rec cmp_exp (tc : TypeCtxt.t) (c:Ctxt.t) (exp:Ast.exp node) : Ll.ty * Ll.ope
|
|||
and cmp_exp_lhs (tc : TypeCtxt.t) (c:Ctxt.t) (e:exp node) : Ll.ty * Ll.operand * stream =
|
||||
match e.elt with
|
||||
| Ast.Id x ->
|
||||
let t, op = Ctxt.lookup x c in
|
||||
let pt, op = Ctxt.lookup x c in
|
||||
let t = match pt with
|
||||
| Ptr t -> t
|
||||
| _ -> failwith "Unexpected variable type" in
|
||||
t, op, []
|
||||
|
||||
(* STRUCT TASK: Complete this code that emits LL code to compute the
|
||||
|
|
@ -359,7 +378,7 @@ and cmp_exp_lhs (tc : TypeCtxt.t) (c:Ctxt.t) (e:exp node) : Ll.ty * Ll.operand *
|
|||
let ans_ty = match arr_ty with
|
||||
| Ptr (Struct [_; Array (_,t)]) -> t
|
||||
| _ -> failwith "Index: indexed into non pointer" in
|
||||
let ptr_id, tmp_id = gensym "index_ptr", gensym "tmp" in
|
||||
let ptr_id, tmp_id, call_id = gensym "index_ptr", gensym "tmp", gensym "call" in
|
||||
ans_ty, (Id ptr_id),
|
||||
arr_code >@ ind_code >@ lift
|
||||
[ptr_id, Gep(arr_ty, arr_op, [i64_op_of_int 0; i64_op_of_int 1; ind_op]) ]
|
||||
|
|
@ -405,17 +424,17 @@ and cmp_stmt (tc : TypeCtxt.t) (c:Ctxt.t) (rt:Ll.ty) (stmt:Ast.stmt node) : Ctxt
|
|||
let c' = Ctxt.add c id (Ptr ll_ty, Id res_id) in
|
||||
c', init_code
|
||||
>:: E(res_id, Alloca ll_ty)
|
||||
>:: I("", Store (ll_ty, init_op, Id res_id))
|
||||
>:: I(gensym "store", Store (ll_ty, init_op, Id res_id))
|
||||
|
||||
| Ast.Assn (path ,e) ->
|
||||
let _, pop, path_code = cmp_exp_lhs tc c path in
|
||||
let ll_ty, eop, exp_code = cmp_exp tc c e in
|
||||
c, path_code >@ exp_code >:: I("", (Store (ll_ty, eop, pop)))
|
||||
let ll_ty, pop, path_code = cmp_exp_lhs tc c path in
|
||||
let eop, exp_code = cmp_exp_as tc c e ll_ty in
|
||||
c, path_code >@ exp_code >:: I(gensym "store", (Store (ll_ty, eop, pop)))
|
||||
|
||||
| Ast.If (guard, st1, st2) ->
|
||||
let guard_ty, guard_op, guard_code = cmp_exp tc c guard in
|
||||
let then_code = cmp_block tc c rt st1 in
|
||||
let else_code = cmp_block tc c rt st2 in
|
||||
let _, then_code = cmp_block tc c rt st1 in
|
||||
let _, else_code = cmp_block tc c rt st2 in
|
||||
let lt, le, lm = gensym "then", gensym "else", gensym "merge" in
|
||||
c, guard_code
|
||||
>:: T(Cbr (guard_op, lt, le))
|
||||
|
|
@ -428,7 +447,7 @@ and cmp_stmt (tc : TypeCtxt.t) (c:Ctxt.t) (rt:Ll.ty) (stmt:Ast.stmt node) : Ctxt
|
|||
- check whether the value computed by exp is null, if so jump to
|
||||
the 'null' block, otherwise take the 'notnull' block
|
||||
|
||||
- the identifier id is in scope in the 'nutnull' block and so
|
||||
- the identifier id is in scope in the 'notnull' block and so
|
||||
needs to be allocated (and added to the context)
|
||||
|
||||
- as in the if-the-else construct, you should jump to the common
|
||||
|
|
@ -440,7 +459,7 @@ and cmp_stmt (tc : TypeCtxt.t) (c:Ctxt.t) (rt:Ll.ty) (stmt:Ast.stmt node) : Ctxt
|
|||
| Ast.While (guard, body) ->
|
||||
let guard_ty, guard_op, guard_code = cmp_exp tc c guard in
|
||||
let lcond, lbody, lpost = gensym "cond", gensym "body", gensym "post" in
|
||||
let body_code = cmp_block tc c rt body in
|
||||
let _, body_code = cmp_block tc c rt body in
|
||||
c, []
|
||||
>:: T (Br lcond)
|
||||
>:: L lcond >@ guard_code >:: T (Cbr (guard_op, lbody, lpost))
|
||||
|
|
@ -448,12 +467,19 @@ and cmp_stmt (tc : TypeCtxt.t) (c:Ctxt.t) (rt:Ll.ty) (stmt:Ast.stmt node) : Ctxt
|
|||
>:: L lpost
|
||||
|
||||
| Ast.For (inits, guard, after, body) ->
|
||||
let guard = match guard with Some e -> e | None -> no_loc (CBool true) in
|
||||
let after = match after with Some s -> [s] | None -> [] in
|
||||
let body = body @ after in
|
||||
let ds = List.map (fun d -> no_loc (Decl d)) inits in
|
||||
let stream = cmp_block tc c rt (ds @ [no_loc @@ Ast.While (guard, body)]) in
|
||||
c, stream
|
||||
let ci, init = cmp_block tc c rt ds in
|
||||
let guard = match guard with Some e -> e | None -> no_loc (CBool true) in
|
||||
let guard_ty, guard_op, guard_code = cmp_exp tc ci guard in
|
||||
let after = match after with Some s -> [s] | None -> [] in
|
||||
let lcond, lbody, lpost = gensym "cond", gensym "body", gensym "post" in
|
||||
let _,body_code = cmp_block tc ci rt body in
|
||||
let _,after_code = cmp_block tc ci rt after in
|
||||
c, init
|
||||
>:: T (Br lcond)
|
||||
>:: L lcond >@ guard_code >:: T (Cbr (guard_op, lbody, lpost))
|
||||
>:: L lbody >@ body_code >@ after_code >:: T (Br lcond)
|
||||
>:: L lpost
|
||||
|
||||
| Ast.Ret None ->
|
||||
c, [T (Ret(Void, None))]
|
||||
|
|
@ -467,8 +493,8 @@ and cmp_stmt (tc : TypeCtxt.t) (c:Ctxt.t) (rt:Ll.ty) (stmt:Ast.stmt node) : Ctxt
|
|||
c, code
|
||||
|
||||
(* Compile a series of statements *)
|
||||
and cmp_block (tc : TypeCtxt.t) (c:Ctxt.t) (rt:Ll.ty) (stmts:Ast.block) : stream =
|
||||
snd @@ List.fold_left (fun (c, code) s ->
|
||||
and cmp_block (tc : TypeCtxt.t) (c:Ctxt.t) (rt:Ll.ty) (stmts:Ast.block) : Ctxt.t * stream =
|
||||
List.fold_left (fun (c, code) s ->
|
||||
let c, stmt_code = cmp_stmt tc c rt s in
|
||||
c, code >@ stmt_code
|
||||
) (c,[]) stmts
|
||||
|
|
@ -514,8 +540,8 @@ let cmp_global_ctxt (tc : TypeCtxt.t) (c:Ctxt.t) (p:Ast.prog) : Ctxt.t =
|
|||
| CNull r -> cmp_ty tc (TNullRef r)
|
||||
| CBool b -> I1
|
||||
| CInt i -> I64
|
||||
| CStr s -> Ptr (str_arr_ty s)
|
||||
| CArr (u, cs) -> Ptr (Struct [I64; Array(List.length cs, cmp_ty tc u)])
|
||||
| CStr s -> Ptr I8
|
||||
| CArr (u, cs) -> Ptr (Struct [I64; Array(0, cmp_ty tc u)])
|
||||
| x -> failwith ( "bad global initializer: " ^ (Astlib.string_of_exp (no_loc x)))
|
||||
in
|
||||
List.fold_left (fun c -> function
|
||||
|
|
@ -537,13 +563,13 @@ let cmp_fdecl (tc : TypeCtxt.t) (c:Ctxt.t) (f:Ast.fdecl node) : Ll.fdecl * (Ll.g
|
|||
let c = Ctxt.add c s_id (Ptr ll_ty, Ll.Id alloca_id)in
|
||||
c, []
|
||||
>:: E(alloca_id, Alloca ll_ty)
|
||||
>:: I("", Store(ll_ty, Id ll_id, Id alloca_id))
|
||||
>:: I(gensym "store", Store(ll_ty, Id ll_id, Id alloca_id))
|
||||
>@ code,
|
||||
(ll_ty, ll_id)::args
|
||||
in
|
||||
let c, args_code, args = List.fold_right add_arg args (c,[],[]) in
|
||||
let ll_rty = cmp_ret_ty tc frtyp in
|
||||
let block_code = cmp_block tc c ll_rty body in
|
||||
let _, block_code = cmp_block tc c ll_rty body in
|
||||
let argtys, f_param = List.split args in
|
||||
let f_ty = (argtys, ll_rty) in
|
||||
let return_code =
|
||||
|
|
@ -551,8 +577,7 @@ let cmp_fdecl (tc : TypeCtxt.t) (c:Ctxt.t) (f:Ast.fdecl node) : Ll.fdecl * (Ll.g
|
|||
match frtyp with
|
||||
| RetVoid -> None
|
||||
| RetVal TBool | RetVal TInt -> Some (Const 0L)
|
||||
| RetVal (TRef _) -> Some Null
|
||||
| RetVal (TNullRef _) -> Some Null
|
||||
| RetVal (TRef _ | TNullRef _) -> Some Null
|
||||
in
|
||||
[T (Ret (ll_rty, return_val))]
|
||||
in
|
||||
|
|
@ -574,7 +599,8 @@ let rec cmp_gexp c (tc : TypeCtxt.t) (e:Ast.exp node) : Ll.gdecl * (Ll.gid * Ll.
|
|||
| CStr s ->
|
||||
let gid = gensym "str" in
|
||||
let ll_ty = str_arr_ty s in
|
||||
(Ptr ll_ty, GGid gid), [gid, (ll_ty, GString s)]
|
||||
let cast = GBitcast (Ptr ll_ty, GGid gid, Ptr I8) in
|
||||
(Ptr I8, cast), [gid, (ll_ty, GString s)]
|
||||
|
||||
| CArr (u, cs) ->
|
||||
let elts, gs = List.fold_right
|
||||
|
|
@ -587,7 +613,9 @@ let rec cmp_gexp c (tc : TypeCtxt.t) (e:Ast.exp node) : Ll.gdecl * (Ll.gid * Ll.
|
|||
let gid = gensym "global_arr" in
|
||||
let arr_t = Struct [ I64; Array(len, ll_u) ] in
|
||||
let arr_i = GStruct [ I64, GInt (Int64.of_int len); Array(len, ll_u), GArray elts ] in
|
||||
(Ptr arr_t, GGid gid), (gid, (arr_t, arr_i))::gs
|
||||
let final_t = Struct [ I64; Array(0, ll_u) ] in
|
||||
let cast = GBitcast (Ptr arr_t, GGid gid, Ptr final_t) in
|
||||
(Ptr final_t, cast), (gid, (arr_t, arr_i))::gs
|
||||
|
||||
(* STRUCT TASK: Complete this code that generates the global initializers for a struct value. *)
|
||||
| CStruct (id, cs) ->
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
open Lexing
|
||||
open Parser
|
||||
|
||||
module Range = Util.Range
|
||||
open Range
|
||||
|
||||
exception Lexer_error of Range.t * string
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
open Ll
|
||||
open Arg
|
||||
open Assert
|
||||
open Driver
|
||||
open Util.Assert
|
||||
open Oat.Driver
|
||||
|
||||
exception Ran_tests
|
||||
let suite = ref (Studenttests.provided_tests @ Gradedtests.graded_tests)
|
||||
let suite = ref (Studenttests.student_local_tests @ Gradedtests.graded_tests)
|
||||
|
||||
let execute_tests () =
|
||||
Platform.configure_os ();
|
||||
|
|
@ -13,7 +13,7 @@ let execute_tests () =
|
|||
raise Ran_tests
|
||||
|
||||
let args =
|
||||
[ ("-linux", Set Platform.linux, "use linux-style name mangling [must precede --test on linux]")
|
||||
[ ("-linux", Set Platform.linux, "use linux-style name mangling [must preceed --test on linux]")
|
||||
; ("--test", Unit execute_tests, "run the test suite, ignoring other files inputs")
|
||||
; ("-op", Set_string Platform.output_path, "set the path to the output files directory [default='output']")
|
||||
; ("-o", Set_string executable_filename, "set the name of the resulting executable [default='a.out']")
|
||||
|
|
@ -21,10 +21,11 @@ let args =
|
|||
; ("-c", Clear link, "stop after generating .o files; do not generate executables")
|
||||
; ("--print-ll", Set print_ll_flag, "prints the program's LL code (after lowering to clang code if --clang-malloc is set)")
|
||||
; ("--print-x86", Set print_x86_flag, "prints the program's assembly code")
|
||||
; ("--clang", Set clang, "compiles to assembly using clang, not the 341 backend (implies --clang-malloc)")
|
||||
; ("--print-regs", Set print_regs_flag, "prints the register usage statistics for x86 code")
|
||||
; ("--clang", Set clang, "compiles to assembly using clang, not the 131 backend (implies --clang-malloc)")
|
||||
; ("--execute-x86", Set execute_x86, "run the resulting executable file")
|
||||
; ("-v", Set Platform.verbose, "enables more verbose compilation output")
|
||||
]
|
||||
]
|
||||
|
||||
let files = ref []
|
||||
|
||||
|
|
@ -33,7 +34,7 @@ let _ =
|
|||
Platform.create_output_dir ();
|
||||
try
|
||||
Arg.parse args (fun filename -> files := filename :: !files)
|
||||
"Compiler Design main test harness\n\
|
||||
"cs131 main test harness\n\
|
||||
USAGE: ./main.native [options] <files>\n\
|
||||
see README for details about using the compiler";
|
||||
Platform.configure_os ();
|
||||
|
|
@ -188,12 +188,14 @@ exp:
|
|||
| i=INT { loc $startpos $endpos @@ CInt i }
|
||||
| s=STRING { loc $startpos $endpos @@ CStr s }
|
||||
| NEW t=ty LBRACKET RBRACKET LBRACE cs=separated_list(COMMA, exp) RBRACE
|
||||
{ loc $startpos $endpos @@ CArr (t, cs) }
|
||||
{ loc $startpos $endpos @@ CArr (t, cs) }
|
||||
| NEW t=ty LBRACKET e1=exp RBRACKET
|
||||
{ loc $startpos $endpos @@ NewArr(t, e1) }
|
||||
| NEW t=UIDENT LBRACE cs=separated_list(SEMI, field) RBRACE
|
||||
{ loc $startpos $endpos @@ CStruct(t, cs) }
|
||||
| e=exp DOT id=IDENT { loc $startpos $endpos @@ Proj(e, id) }
|
||||
| NEW t=ty LBRACKET e1=exp RBRACKET LBRACE u=IDENT ARROW e2=exp RBRACE
|
||||
{ loc $startpos $endpos @@ NewArr(t, e1, u, e2) }
|
||||
{ loc $startpos $endpos @@ NewArrInit(t, e1, u, e2) }
|
||||
| id=IDENT { loc $startpos $endpos @@ Id id }
|
||||
| e=exp LBRACKET i=exp RBRACKET
|
||||
{ loc $startpos $endpos @@ Index (e, i) }
|
||||
|
|
@ -12,7 +12,7 @@ int64_t* oat_malloc(int64_t size) {
|
|||
|
||||
int64_t* oat_alloc_array (int64_t size) {
|
||||
assert (size >= 0);
|
||||
int64_t *arr = (int64_t*)malloc(sizeof(int64_t) * (size+1));
|
||||
int64_t *arr = (int64_t*)calloc(size+1, sizeof(int64_t));
|
||||
arr[0] = size;
|
||||
return arr;
|
||||
}
|
||||
|
|
@ -117,7 +117,7 @@ void print_bool (int64_t i) {
|
|||
}
|
||||
}
|
||||
|
||||
extern int64_t program(int64_t argc, int64_t* oargv);
|
||||
extern int64_t program(int64_t oargc, int64_t* oargv);
|
||||
|
||||
/*
|
||||
* Convert the argv array into an Oat array of
|
||||
|
|
@ -7,7 +7,7 @@ open Tctxt
|
|||
|
||||
exception TypeError of string
|
||||
|
||||
let type_error (l : 'a node) err =
|
||||
let type_error (l : 'a node) (err : string) =
|
||||
let (_, (s, e), _) = l.loc in
|
||||
raise (TypeError (Printf.sprintf "[%d, %d] %s" s e err))
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ and subtype_ref (c : Tctxt.t) (t1 : Ast.rty) (t2 : Ast.rty) : bool =
|
|||
according to the rules
|
||||
|
||||
- the function should fail using the "type_error" helper function if the
|
||||
type is not well-formed
|
||||
type is not well formed
|
||||
|
||||
- l is just an ast node that provides source location information for
|
||||
generating error messages (it's only needed for the type_error generation)
|
||||
|
|
@ -72,10 +72,17 @@ and subtype_ref (c : Tctxt.t) (t1 : Ast.rty) (t2 : Ast.rty) : bool =
|
|||
let rec typecheck_ty (l : 'a Ast.node) (tc : Tctxt.t) (t : Ast.ty) : unit =
|
||||
failwith "todo: implement typecheck_ty"
|
||||
|
||||
|
||||
(* A helper function to determine whether a type allows the null value *)
|
||||
let is_nullable_ty (t : Ast.ty) : bool =
|
||||
match t with
|
||||
| TNullRef _ -> true
|
||||
| _ -> false
|
||||
|
||||
(* typechecking expressions ------------------------------------------------- *)
|
||||
(* Typechecks an expression in the typing context c, returns the type of the
|
||||
expression. This function should implement the inference rules given in the
|
||||
oad.pdf specification. There, they are written:
|
||||
oat.pdf specification. There, they are written:
|
||||
|
||||
H; G; L |- exp : t
|
||||
|
||||
|
|
@ -103,7 +110,7 @@ let rec typecheck_exp (c : Tctxt.t) (e : Ast.exp node) : Ast.ty =
|
|||
(* statements --------------------------------------------------------------- *)
|
||||
|
||||
(* Typecheck a statement
|
||||
This function should implement the statement typechecking rules from oat.pdf.
|
||||
This function should implement the statment typechecking rules from oat.pdf.
|
||||
|
||||
Inputs:
|
||||
- tc: the type context
|
||||
|
|
@ -112,15 +119,19 @@ let rec typecheck_exp (c : Tctxt.t) (e : Ast.exp node) : Ast.ty =
|
|||
|
||||
Returns:
|
||||
- the new type context (which includes newly declared variables in scope
|
||||
after this statement
|
||||
after this statement)
|
||||
|
||||
- A boolean indicating the return behavior of a statement:
|
||||
false: might not return
|
||||
true: definitely returns
|
||||
|
||||
in the branching statements, both branches must definitely return
|
||||
in the branching statements, the return behavior of the branching
|
||||
statement is the conjunction of the return behavior of the two
|
||||
branches: both both branches must definitely return in order for
|
||||
the whole statement to definitely return.
|
||||
|
||||
Intuitively: if one of the two branches of a conditional does not
|
||||
contain a return statement, then the entier conditional statement might
|
||||
contain a return statement, then the entire conditional statement might
|
||||
not return.
|
||||
|
||||
looping constructs never definitely return
|
||||
|
|
@ -143,18 +154,19 @@ let rec typecheck_stmt (tc : Tctxt.t) (s:Ast.stmt node) (to_ret:ret_ty) : Tctxt.
|
|||
*)
|
||||
|
||||
(* Helper function to look for duplicate field names *)
|
||||
let rec check_dups fs =
|
||||
let rec check_dups (fs : field list) =
|
||||
match fs with
|
||||
| [] -> false
|
||||
| h :: t -> (List.exists (fun x -> x.fieldName = h.fieldName) t) || check_dups t
|
||||
|
||||
let typecheck_tdecl (tc : Tctxt.t) id fs (l : 'a Ast.node) : unit =
|
||||
let typecheck_tdecl (tc : Tctxt.t) (id : id) (fs : field list) (l : 'a Ast.node) : unit =
|
||||
if check_dups fs
|
||||
then type_error l ("Repeated fields in " ^ id)
|
||||
else List.iter (fun f -> typecheck_ty l tc f.ftyp) fs
|
||||
|
||||
(* function declarations ---------------------------------------------------- *)
|
||||
(* typecheck a function declaration
|
||||
- ensures formal parameters are distinct
|
||||
- extends the local context with the types of the formal parameters to the
|
||||
function
|
||||
- typechecks the body of the function (passing in the expected return type
|
||||
|
|
@ -188,7 +200,8 @@ let typecheck_fdecl (tc : Tctxt.t) (f : Ast.fdecl) (l : 'a Ast.node) : unit =
|
|||
|
||||
|
||||
NOTE: global initializers may mention function identifiers as
|
||||
constants, but can't mention other global values *)
|
||||
constants, but can mention only other global values that were declared earlier
|
||||
*)
|
||||
|
||||
let create_struct_ctxt (p:Ast.prog) : Tctxt.t =
|
||||
failwith "todo: create_struct_ctxt"
|
||||
3
hw5/dune-project
Normal file
3
hw5/dune-project
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
(lang dune 2.9)
|
||||
(name hw5)
|
||||
(using menhir 2.1)
|
||||
|
|
@ -1,490 +0,0 @@
|
|||
open Assert
|
||||
open X86
|
||||
open Driver
|
||||
open Ll
|
||||
open Backend
|
||||
|
||||
(* Do NOT modify this file -- we will overwrite it with our *)
|
||||
(* own version when we test your project. *)
|
||||
|
||||
(* These tests will be used to grade your assignment *)
|
||||
|
||||
let fdecl_of_path path =
|
||||
Platform.verb @@ Printf.sprintf "* processing file: %s\n" path;
|
||||
let ll_ast = parse_ll_file path in
|
||||
match ll_ast.Ll.fdecls with
|
||||
| [_, fdecl] -> fdecl
|
||||
| _ -> failwith "test expected one fdecl"
|
||||
|
||||
|
||||
let exec_e2e_ast ll_ast args extra_files =
|
||||
let output_path = !Platform.output_path in
|
||||
let dot_s_file = Platform.gen_name output_path "test" ".s" in
|
||||
let exec_file = Platform.gen_name output_path "exec" "" in
|
||||
let asm_ast = Backend.compile_prog ll_ast in
|
||||
let asm_str = X86.string_of_prog asm_ast in
|
||||
let _ = Driver.write_file dot_s_file asm_str in
|
||||
let _ = Platform.link (dot_s_file::extra_files) exec_file in
|
||||
let result = Driver.run_executable args exec_file in
|
||||
let _ = Platform.sh (Printf.sprintf "rm -f %s %s" dot_s_file exec_file) Platform.ignore_error in
|
||||
let _ = Platform.verb @@ Printf.sprintf "** Executable exited with: %d\n" result in
|
||||
Int64.of_int result
|
||||
|
||||
|
||||
let exec_e2e_file path args =
|
||||
let ast = Driver.parse_ll_file path in
|
||||
exec_e2e_ast ast args []
|
||||
|
||||
let io_test path args =
|
||||
let ll_ast = Driver.parse_ll_file path in
|
||||
let output_path = !Platform.output_path in
|
||||
let dot_s_file = Platform.gen_name output_path "test" ".s" in
|
||||
let exec_file = Platform.gen_name output_path "exec" "" in
|
||||
let tmp_file = Platform.gen_name output_path "tmp" ".txt" in
|
||||
let asm_ast = Backend.compile_prog ll_ast in
|
||||
let asm_str = X86.string_of_prog asm_ast in
|
||||
let _ = Driver.write_file dot_s_file asm_str in
|
||||
let _ = Platform.link (dot_s_file::["cinterop.c"]) exec_file in
|
||||
let args = String.concat " " args in
|
||||
let result = Driver.run_program args exec_file tmp_file in
|
||||
let _ = Platform.sh (Printf.sprintf "rm -f %s %s %s" dot_s_file exec_file tmp_file) Platform.ignore_error in
|
||||
let _ = Platform.verb @@ Printf.sprintf "** Executable output:\n%s\n" result in
|
||||
result
|
||||
|
||||
let c_link_test c_files path args =
|
||||
let ll_ast = Driver.parse_ll_file path in
|
||||
let output_path = !Platform.output_path in
|
||||
let dot_s_file = Platform.gen_name output_path "test" ".s" in
|
||||
let exec_file = Platform.gen_name output_path "exec" "" in
|
||||
let asm_ast = Backend.compile_prog ll_ast in
|
||||
let asm_str = X86.string_of_prog asm_ast in
|
||||
let _ = Driver.write_file dot_s_file asm_str in
|
||||
let _ = Platform.link (dot_s_file::c_files) exec_file in
|
||||
let args = String.concat " " args in
|
||||
let result = Driver.run_executable args exec_file in
|
||||
let _ = Platform.sh (Printf.sprintf "rm -f %s %s" dot_s_file exec_file) Platform.ignore_error in
|
||||
Int64.of_int result
|
||||
|
||||
let oat_file_test path args =
|
||||
let () = Platform.verb @@ Printf.sprintf "** Processing: %s\n" path in
|
||||
|
||||
let output_path = !Platform.output_path in
|
||||
let dot_ll_file = Platform.gen_name output_path "test" ".ll" in
|
||||
let exec_file = Platform.gen_name output_path "exec" "" in
|
||||
let tmp_file = Platform.gen_name output_path "tmp" ".txt" in
|
||||
|
||||
let oat_ast = parse_oat_file path in
|
||||
Typechecker.typecheck_program oat_ast;
|
||||
let ll_ast = Frontend.cmp_prog oat_ast in
|
||||
let ll_str = Driver.string_of_ll_ast path ll_ast in
|
||||
let () = write_file dot_ll_file ll_str in
|
||||
let () = Platform.link (dot_ll_file::["runtime.c"]) exec_file in
|
||||
|
||||
let result = Driver.run_program args exec_file tmp_file in
|
||||
let () = Platform.sh (Printf.sprintf "rm -f %s %s %s" dot_ll_file exec_file tmp_file) Platform.ignore_error in
|
||||
let () = Platform.verb @@ Printf.sprintf "** Executable output:\n%s\n" result in
|
||||
result
|
||||
|
||||
let oat_tc_ok_file_test path =
|
||||
let _ = Platform.verb @@ Printf.sprintf "** OAT Typechecker OK Processing: %s\n" path in
|
||||
let oat_ast = parse_oat_file path in
|
||||
let _= Typechecker.typecheck_program oat_ast in
|
||||
()
|
||||
|
||||
let oat_tc_err_file_test path err =
|
||||
let _ = Platform.verb @@ Printf.sprintf "** OAT Typechecker Error Processing: %s\n" path in
|
||||
let oat_ast = parse_oat_file path in
|
||||
try
|
||||
let _ = Typechecker.typecheck_program oat_ast in
|
||||
failwith @@ Printf.sprintf "Expected type error: %s" err
|
||||
with
|
||||
| Typechecker.TypeError s ->
|
||||
if s = err then () else
|
||||
failwith @@ Printf.sprintf "Expected type error: %s but got %s" err s
|
||||
|
||||
let executed tests =
|
||||
List.map (fun (fn, ans) ->
|
||||
fn, assert_eqf (fun () -> exec_e2e_file fn "") ans)
|
||||
tests
|
||||
|
||||
let executed_oat_file tests =
|
||||
List.map (fun (path, args, ans) ->
|
||||
(path ^ " args: " ^ args), assert_eqf (fun () -> oat_file_test path args) ans)
|
||||
tests
|
||||
|
||||
let executed_tc_ok_file tests =
|
||||
List.map (fun path ->
|
||||
("typechecking: " ^ path, fun () -> oat_tc_ok_file_test path)) tests
|
||||
|
||||
let executed_tc_err_file tests =
|
||||
List.map (fun (path, err) ->
|
||||
("typechecking: " ^ path, fun () -> oat_tc_err_file_test path err)) tests
|
||||
|
||||
|
||||
|
||||
let executed_io tests =
|
||||
List.map (fun (fn, args, ans) ->
|
||||
(fn ^ ":" ^ (String.concat " " args)), assert_eqf (fun () -> io_test fn args) ans)
|
||||
tests
|
||||
|
||||
let executed_c_link tests =
|
||||
List.map (fun (c_file, fn, args, ans) ->
|
||||
(fn ^ ":" ^ (String.concat " " args)), assert_eqf (fun () -> c_link_test c_file fn args) ans)
|
||||
tests
|
||||
|
||||
let typecheck path () =
|
||||
let () = Platform.verb @@ Printf.sprintf "** Processing: %s\n" path in
|
||||
let oat_ast = parse_oat_file path in
|
||||
Typechecker.typecheck_program oat_ast
|
||||
|
||||
let typecheck_error (a : assertion) () =
|
||||
try a (); failwith "Should have a type error" with Typechecker.TypeError s -> ()
|
||||
|
||||
let typecheck_correct (a : assertion) () =
|
||||
try a () with Typechecker.TypeError s -> failwith "Should not have had a type error"
|
||||
|
||||
|
||||
let typecheck_file_error tests =
|
||||
List.map (fun p -> p, typecheck_error (typecheck p)) tests
|
||||
|
||||
let typecheck_file_correct tests =
|
||||
List.map (fun p -> p, typecheck_correct (typecheck p)) tests
|
||||
|
||||
let unit_tests = [
|
||||
"subtype_stringQ_stringQ",
|
||||
(fun () ->
|
||||
if Typechecker.subtype Tctxt.empty (TNullRef RString) (TNullRef RString) then ()
|
||||
else failwith "should not fail")
|
||||
; ("no_subtype_stringQ_stringQ",
|
||||
(fun () ->
|
||||
if Typechecker.subtype Tctxt.empty (TNullRef RString) (TRef RString) then
|
||||
failwith "should not succeed" else ())
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
let hw4_easiest_tests = [
|
||||
("oatprograms/easyrun1.oat", "", "17");
|
||||
("oatprograms/easyrun2.oat", "", "35");
|
||||
("oatprograms/easyrun3.oat", "", "73");
|
||||
("oatprograms/easyrun4.oat", "", "6");
|
||||
("oatprograms/easyrun5.oat", "", "212");
|
||||
("oatprograms/easyrun6.oat", "", "9");
|
||||
("oatprograms/easyrun7.oat", "", "23");
|
||||
("oatprograms/easyrun8.oat", "", "96");
|
||||
("oatprograms/easyrun9.oat", "", "236");
|
||||
]
|
||||
|
||||
let hw4_globals_tests = [
|
||||
("oatprograms/globals1.oat", "", "42");
|
||||
("oatprograms/globals2.oat", "", "17");
|
||||
("oatprograms/globals3.oat", "", "17");
|
||||
("oatprograms/globals4.oat", "", "5");
|
||||
("oatprograms/globals5.oat", "", "17");
|
||||
("oatprograms/globals6.oat", "", "15");
|
||||
|
||||
]
|
||||
|
||||
let hw4_path_tests = [
|
||||
("oatprograms/path1.oat", "", "17");
|
||||
("oatprograms/path2.oat", "", "35");
|
||||
("oatprograms/path3.oat", "", "3");
|
||||
("oatprograms/arrayargs1.oat", "", "17");
|
||||
("oatprograms/arrayargs2.oat", "", "17");
|
||||
("oatprograms/arrayargs3.oat", "", "34");
|
||||
]
|
||||
|
||||
let hw4_easy_tests = [
|
||||
("oatprograms/run26.oat", "", "0");
|
||||
("oatprograms/run27.oat", "", "99");
|
||||
("oatprograms/run28.oat", "", "18");
|
||||
("oatprograms/run29.oat", "", "1");
|
||||
("oatprograms/run30.oat", "", "9");
|
||||
("oatprograms/run31.oat", "", "9");
|
||||
("oatprograms/run13.oat", "", "1");
|
||||
("oatprograms/run32.oat", "", "33");
|
||||
("oatprograms/run21.oat", "", "99");
|
||||
("oatprograms/run33.oat", "", "1");
|
||||
("oatprograms/run34.oat", "", "66");
|
||||
("oatprograms/run38.oat", "", "31");
|
||||
("oatprograms/run39.oat", "a", "2");
|
||||
("oatprograms/run40.oat", "", "8");
|
||||
("oatprograms/run41.oat", "", "3");
|
||||
("oatprograms/run42.oat", "", "2");
|
||||
("oatprograms/run49.oat", "", "abc0");
|
||||
("oatprograms/run50.oat", "", "abcde0");
|
||||
("oatprograms/run60.oat", "", "85");
|
||||
("oatprograms/run61.oat", "", "3410");
|
||||
]
|
||||
|
||||
let hw4_medium_tests = [
|
||||
("oatprograms/fact.oat", "", "1200");
|
||||
("oatprograms/run1.oat", "", "153");
|
||||
("oatprograms/run2.oat", "", "6");
|
||||
("oatprograms/run8.oat", "", "2");
|
||||
("oatprograms/run9.oat", "", "4");
|
||||
("oatprograms/run10.oat", "", "5");
|
||||
("oatprograms/run11.oat", "", "7");
|
||||
("oatprograms/run14.oat", "", "16");
|
||||
("oatprograms/run15.oat", "", "19");
|
||||
("oatprograms/run16.oat", "", "13");
|
||||
("oatprograms/run22.oat", "", "abc0");
|
||||
("oatprograms/run23.oat", "", "1230");
|
||||
("oatprograms/run25.oat", "", "nnn0");
|
||||
("oatprograms/run46.oat", "", "420");
|
||||
("oatprograms/run47.oat", "", "3");
|
||||
("oatprograms/run48.oat", "", "11");
|
||||
("oatprograms/lib4.oat", "", "53220");
|
||||
("oatprograms/lib5.oat", "", "20");
|
||||
("oatprograms/lib6.oat", "", "56553");
|
||||
("oatprograms/lib7.oat", "", "53");
|
||||
("oatprograms/lib8.oat", "", "Hello world!0");
|
||||
("oatprograms/lib9.oat", "a b c d", "abcd5");
|
||||
("oatprograms/lib11.oat", "", "45");
|
||||
("oatprograms/lib14.oat", "", "~}|{zyxwvu0");
|
||||
("oatprograms/lib15.oat", "123456789", "456780");
|
||||
]
|
||||
|
||||
let hw4_hard_tests = [
|
||||
("oatprograms/fac.oat", "", "120");
|
||||
("oatprograms/qsort.oat", "", "kpyf{shomfhkmopsy{255");
|
||||
("oatprograms/bsort.oat", "", "y}xotnuw notuwxy}255");
|
||||
("oatprograms/msort.oat", "", "~}|{zyxwvu uvwxyz{|}~ 0");
|
||||
("oatprograms/msort2.oat", "", "~}|{zyxwvu uvwxyz{|}~ 0");
|
||||
("oatprograms/selectionsort.oat", "", "01253065992000");
|
||||
("oatprograms/matrixmult.oat", "", "19 16 13 23 \t5 6 7 6 \t19 16 13 23 \t5 6 7 6 \t0");
|
||||
]
|
||||
|
||||
let hw4_old_student_tests = [
|
||||
("oatprograms/binary_search.oat", "", "Correct!0")
|
||||
; ("oatprograms/xor_shift.oat", "", "838867572\n22817190600")
|
||||
; ("oatprograms/sieve.oat", "", "25")
|
||||
; ("oatprograms/count_sort.oat", "", "AFHZAAEYC\nAAACEFHYZ0")
|
||||
; ("oatprograms/determinant_size2.oat", "", "94")
|
||||
; ("oatprograms/fibo.oat", "", "0")
|
||||
; ("oatprograms/bubble_sort.oat", "", "1")
|
||||
; ("oatprograms/heap.oat", "", "1")
|
||||
; ("oatprograms/binary_gcd.oat", "", "3")
|
||||
; ("oatprograms/lfsr.oat", "", "TFTF FFTT0")
|
||||
; ("oatprograms/gnomesort.oat", "", "01253065992000")
|
||||
; ("oatprograms/josh_joyce_test.oat", "", "0")
|
||||
; ("oatprograms/conquest.oat", "", "My name is Jeff...\nCharizard is the BEST Pokemon ever!!!11")
|
||||
; ("oatprograms/gcd.oat", "", "16")
|
||||
; ("oatprograms/lcs.oat", "", "OAT0")
|
||||
; ("oatprograms/insertion_sort.oat", "", "42")
|
||||
; ("oatprograms/maxsubsequence.oat", "", "107")
|
||||
]
|
||||
|
||||
let hw4_type_error_tests = [
|
||||
"oatprograms/run3.oat"
|
||||
; "oatprograms/run5.oat"
|
||||
; "oatprograms/run35.oat"
|
||||
; "oatprograms/run43.oat"
|
||||
; "oatprograms/run44.oat"
|
||||
; "oatprograms/run45.oat"
|
||||
]
|
||||
|
||||
|
||||
|
||||
let struct_tests = [
|
||||
("hw5programs/compile_assign_struct.oat", "", "16");
|
||||
("hw5programs/compile_basic_struct.oat", "", "7");
|
||||
("hw5programs/compile_global_struct.oat", "", "254");
|
||||
("hw5programs/compile_nested_struct.oat", "", "10");
|
||||
("hw5programs/compile_return_struct.oat", "", "0");
|
||||
("hw5programs/compile_struct_array.oat", "", "15");
|
||||
("hw5programs/compile_struct_fptr.oat", "", "7");
|
||||
("hw5programs/compile_various_fields.oat", "", "hello253");
|
||||
]
|
||||
|
||||
let fptr_tests = [
|
||||
("hw5programs/compile_array_fptr.oat", "", "2");
|
||||
("hw5programs/compile_func_argument.oat", "", "4");
|
||||
("hw5programs/compile_global_fptr.oat", "", "7");
|
||||
("hw5programs/compile_global_fptr_unordered.oat", "", "2");
|
||||
("hw5programs/compile_scall_fptr.oat", "", "4");
|
||||
("hw5programs/compile_var_fptr.oat", "", "1");
|
||||
("hw5programs/compile_local_fptr.oat", "", "5");
|
||||
("hw5programs/compile_function_shadow.oat", "", "12");
|
||||
("hw5programs/compile_global_struct_fptr.oat", "", "20");
|
||||
("hw5programs/compile_builtin_argument.oat", "", "abab0");
|
||||
]
|
||||
|
||||
let typecheck_subtyping_tests =
|
||||
[ "hw5programs/tc_subtyping1.oat"
|
||||
; "hw5programs/tc_subtyping2.oat"
|
||||
; "hw5programs/tc_subtyping3.oat"
|
||||
; "hw5programs/tc_subtyping4.oat"
|
||||
; "hw5programs/tc_subtyping5.oat"
|
||||
; "hw5programs/tc_subtyping6.oat"
|
||||
; "hw5programs/tc_subtyping7.oat"
|
||||
; "hw5programs/tc_subtyping8.oat"
|
||||
; "hw5programs/tc_subtyping9.oat"
|
||||
]
|
||||
|
||||
let typecheck_subtyping_error_tests =
|
||||
[ "hw5programs/tc_subtyping_err1.oat"
|
||||
; "hw5programs/tc_subtyping_err2.oat"
|
||||
; "hw5programs/tc_subtyping_err3.oat"
|
||||
; "hw5programs/tc_subtyping_err4.oat"
|
||||
; "hw5programs/tc_subtyping_err5.oat"
|
||||
; "hw5programs/tc_subtyping_err6.oat"
|
||||
; "hw5programs/tc_subtyping_err7.oat"
|
||||
; "hw5programs/tc_subtyping_err8.oat"
|
||||
]
|
||||
|
||||
|
||||
let typecheck_statement_error_tests =
|
||||
[ "hw5programs/tc_error_early_return.oat";
|
||||
"hw5programs/tc_error_early_return_void.oat";
|
||||
"hw5programs/tc_error_return_wrong.oat";
|
||||
"hw5programs/tc_error_while_nonbool.oat";
|
||||
"hw5programs/tc_error_while.oat";
|
||||
"hw5programs/tc_error_if_nonbool.oat";
|
||||
"hw5programs/tc_error_if.oat";
|
||||
"hw5programs/tc_error_for.oat";
|
||||
"hw5programs/tc_error_void.oat";
|
||||
"hw5programs/tc_error_assign_void.oat";
|
||||
"hw5programs/tc_error_scall_nonvoid.oat";
|
||||
]
|
||||
|
||||
let typecheck_correct_statement_tests =
|
||||
[ "hw5programs/tc_correct_while.oat";
|
||||
"hw5programs/tc_correct_for.oat";
|
||||
"hw5programs/tc_correct_if.oat";
|
||||
"hw5programs/tc_correct_void.oat"
|
||||
]
|
||||
|
||||
let typecheck_error_expression_tests =
|
||||
[ "hw5programs/tc_error_binop1.oat";
|
||||
"hw5programs/tc_error_binop2.oat";
|
||||
"hw5programs/tc_error_binop3.oat";
|
||||
"hw5programs/tc_error_call1.oat";
|
||||
"hw5programs/tc_error_call2.oat";
|
||||
"hw5programs/tc_error_unop1.oat";
|
||||
"hw5programs/tc_error_array1.oat";
|
||||
"hw5programs/tc_error_array2.oat";
|
||||
"hw5programs/tc_error_null.oat";
|
||||
]
|
||||
|
||||
let typecheck_error_struct_tests =
|
||||
[ "hw5programs/tc_error_struct_proj.oat";
|
||||
"hw5programs/tc_error_struct1.oat";
|
||||
"hw5programs/tc_error_struct2.oat";
|
||||
"hw5programs/tc_error_struct3.oat";
|
||||
"hw5programs/tc_error_struct4.oat";
|
||||
"hw5programs/tc_error_struct_dup.oat";
|
||||
"hw5programs/tc_error_struct.oat";
|
||||
"hw5programs/tc_error_dupstruct.oat";
|
||||
"hw5programs/tc_error_struct_unbound.oat";
|
||||
]
|
||||
|
||||
let typecheck_error_global_tests =
|
||||
[ "hw5programs/tc_error_global_dup.oat";
|
||||
"hw5programs/tc_error_global.oat";
|
||||
"hw5programs/tc_error_func_redeclaration.oat";
|
||||
"hw5programs/tc_error_func_assign.oat";
|
||||
"hw5programs/tc_error_overwrite.oat";
|
||||
"hw5programs/tc_error_global_fptr_scope.oat";
|
||||
"hw5programs/tc_error_function_no_shadow.oat";
|
||||
"hw5programs/tc_correct_null.oat";
|
||||
]
|
||||
|
||||
let typecheck_correct_other_tests =
|
||||
[ "hw5programs/tc_correct_array.oat";
|
||||
"hw5programs/tc_correct_call.oat";
|
||||
"hw5programs/tc_correct_fptr.oat";
|
||||
"hw5programs/tc_correct_global.oat";
|
||||
"hw5programs/tc_correct_struct.oat";
|
||||
"hw5programs/tc_correct_struct_fptr.oat";
|
||||
"hw5programs/tc_correct_void.oat";
|
||||
"hw5programs/tc_correct_local_redeclaration.oat";
|
||||
"hw5programs/tc_correct_fptr_array.oat";
|
||||
]
|
||||
|
||||
let typecheck_error_null_not_null_tests =
|
||||
hw4_type_error_tests
|
||||
|
||||
|
||||
let fptr_tests = [
|
||||
("hw5programs/compile_array_fptr.oat", "", "2");
|
||||
("hw5programs/compile_func_argument.oat", "", "4");
|
||||
("hw5programs/compile_global_fptr.oat", "", "7");
|
||||
("hw5programs/compile_global_fptr_unordered.oat", "", "2");
|
||||
("hw5programs/compile_scall_fptr.oat", "", "4");
|
||||
("hw5programs/compile_var_fptr.oat", "", "1");
|
||||
("hw5programs/compile_local_fptr.oat", "", "5");
|
||||
("hw5programs/compile_function_shadow.oat", "", "12");
|
||||
("hw5programs/compile_global_struct_fptr.oat", "", "20");
|
||||
("hw5programs/compile_builtin_argument.oat", "", "abab0");
|
||||
]
|
||||
|
||||
|
||||
let tc_ok_tests = [
|
||||
"hw5programs/tc_struct_ok.oat"
|
||||
; "hw5programs/tc_func_ret_ok.oat"
|
||||
; "hw5programs/tc_func_arg_ok.oat"
|
||||
; "hw5programs/tc_ifq1.oat"
|
||||
; "oatprograms/tc_ok1.oat"
|
||||
; "oatprograms/tc_ok2.oat"
|
||||
; "oatprograms/tc_ok4.oat"
|
||||
; "oatprograms/tc_ok5.oat"
|
||||
; "oatprograms/tc_ok6.oat"
|
||||
; "oatprograms/tc_ok7.oat"
|
||||
; "oatprograms/tc_ok8.oat"
|
||||
; "hw5programs/tc_arrow.oat"
|
||||
; "hw5programs/tc_arrow_null.oat"
|
||||
; "hw5programs/tc_arrow_null_rec.oat"
|
||||
]
|
||||
|
||||
let tc_err_tests = [
|
||||
"hw5programs/tc_null_array_err.oat"
|
||||
; "hw5programs/tc_struct_err.oat"
|
||||
; "hw5programs/tc_func_ret_err.oat"
|
||||
; "hw5programs/tc_func_arg_err.oat"
|
||||
; "hw5programs/tc_array_err.oat"
|
||||
; "hw5programs/tc_struct_field_err.oat"
|
||||
; "hw5programs/tc_recursive_struct_err.oat"
|
||||
; "hw5programs/tc_ifq_err1.oat"
|
||||
]
|
||||
|
||||
|
||||
let typecheck_tests : suite = [
|
||||
GradedTest("subtype unit tests", 3, unit_tests);
|
||||
GradedTest("tc subtyping tests", 4, typecheck_file_correct typecheck_subtyping_tests);
|
||||
GradedTest("tc subtyping error tests", 4, typecheck_file_error typecheck_subtyping_error_tests);
|
||||
GradedTest("tc statement error tests", 5, typecheck_file_error typecheck_statement_error_tests);
|
||||
GradedTest("tc statement correct tests", 5, typecheck_file_correct typecheck_correct_statement_tests);
|
||||
GradedTest("tc other correct tests", 5, typecheck_file_correct typecheck_correct_other_tests);
|
||||
GradedTest("tc null/not null error tests", 5, typecheck_file_error typecheck_error_null_not_null_tests);
|
||||
GradedTest("tc expression error tests", 5, typecheck_file_error typecheck_error_expression_tests);
|
||||
GradedTest("tc struct/global error tests", 5, typecheck_file_error (typecheck_error_struct_tests @ typecheck_error_global_tests));
|
||||
GradedTest("extra tc err tests", 5, typecheck_file_error tc_err_tests);
|
||||
|
||||
]
|
||||
|
||||
let student_tests = []
|
||||
|
||||
let hw5_tests : suite = [
|
||||
GradedTest("tc ok tests", 10, executed_tc_ok_file tc_ok_tests)
|
||||
; GradedTest("struct tests", 10, executed_oat_file struct_tests)
|
||||
; GradedTest("fptr tests", 4, executed_oat_file fptr_tests)
|
||||
; GradedTest("hidden tests", 20, executed_oat_file student_tests)
|
||||
]
|
||||
|
||||
|
||||
let hw4_tests =
|
||||
hw4_easiest_tests
|
||||
@ hw4_globals_tests
|
||||
@ hw4_path_tests
|
||||
@ hw4_easy_tests
|
||||
@ hw4_medium_tests
|
||||
@ hw4_hard_tests
|
||||
@ hw4_old_student_tests
|
||||
|
||||
let functionality_tests : suite = [GradedTest("functionality tests from HW04", 10, executed_oat_file hw4_tests)]
|
||||
|
||||
let graded_tests : suite =
|
||||
typecheck_tests @
|
||||
hw5_tests @
|
||||
functionality_tests
|
||||
13
hw5/hw4programs/abs.oat
Normal file
13
hw5/hw4programs/abs.oat
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
int abs(int x) {
|
||||
if (x < 0) {
|
||||
return -x;
|
||||
} else if (x > 0) {
|
||||
return x;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
int program (int argc, string[] argv) {
|
||||
print_int(abs(10) + abs(-10) + abs(0));
|
||||
return 0;
|
||||
}
|
||||
8
hw5/hw4programs/argassign.oat
Normal file
8
hw5/hw4programs/argassign.oat
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
int foo(int x) {
|
||||
x = x + 1;
|
||||
return x;
|
||||
}
|
||||
|
||||
int program (int argc, string[] argv) {
|
||||
return foo(17);
|
||||
}
|
||||
|
|
@ -7,8 +7,8 @@ int[] f(int[] x, int[] y, bool b) {
|
|||
}
|
||||
|
||||
int program (int argc, string[] argv) {
|
||||
var x = new int[3]{i -> 0};
|
||||
var y = new int[3]{i -> 0};
|
||||
var x = new int[3];
|
||||
var y = new int[3];
|
||||
f(x, y, true)[0] = 17;
|
||||
return x[0];
|
||||
}
|
||||
|
|
@ -51,7 +51,7 @@ bool binary_search (int[] input, int key, int min, int max) {
|
|||
}
|
||||
|
||||
int program (int argc, string[] argv) {
|
||||
var test_array = new int[100]{i->0};
|
||||
var test_array = new int[100];
|
||||
for (var i=0; i < 100; i=i+1;) { test_array[i] = 2 * i + 1; }
|
||||
var even = binary_search (test_array, 80, 0, 99);
|
||||
var odd = binary_search (test_array, 81, 0, 99);
|
||||
|
|
@ -20,7 +20,7 @@ void bubble_sort(int[] numbers, int array_size)
|
|||
}
|
||||
|
||||
int program (int argc, string[] argv) {
|
||||
var a = new int[8]{i -> 0};
|
||||
var a = new int[8];
|
||||
|
||||
a[0] = 121;
|
||||
a[1] = 125;
|
||||
|
|
@ -23,7 +23,7 @@ int[] count_sort(int[] arr, int len) {
|
|||
var min = min(arr, len);
|
||||
var max = max(arr, len);
|
||||
|
||||
var counts = new int[max - min + 1]{i->0};
|
||||
var counts = new int[max - min + 1];
|
||||
|
||||
for (var i = 0; i < len; i = i + 1;) {
|
||||
counts[arr[i] - min] = counts[arr[i] - min] + 1;
|
||||
|
|
@ -32,7 +32,7 @@ int[] count_sort(int[] arr, int len) {
|
|||
var i = min;
|
||||
var j = 0;
|
||||
|
||||
var out = new int[len]{i2->0};
|
||||
var out = new int[len];
|
||||
|
||||
while (i <= max) {
|
||||
|
||||
14
hw5/hw4programs/easy_p5.oat
Normal file
14
hw5/hw4programs/easy_p5.oat
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
global i = 19;
|
||||
global b1 = true;
|
||||
global b2 = false;
|
||||
global str = "This is a string!";
|
||||
global arr1 = new int[]{0,1,2};
|
||||
global arr2 = new int[][]{ new int[]{10,11}, new int[]{20,21}, new int[]{30,31}};
|
||||
global arr3 = new string[]{"String1", "String2", "String3"};
|
||||
|
||||
global arr4 = new string[][]
|
||||
{
|
||||
new string[]{"String00","String01"},
|
||||
new string[]{"String10","String11"},
|
||||
new string[]{"String20","String21"}
|
||||
};
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
global j = int[]{1,2,3,4};
|
||||
global j = new int[]{1,2,3,4};
|
||||
int[] f () {
|
||||
var a = new int[][]{1, 2};
|
||||
var i = new int[4];
|
||||
var arr1 = new int[3];
|
||||
var arr2 = new int[][3];
|
||||
return new int[2];
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
int program (int argc, string[] argv) {
|
||||
if(6 != 5) {
|
||||
return ~(5 << 17 >> 2 >>> 10) * 2 - 100 + 6;
|
||||
return ~(5 >> --6 << 9 >>> 10) * 2 - 100 + 6;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
|
|
@ -1,52 +1,52 @@
|
|||
global float_len = 2;
|
||||
int[] determine_shift(int[] float)
|
||||
{
|
||||
var dec = float[1];
|
||||
var count = 0;
|
||||
while(dec > 0)
|
||||
{
|
||||
var temp = float[0];
|
||||
float[0] = temp << 1;
|
||||
dec = dec >>> 1;
|
||||
count = count + 1;
|
||||
}
|
||||
var list = new int[2];
|
||||
list[0] = float[0] + float[1];
|
||||
list[1] = count;
|
||||
return list;
|
||||
}
|
||||
|
||||
int[] multiply_floats(int[] f1, int[] f2)
|
||||
{
|
||||
var f1_shifted = determine_shift(f1);
|
||||
var f2_shifted = determine_shift(f2);
|
||||
var product = f1_shifted[0] * f2_shifted[0];
|
||||
var num_left_shifts = f1_shifted[1] + f2_shifted[1];
|
||||
var remainder = 0;
|
||||
for(var i = 0; i < num_left_shifts; i=i+1;)
|
||||
{
|
||||
var lsb = product [&] 1;
|
||||
var shifted_lsb = lsb << i;
|
||||
product = product >>> 1;
|
||||
remainder = remainder + shifted_lsb;
|
||||
}
|
||||
var ans = new int[2];
|
||||
ans[0] = product;
|
||||
ans[1] = remainder;
|
||||
return ans;
|
||||
}
|
||||
|
||||
int program(int argc, string[] argv)
|
||||
{
|
||||
var pi = new int[2];
|
||||
pi[0] = 3;
|
||||
pi[1] = 14159;
|
||||
var diameter = new int[2];
|
||||
diameter[0] = 20;
|
||||
diameter[1] = 17;
|
||||
var prod = multiply_floats(pi, diameter);
|
||||
print_int(prod[0]);
|
||||
print_string(".");
|
||||
print_int(prod[1]);
|
||||
return 0;
|
||||
global float_len = 2;
|
||||
int[] determine_shift(int[] float)
|
||||
{
|
||||
var dec = float[1];
|
||||
var count = 0;
|
||||
while(dec > 0)
|
||||
{
|
||||
var temp = float[0];
|
||||
float[0] = temp << 1;
|
||||
dec = dec >>> 1;
|
||||
count = count + 1;
|
||||
}
|
||||
var list = new int[2];
|
||||
list[0] = float[0] + float[1];
|
||||
list[1] = count;
|
||||
return list;
|
||||
}
|
||||
|
||||
int[] multiply_floats(int[] f1, int[] f2)
|
||||
{
|
||||
var f1_shifted = determine_shift(f1);
|
||||
var f2_shifted = determine_shift(f2);
|
||||
var product = f1_shifted[0] * f2_shifted[0];
|
||||
var num_left_shifts = f1_shifted[1] + f2_shifted[1];
|
||||
var remainder = 0;
|
||||
for(var i = 0; i < num_left_shifts; i=i+1;)
|
||||
{
|
||||
var lsb = product [&] 1;
|
||||
var shifted_lsb = lsb << i;
|
||||
product = product >>> 1;
|
||||
remainder = remainder + shifted_lsb;
|
||||
}
|
||||
var ans = new int[2];
|
||||
ans[0] = product;
|
||||
ans[1] = remainder;
|
||||
return ans;
|
||||
}
|
||||
|
||||
int program(int argc, string[] argv)
|
||||
{
|
||||
var pi = new int[2];
|
||||
pi[0] = 3;
|
||||
pi[1] = 14159;
|
||||
var diameter = new int[2];
|
||||
diameter[0] = 20;
|
||||
diameter[1] = 17;
|
||||
var prod = multiply_floats(pi, diameter);
|
||||
print_int(prod[0]);
|
||||
print_string(".");
|
||||
print_int(prod[1]);
|
||||
return 0;
|
||||
}
|
||||
8
hw5/hw4programs/globals7.oat
Normal file
8
hw5/hw4programs/globals7.oat
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
global arr = new int[] {};
|
||||
|
||||
int program (int argc, string[] argv) {
|
||||
var x = new int[3];
|
||||
arr = x;
|
||||
x[2] = 3;
|
||||
return arr[2];
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
int[] insert(int[] partial, int len, int insertee) {
|
||||
var inserted = new int[len+1]{i->0};
|
||||
var inserted = new int[len+1];
|
||||
for (var i=0; i < len+1; i=i+1;) { inserted[i] = -1; }
|
||||
var not_yet_inserted = true;
|
||||
if (insertee < partial[0]) {
|
||||
|
|
@ -20,7 +20,7 @@ void print_lfsr(bool[] lfsr_register, int len) {
|
|||
|
||||
int program(int argc, string[] argv) {
|
||||
/* Initialize the working register */
|
||||
var lfsr_register = new bool[lfsr_length]{i->false};
|
||||
var lfsr_register = new bool[lfsr_length];
|
||||
for (var i=0; i < lfsr_length; i=i+1;) {
|
||||
lfsr_register[i] = lfsr_init_values[i];
|
||||
}
|
||||
|
|
@ -1,6 +1,9 @@
|
|||
string sub (string str, int start, int len) {
|
||||
var arr = array_of_string(str);
|
||||
var r = new int[len]{i -> arr[i+start]};
|
||||
var r = new int[len];
|
||||
for (var i = 0; i < len; i = i + 1;) {
|
||||
r[i] = arr[i+start];
|
||||
}
|
||||
return string_of_array (r);
|
||||
}
|
||||
|
||||
|
|
@ -44,7 +44,10 @@ int program (int argc, string[] argv) {
|
|||
new int[]{1, 1, 1, 0},
|
||||
new int[]{0, 0, 0, 0} };
|
||||
|
||||
var new_board = new int[][4];
|
||||
var new_board = new int[][]{ new int[]{0, 0, 0, 0},
|
||||
new int[]{0, 0, 0, 0},
|
||||
new int[]{0, 0, 0, 0},
|
||||
new int[]{0, 0, 0, 0} };
|
||||
for (var i=0; i < 4; i=i+1;) {
|
||||
new_board[i] = new int[4];
|
||||
for (var j=0; j < 4; j=j+1;) { new_board[i][j] = val_at(board, i,j); }
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
int maxsum(int[] arr, int size) {
|
||||
var maxarr = new int[size]{i->0};
|
||||
var maxarr = new int[size];
|
||||
var maxs = 0;
|
||||
maxarr[0] = arr[0];
|
||||
for(var i = 0; i < size; i = i+1;){
|
||||
|
|
@ -27,7 +27,7 @@ void merge(int[] a, int low, int high, int mid)
|
|||
var i=0;
|
||||
var j=0;
|
||||
var k=0;
|
||||
var c=new int[50]{i1->0};
|
||||
var c=new int[50];
|
||||
i=low;
|
||||
j=mid+1;
|
||||
k=low;
|
||||
|
|
@ -27,7 +27,7 @@ void merge(int[] a, int low, int high, int mid)
|
|||
var i=0;
|
||||
var j=0;
|
||||
var k=0;
|
||||
var c=new int[50]{i2->0};
|
||||
var c=new int[50];
|
||||
i=low;
|
||||
j=mid+1;
|
||||
k=low;
|
||||
|
|
@ -1,39 +1,39 @@
|
|||
int mod (int a, int b) {
|
||||
var t = a;
|
||||
while (t - b >= 0) {
|
||||
t = t - b;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
int div (int a, int b) {
|
||||
var result = 0;
|
||||
var num = a;
|
||||
var denom = b;
|
||||
while (num > 0) {
|
||||
num = num - denom;
|
||||
result = result + 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int no_of_factors(int n) {
|
||||
var num_fact = 1;
|
||||
var input = n;
|
||||
for (var i = 2; i * i < input + 1; i=i+1;) {
|
||||
var power = 0;
|
||||
while (mod(n, i) == 0) {
|
||||
n = div(n, i);
|
||||
power = power + 1;
|
||||
}
|
||||
num_fact = num_fact * (power + 1);
|
||||
}
|
||||
if (n > 1) {
|
||||
num_fact = num_fact * 2;
|
||||
}
|
||||
return num_fact;
|
||||
}
|
||||
|
||||
int program (int argc, string[] argv) {
|
||||
return no_of_factors(6400);
|
||||
}
|
||||
int mod (int a, int b) {
|
||||
var t = a;
|
||||
while (t - b >= 0) {
|
||||
t = t - b;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
int div (int a, int b) {
|
||||
var result = 0;
|
||||
var num = a;
|
||||
var denom = b;
|
||||
while (num > 0) {
|
||||
num = num - denom;
|
||||
result = result + 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int no_of_factors(int n) {
|
||||
var num_fact = 1;
|
||||
var input = n;
|
||||
for (var i = 2; i * i < input + 1; i=i+1;) {
|
||||
var power = 0;
|
||||
while (mod(n, i) == 0) {
|
||||
n = div(n, i);
|
||||
power = power + 1;
|
||||
}
|
||||
num_fact = num_fact * (power + 1);
|
||||
}
|
||||
if (n > 1) {
|
||||
num_fact = num_fact * 2;
|
||||
}
|
||||
return num_fact;
|
||||
}
|
||||
|
||||
int program (int argc, string[] argv) {
|
||||
return no_of_factors(6400);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue