diff --git a/hw4/.ocamlformat b/hw4/.ocamlformat new file mode 100644 index 0000000..fd111e4 --- /dev/null +++ b/hw4/.ocamlformat @@ -0,0 +1,2 @@ +profile = janestreet +version = 0.26.1 diff --git a/hw4/.ocamlinit b/hw4/.ocamlinit index 56ad796..576e012 100644 --- a/hw4/.ocamlinit +++ b/hw4/.ocamlinit @@ -1,9 +1 @@ -#use "topfind";; - -#directory "_build" -#directory "_build/util" -#directory "_build/x86" -#directory "_build/grading" - -#load_rec "x86.cmo" -#use "llinterp.ml" \ No newline at end of file +#use_output "dune top";; diff --git a/hw4/Makefile b/hw4/Makefile index 12de57b..0f33163 100644 --- a/hw4/Makefile +++ b/hw4/Makefile @@ -1,24 +1,27 @@ -INCLUDES= util,x86,grading,ll -LIBS = unix,str -SUBMIT := lexer.mll parser.mly frontend.ml team.txt +SUBMIT := $(shell cat submit_zip_contents.txt) +HWNAME := hw4 +TIMESTAMP := $(shell /bin/date "+%Y-%m-%d-%H:%M:%S") +ZIPNAME := $(HWNAME)-submit-$(TIMESTAMP).zip -HWNAME := hw04 -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 -main.native: $(SUBMIT) ast.ml astlib.ml backend.ml driver.ml main.ml progasts.ml runtime.c - ocamlbuild -Is $(INCLUDES) -libs $(LIBS) -pkg num 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 + +# diff --git a/hw4/README b/hw4/README deleted file mode 100644 index c640226..0000000 --- a/hw4/README +++ /dev/null @@ -1,76 +0,0 @@ -Using main.native: - -main.native acts like the clang compiler. Given several .ll, .c, and .o files, -it will compile the .ll files to .s files (using the Compiler Design 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 -Compiler Design backend, which can be useful for testing purposes. - - -* To run the automated test harness do: - ./main.native --test - -* To compile ll files using the Compiler Design 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-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 Compiler Design backend or clang-compiled code) - - --clang compiles to assembly using clang, not the Compiler Design backend - - -v - generates verbose output, showing which commands are used - for linking, etc. - - -op - 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 Compiler Design backend: - - -./main.native --execute-x86 programs/factrect.ll ---------------------------------------------------------------- Executing: a.out -* a.out returned 120 diff --git a/hw4/README.md b/hw4/README.md new file mode 100644 index 0000000..8285fc6 --- /dev/null +++ b/hw4/README.md @@ -0,0 +1,72 @@ +# HW4: Oat v.1 + +Quick Start: + +1. open the folder in VSCode +2. start an OCaml sandbox terminal +3. run `make test` from the command line +4. 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 CIS 341 +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 341 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 341 backend or clang-compiled code) | + | --clang | compiles to assembly using clang, not the 341 backend | + | -v | generates verbose output, showing which commands are used for linking, etc. | + | -op ```` | 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 341 backend: + + /oatc --execute-x86 hw4programs/fact.oat bin/runtime.c + 120--------------------------------------------------------------- Executing: a.out + * a.out returned 0 diff --git a/hw4/ast.ml b/hw4/bin/ast.ml similarity index 68% rename from hw4/ast.ml rename to hw4/bin/ast.ml index 0b0319c..e88dfe7 100644 --- a/hw4/ast.ml +++ b/hw4/bin/ast.ml @@ -1,13 +1,27 @@ +(* The type declarations in this file correspond to productions in the Oat + * grammar provided in the Oat v.1 Language Specification. *) +module Range = Util.Range + +(* The `node` type represents a node in an abstract syntax tree. + * The `elt` is the AST element, the `loc` contains the line number + * info of the corresponding concrete syntax element. The parser uses + * the `loc` to give line numbers with error messages, and you can do + * so too in the compiler if you like! + *) type 'a node = { elt : 'a; loc : Range.t } (** val no_loc : 'a1 -> 'a1 node **) +(* This function might be useful if some of your helper functions + * have to return a `node` type. + *) let no_loc x = { elt = x; loc = Range.norange } type id = string +(* Oat types *) type ty = | TBool | TInt @@ -43,6 +57,7 @@ type binop = | Shr | Sar +(* Oat expressions *) type exp = | CNull of rty | CBool of bool diff --git a/hw4/astlib.ml b/hw4/bin/astlib.ml similarity index 100% rename from hw4/astlib.ml rename to hw4/bin/astlib.ml diff --git a/hw4/backend.ml b/hw4/bin/backend.ml similarity index 91% rename from hw4/backend.ml rename to hw4/bin/backend.ml index beebfd6..5321837 100644 --- a/hw4/backend.ml +++ b/hw4/bin/backend.ml @@ -3,11 +3,13 @@ open Ll open X86 +module Platform = Util.Platform + (* Overview ----------------------------------------------------------------- *) -(* We suggest that you spend some time understinging this entire file and +(* We suggest that you spend some time understanding this entire file and how it fits with the compiler pipeline before making changes. The suggested - plan for implementing the compiler is provided on the project web page. + plan for implementing the compiler is provided on the project web page. *) @@ -52,7 +54,7 @@ let rbp_offset (offset:int) : X86.operand = 'stack layout'. A stack layout maps a uid to an X86 operand for accessing its contents. For this compilation strategy, the operand is always an offset from %rbp (in bytes) that represents a storage slot in - the stack. + the stack. *) type layout = (uid * X86.operand) list @@ -77,7 +79,7 @@ let lookup m x = List.assoc x m NOTE: two important facts about global identifiers: - (1) You should use (Platform.mangle gid) to obtain a string + (1) You should use (Platform.mangle gid) to obtain a string suitable for naming a global label on your platform (OS X expects "_main" while linux expects "main"). @@ -85,14 +87,14 @@ let lookup m x = List.assoc x m That is, the X86 code: movq _gid %rax which looks like it should put the address denoted by _gid into %rax is not allowed. Instead, you need to compute an %rip-relative address using the - leaq instruction: leaq _gid(%rip). + leaq instruction: leaq _gid(%rip) %rax. One strategy for compiling instruction operands is to use a designated register (or registers) for holding the values being manipulated by the LLVM IR instruction. You might find it useful to implement the following helper function, whose job is to generate the X86 instruction that moves an LLVM operand into a designated - destination (usually a register). + destination (usually a register). *) let compile_operand ctxt dest : Ll.operand -> ins = function @@ -104,7 +106,7 @@ let compile_operand ctxt dest : Ll.operand -> ins = (* compiling call ---------------------------------------------------------- *) -(* You will probably find it helpful to implement a helper function that +(* You will probably find it helpful to implement a helper function that generates code for the LLVM IR call instruction. The code you generate should follow the x64 System V AMD64 ABI @@ -120,6 +122,9 @@ let compile_operand ctxt dest : Ll.operand -> ins = [ NOTE: Don't forget to preserve caller-save registers (only if needed). ] + + [ NOTE: Remember, call can use labels as immediates! You shouldn't + need to perform any RIP-relative addressing for this one. ] *) @@ -164,11 +169,11 @@ let compile_call ctxt fop args = address based on the size of the data, which is dictated by the data's type. - To compile getelmentptr, you must generate x86 code that performs - the appropriate arithemetic calculations. + To compile getelementptr, you must generate x86 code that performs + the appropriate arithmetic calculations. *) -(* [size_ty] maps an LLVMlite type to a size in bytes. +(* [size_ty] maps an LLVMlite type to a size in bytes. (needed for getelementptr) - the size of a struct is the sum of the sizes of each component @@ -185,7 +190,7 @@ let rec size_ty (tdecls:(tid * ty) list) (t:Ll.ty) : int = | I1 | I64 | Ptr _ -> 8 (* Target 64-bit only subset of X86 *) | Struct ts -> List.fold_left (fun acc t -> acc + (size_ty tdecls t)) 0 ts | Array (n, t) -> n * (size_ty tdecls t) - | Namedt id -> size_ty tdecls (List.assoc id tdecls) + | Namedt id -> size_ty tdecls (lookup tdecls id) end (* Compute the size of the offset (in bytes) of the nth element of a region @@ -200,7 +205,7 @@ let index_into tdecls (ts:ty list) (n:int) : int * ty = in loop ts n 0 -(* Generates code that computes a pointer value. +(* Generates code that computes a pointer value. 1. op must be of pointer type: t* @@ -211,14 +216,14 @@ let index_into tdecls (ts:ty list) (n:int) : int * ty = 4. subsequent indices are interpreted according to the type t: - - if t is a struct, the index must be a constant n and it + - if t is a struct, the index must be a constant n and it picks out the n'th element of the struct. [ NOTE: the offset - within the struct of the n'th element is determined by the + within the struct of the n'th element is determined by the sizes of the types of the previous elements ] - if t is an array, the index can be any operand, and its value determines the offset within the array. - + - if t is any other type, the path is invalid 5. if the index is valid, the remainder of the path is computed as @@ -227,6 +232,10 @@ let index_into tdecls (ts:ty list) (n:int) : int * ty = *) let compile_gep (ctxt:ctxt) (op : Ll.ty * Ll.operand) (path: Ll.operand list) : ins list = let op_to_rax = compile_operand ctxt (Reg Rax) in + let rec effective_type = function + | Namedt id -> effective_type @@ lookup ctxt.tdecls id + | t -> t + in let rec loop ty path code = match (ty, path) with | (_, []) -> List.rev code @@ -248,11 +257,11 @@ let compile_gep (ctxt:ctxt) (op : Ll.ty * Ll.operand) (path: Ll.operand list) : Asm.(Movq, [~%Rax; ~%Rcx]) :: code - | (Namedt t, p) -> loop (List.assoc t ctxt.tdecls) p code + | (Namedt t, p) -> loop (lookup ctxt.tdecls t) p code | _ -> failwith "compile_gep encountered unsupported getelementptr data" in - match op with + match (effective_type @@ fst op, snd op) with | (Ptr t, op) -> loop (Array(0, t)) path [op_to_rax op] | _ -> failwith "compile_gep got incorrect parameters" @@ -281,15 +290,15 @@ let compile_gep (ctxt:ctxt) (op : Ll.ty * Ll.operand) (path: Ll.operand list) : - Bitcast: does nothing interesting at the assembly level *) let compile_insn (ctxt:ctxt) ((uid:uid), (i:Ll.insn)) : X86.ins list = - let op_to = compile_operand ctxt in + let op_to = compile_operand ctxt in let op_to_rax = op_to (Reg Rax) in (* Move the value of op into rax *) let op_to_rcx = op_to (Reg Rcx) in (* Move the value of op into rax *) let dst = lookup ctxt.layout uid in match i with - | Binop (bop, t, op1, op2) -> - let bin op = - (op_to_rax op1) :: - (op_to_rcx op2) :: + | Binop (bop, _t, op1, op2) -> + let bin op = + (op_to_rax op1) :: + (op_to_rcx op2) :: Asm.([ op, [~%Rcx; ~%Rax] ; Movq, [~%Rax; dst] ]) in @@ -305,26 +314,26 @@ let compile_insn (ctxt:ctxt) ((uid:uid), (i:Ll.insn)) : X86.ins list = | Ll.Xor -> bin Xorq end - (* Alloca instructions allocate an fresh stack slot and + (* Alloca instructions allocate an fresh stack slot and move the address of the newly allocated storage into the destination uid. *) | Alloca (_t) -> Asm.([ Pushq, [~$0] - ; Movq, [~%Rsp; dst] ]) + ; Movq, [~%Rsp; dst] ]) (* Load dereferences the pointer value stored in a local. Global and constant pointers don't need indirection. *) - | Load (t, op) -> (op_to_rax op) :: Asm.([ Movq, [Ind2 Rax; ~%Rcx] - ; Movq, [~%Rcx; dst] ]) + | Load (_t, op) -> (op_to_rax op) :: Asm.([ Movq, [Ind2 Rax; ~%Rcx] + ; Movq, [~%Rcx; dst] ]) (* Store also needs to dereference the destination pointer if it's a global *) - | Store (_, src, (Id uid as dest)) -> + | Store (_, src, (Id _ as dest)) -> (op_to_rcx src) :: (op_to_rax dest) :: Asm.([Movq, [~%Rcx; Ind2 Rax]]) | Store (_, src, Gid gid) -> (op_to_rax src) :: Asm.([Movq, [~%Rax; Ind3 (Lbl (Platform.mangle gid), Rip)]]) | Store (_, _, _) -> failwith "store destination was not a local or global id" - (* Treat LL i1 values as words, so zero-out the rest of the bits *) + (* Treat LL i1 values as quadwords, so zero-out the rest of the bits *) | Icmp (cnd, _, op1, op2) -> (op_to_rax op1) :: (op_to_rcx op2) :: Asm.([ Cmpq, [~%Rcx; ~%Rax] @@ -362,6 +371,8 @@ let mk_lbl (fn:string) (l:string) = fn ^ "." ^ l - Br should jump - Cbr branch should treat its operand as a boolean conditional + + [fn] - the name of the function containing this terminator *) let compile_terminator (fn:string) (ctxt:ctxt) (t:Ll.terminator) : ins list = let epilogue = Asm.([ Movq, [~%Rbp; ~%Rsp] @@ -405,13 +416,13 @@ let arg_loc (n : int) : operand = | None -> rbp_offset (n-4) end -(* We suggest that you create a helper function that computes the +(* We suggest that you create a helper function that computes the stack layout for a given function declaration. - each function argument should be copied into a stack slot - - in this (inefficient) compilation strategy, each local id + - in this (inefficient) compilation strategy, each local id is also stored as a stack slot. - - see the discussion about locals + - see the discussion about locals *) let stack_layout (args : uid list) ((block, lbled_blocks):cfg) : layout = @@ -467,7 +478,7 @@ let rec compile_ginit : ginit -> X86.data list = function | GInt c -> [Quad (Lit c)] | GString s -> [Asciz s] | GArray gs | GStruct gs -> List.map compile_gdecl gs |> List.flatten - | GBitcast (t1,g,t2) -> compile_ginit g + | GBitcast (_t1,g,_t2) -> compile_ginit g and compile_gdecl (_, g) = compile_ginit g diff --git a/hw4/driver.ml b/hw4/bin/driver.ml similarity index 95% rename from hw4/driver.ml rename to hw4/bin/driver.ml index f2cbe9c..aba123e 100644 --- a/hw4/driver.ml +++ b/hw4/bin/driver.ml @@ -1,4 +1,6 @@ open Printf +module Platform = Util.Platform +module Range = Util.Range open Platform (* configuration flags ------------------------------------------------------ *) @@ -76,7 +78,7 @@ let run_program (args:string) (executable:string) (tmp_out:string) : string = read_file tmp_out let run_program_error (args:string) (executable:string) (tmp_out:string) : string = - let cmd = sprintf "timeout 60 %s%s %s > %s 2>&1" dot_path executable args tmp_out in + let cmd = sprintf "%s%s %s > %s 2>&1" dot_path executable args tmp_out in let result = sh cmd (fun _ i -> i) in (read_file tmp_out) ^ (string_of_int result) @@ -107,7 +109,7 @@ let string_of_ll_ast path ll_ast = let process_ll_ast path file ll_ast = let _ = if !print_ll_flag then print_ll file ll_ast in - (* Optionally interpret it using the reference interpreter. *) + (* Optionally interpret it using the cis341 reference interperter. *) let _ = if !interpret_ll then let result = interpret ll_ast [] in Printf.printf "Interpreter Result: %s\n" result @@ -126,7 +128,7 @@ let process_ll_ast path file ll_ast = Platform.sh (Printf.sprintf "cat %s" dot_s_file) Platform.raise_error end end else begin - Platform.verb "* compiling with Compiler Design backend"; + Platform.verb "* compiling with cis341 backend"; let asm_ast = Backend.compile_prog ll_ast in let asm_str = X86.string_of_prog asm_ast in let _ = if !print_x86_flag then print_x86 dot_s_file asm_str in @@ -198,7 +200,7 @@ let process_files files = 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 diff --git a/hw4/bin/dune b/hw4/bin/dune new file mode 100644 index 0000000..e5a18b8 --- /dev/null +++ b/hw4/bin/dune @@ -0,0 +1,31 @@ +(library + (name oat) + (modules driver backend frontend lexer parser ast astlib) + (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 + ; sp24_hw4_tests + )) diff --git a/hw4/frontend.ml b/hw4/bin/frontend.ml similarity index 94% rename from hw4/frontend.ml rename to hw4/bin/frontend.ml index 05e81e0..6f885f1 100644 --- a/hw4/frontend.ml +++ b/hw4/bin/frontend.ml @@ -2,11 +2,17 @@ open Ll open Llutil open Ast +(* This file is where much of the work of the project will be carried out. + Follow the instructions on the project web site, but first skim through + this file to see what it contains. +*) + + (* instruction streams ------------------------------------------------------ *) (* As in the last project, we'll be working with a flattened representation of LLVMlite programs to make emitting code easier. This version - additionally makes it possible to emit elements will be gathered up and + additionally makes it possible to emit elements that will be gathered up and "hoisted" to specific parts of the constructed CFG - G of gid * Ll.gdecl: allows you to output global definitions in the middle of the instruction stream. You will find this useful for compiling string @@ -23,6 +29,16 @@ type elt = | G of gid * Ll.gdecl (* hoisted globals (usually strings) *) | E of uid * Ll.insn (* hoisted entry block instructions *) +(* The type of streams of LLVMLite instructions. Note that to improve performance, + * we will emit the instructions in reverse order. That is, the LLVMLite code: + * %1 = mul i64 2, 2 + * %2 = add i64 1, %1 + * br label %l1 + * would be constructed as a stream as follows: + * I ("1", Binop (Mul, I64, Const 2L, Const 2L)) + * >:: I ("2", Binop (Add, I64, Const 1L, Id "1")) + * >:: T (Br "l1") + *) type stream = elt list let ( >@ ) x y = y @ x let ( >:: ) x y = y :: x @@ -160,10 +176,10 @@ let typ_of_unop : Ast.unop -> Ast.ty * Ast.ty = function the array), we can simply compile e1[e2] as a left-hand-side and then do the load. So cmp_exp and cmp_lhs are mutually recursive. [[Actually, as I am writing this, I think it could make sense to factor the Oat grammar in this - way, which would make things clearer, I may do that for next time around.]] + way, which would make things clearerhw, I may do that for next time around.]] - Consider globals7.oat + Consider globals7.oat (in hw4programs) /--------------- globals7.oat ------------------ global arr = int[] null; @@ -247,7 +263,7 @@ let typ_of_unop : Ast.unop -> Ast.ty * Ast.ty = function (* Global initialized arrays: - There is another wrinkle: To compile global initialized arrays like in the + There is another wrinkle: to compile global initialized arrays like in the globals4.oat, it is helpful to do a bitcast once at the global scope to convert the "precise type" required by the LLVM initializer to the actual translation type (which sets the array length to 0). So for globals4.oat, @@ -287,6 +303,9 @@ let oat_alloc_array (t:Ast.ty) (size:Ll.operand) : Ll.ty * operand * stream = [ arr_id, Call(arr_ty, Gid "oat_alloc_array", [I64, size]) ; ans_id, Bitcast(arr_ty, Id arr_id, ans_ty) ] + + + (* Compiles an expression exp in context c, outputting the Ll operand that will recieve the value of the expression, and the stream of instructions implementing the expression. @@ -303,9 +322,9 @@ let oat_alloc_array (t:Ast.ty) (size:Ll.operand) : Ll.ty * operand * stream = (CArr) and the (NewArr) expressions *) - let rec cmp_exp (c:Ctxt.t) (exp:Ast.exp node) : Ll.ty * Ll.operand * stream = - failwith "cmp_exp not implemented" + failwith "cmp_exp unimplemented" + (* Compile a statement in context c with return typ rt. Return a new context, possibly extended with new local bindings, and the instruction stream @@ -333,10 +352,10 @@ let rec cmp_exp (c:Ctxt.t) (exp:Ast.exp node) : Ll.ty * Ll.operand * stream = pointer, you just need to store to it! *) - let rec cmp_stmt (c:Ctxt.t) (rt:Ll.ty) (stmt:Ast.stmt node) : Ctxt.t * stream = failwith "cmp_stmt not implemented" + (* Compile a series of statements *) and cmp_block (c:Ctxt.t) (rt:Ll.ty) (stmts:Ast.block) : Ctxt.t * stream = List.fold_left (fun (c, code) s -> @@ -366,7 +385,7 @@ let cmp_function_ctxt (c:Ctxt.t) (p:Ast.prog) : Ctxt.t = in well-formed programs. (The constructors starting with C). *) let cmp_global_ctxt (c:Ctxt.t) (p:Ast.prog) : Ctxt.t = - failwith "cmp_global_ctxt not implemented" + failwith "cmp_global_ctxt unimplemented" (* Compile a function declaration in global context c. Return the LLVMlite cfg and a list of global declarations containing the string literals appearing @@ -379,10 +398,10 @@ let cmp_global_ctxt (c:Ctxt.t) (p:Ast.prog) : Ctxt.t = 4. Compile the body of the function using cmp_block 5. Use cfg_of_stream to produce a LLVMlite cfg from *) - let cmp_fdecl (c:Ctxt.t) (f:Ast.fdecl node) : Ll.fdecl * (Ll.gid * Ll.gdecl) list = failwith "cmp_fdecl not implemented" + (* Compile a global initializer, returning the resulting LLVMlite global declaration, and a list of additional global declarations. @@ -394,9 +413,9 @@ let cmp_fdecl (c:Ctxt.t) (f:Ast.fdecl node) : Ll.fdecl * (Ll.gid * Ll.gdecl) lis - OAT arrays are always handled via pointers. A global array of arrays will be an array of pointers to arrays emitted as additional global declarations. *) - let rec cmp_gexp c (e:Ast.exp node) : Ll.gdecl * (Ll.gid * Ll.gdecl) list = - failwith "cmp_gexp not implemented" + failwith "cmp_init not implemented" + (* Oat internals function context ------------------------------------------- *) let internals = [ diff --git a/hw4/lexer.mll b/hw4/bin/lexer.mll similarity index 99% rename from hw4/lexer.mll rename to hw4/bin/lexer.mll index d864900..9f3a339 100644 --- a/hw4/lexer.mll +++ b/hw4/bin/lexer.mll @@ -1,6 +1,7 @@ { open Lexing open Parser + module Range = Util.Range open Range exception Lexer_error of Range.t * string @@ -53,6 +54,7 @@ ( ")", RPAREN); ( "[", LBRACKET); ( "]", RBRACKET); + ] let (symbol_table : (string, Parser.token) Hashtbl.t) = Hashtbl.create 1024 diff --git a/hw4/main.ml b/hw4/bin/main.ml similarity index 93% rename from hw4/main.ml rename to hw4/bin/main.ml index e6c771d..eb5474e 100644 --- a/hw4/main.ml +++ b/hw4/bin/main.ml @@ -1,7 +1,7 @@ open Ll open Arg -open Assert -open Driver +open Util.Assert +open Oat.Driver (* testing harness ---------------------------------------------------------- *) exception Ran_tests @@ -23,12 +23,12 @@ let args = ; ("--interpret-ll", Set interpret_ll, "runs each LL program through the LL interpreter") ; ("--print-ll", Set print_ll_flag, "prints the program LL code") ; ("--print-x86", Set print_x86_flag, "prints the program's assembly code") - ; ("--clang", Set clang, "compiles to assembly using clang, not the Compiler Design backend") + ; ("--clang", Set clang, "compiles to assembly using clang, not the 341 backend") ; ("--execute-x86", Set execute_x86, "run the resulting executable file") ; ("--print-ast", Set print_ast_flag , "print the program's AST as ML code") ; ("--print-oat", Set print_oat_flag , "print the program's OAT code") ; ("-v", Unit Platform.enable_verbose, "enables more verbose compilation output") - ] + ] (* Files found on the command line *) @@ -39,12 +39,13 @@ let main () = Platform.create_output_dir (); try Arg.parse args (fun filename -> files := filename :: !files) - "Compiler Design main test harness\n\ + "CS 131 main test harness\n\ USAGE: ./main.native [options] \n\ see README for details about using the compiler"; process_files !files - with Ran_tests -> () + with Ran_tests -> + () ;; main () diff --git a/hw4/parser.mly b/hw4/bin/parser.mly similarity index 97% rename from hw4/parser.mly rename to hw4/bin/parser.mly index 2d08289..5f6e507 100644 --- a/hw4/parser.mly +++ b/hw4/bin/parser.mly @@ -1,5 +1,6 @@ %{ open Ast +open Lexing let loc (startpos:Lexing.position) (endpos:Lexing.position) (elt:'a) : 'a node = { elt ; loc=Range.mk_lex_range startpos endpos } @@ -38,6 +39,8 @@ let loc (startpos:Lexing.position) (endpos:Lexing.position) (elt:'a) : 'a node = %token BANG /* ! */ %token GLOBAL /* global */ + + %left PLUS DASH %left STAR %nonassoc BANG @@ -82,6 +85,7 @@ ty: | TINT { TInt } | r=rtyp { TRef r } + %inline ret_ty: | TVOID { RetVoid } | t=ty { RetVal t } @@ -94,7 +98,7 @@ ty: | PLUS { Add } | DASH { Sub } | STAR { Mul } - | EQEQ { Eq } + | EQEQ { Eq } %inline uop: | DASH { Neg } @@ -103,7 +107,7 @@ ty: gexp: | t=rtyp NULL { loc $startpos $endpos @@ CNull t } - | i=INT { loc $startpos $endpos @@ CInt i } + | i=INT { loc $startpos $endpos @@ CInt i } lhs: | id=IDENT { loc $startpos $endpos @@ Id id } diff --git a/hw4/runtime.c b/hw4/bin/runtime.c similarity index 100% rename from hw4/runtime.c rename to hw4/bin/runtime.c diff --git a/hw4/dune-project b/hw4/dune-project new file mode 100644 index 0000000..5418e12 --- /dev/null +++ b/hw4/dune-project @@ -0,0 +1,3 @@ +(lang dune 2.9) +(name hw4) +(using menhir 2.1) diff --git a/hw4/hw4.opam b/hw4/hw4.opam new file mode 100644 index 0000000..e69de29 diff --git a/hw4/oatprograms/abs.oat b/hw4/hw4programs/abs.oat similarity index 100% rename from hw4/oatprograms/abs.oat rename to hw4/hw4programs/abs.oat diff --git a/hw4/hw4programs/argassign.oat b/hw4/hw4programs/argassign.oat new file mode 100644 index 0000000..446c90c --- /dev/null +++ b/hw4/hw4programs/argassign.oat @@ -0,0 +1,8 @@ +int foo(int x) { + x = x + 1; + return x; +} + +int program (int argc, string[] argv) { + return foo(17); +} diff --git a/hw4/oatprograms/arrayargs.oat b/hw4/hw4programs/arrayargs.oat similarity index 100% rename from hw4/oatprograms/arrayargs.oat rename to hw4/hw4programs/arrayargs.oat diff --git a/hw4/oatprograms/arrayargs1.oat b/hw4/hw4programs/arrayargs1.oat similarity index 100% rename from hw4/oatprograms/arrayargs1.oat rename to hw4/hw4programs/arrayargs1.oat diff --git a/hw4/oatprograms/arrayargs2.oat b/hw4/hw4programs/arrayargs2.oat similarity index 100% rename from hw4/oatprograms/arrayargs2.oat rename to hw4/hw4programs/arrayargs2.oat diff --git a/hw4/oatprograms/arrayargs3.oat b/hw4/hw4programs/arrayargs3.oat similarity index 100% rename from hw4/oatprograms/arrayargs3.oat rename to hw4/hw4programs/arrayargs3.oat diff --git a/hw4/oatprograms/arrayargs4.oat b/hw4/hw4programs/arrayargs4.oat similarity index 100% rename from hw4/oatprograms/arrayargs4.oat rename to hw4/hw4programs/arrayargs4.oat diff --git a/hw4/oatprograms/binary_gcd.oat b/hw4/hw4programs/binary_gcd.oat similarity index 100% rename from hw4/oatprograms/binary_gcd.oat rename to hw4/hw4programs/binary_gcd.oat diff --git a/hw4/oatprograms/binary_search.oat b/hw4/hw4programs/binary_search.oat similarity index 100% rename from hw4/oatprograms/binary_search.oat rename to hw4/hw4programs/binary_search.oat diff --git a/hw4/oatprograms/bsort.oat b/hw4/hw4programs/bsort.oat similarity index 100% rename from hw4/oatprograms/bsort.oat rename to hw4/hw4programs/bsort.oat diff --git a/hw4/oatprograms/calculator.oat b/hw4/hw4programs/calculator.oat similarity index 100% rename from hw4/oatprograms/calculator.oat rename to hw4/hw4programs/calculator.oat diff --git a/hw4/oatprograms/count_sort.oat b/hw4/hw4programs/count_sort.oat similarity index 100% rename from hw4/oatprograms/count_sort.oat rename to hw4/hw4programs/count_sort.oat diff --git a/hw4/oatprograms/easy_p1.oat b/hw4/hw4programs/easy_p1.oat similarity index 100% rename from hw4/oatprograms/easy_p1.oat rename to hw4/hw4programs/easy_p1.oat diff --git a/hw4/oatprograms/easy_p2.oat b/hw4/hw4programs/easy_p2.oat similarity index 100% rename from hw4/oatprograms/easy_p2.oat rename to hw4/hw4programs/easy_p2.oat diff --git a/hw4/oatprograms/easy_p3.oat b/hw4/hw4programs/easy_p3.oat similarity index 87% rename from hw4/oatprograms/easy_p3.oat rename to hw4/hw4programs/easy_p3.oat index 530ced8..6e998bc 100644 --- a/hw4/oatprograms/easy_p3.oat +++ b/hw4/hw4programs/easy_p3.oat @@ -16,7 +16,7 @@ void proc2 ( ) { } bool foo ( int x, int[] y ) { - var s = bar (x, "compilerdesign"); + var s = bar (x, "cis341"); proc1 (); return true; } diff --git a/hw4/oatprograms/easy_p4.oat b/hw4/hw4programs/easy_p4.oat similarity index 100% rename from hw4/oatprograms/easy_p4.oat rename to hw4/hw4programs/easy_p4.oat diff --git a/hw4/oatprograms/easy_p5.oat b/hw4/hw4programs/easy_p5.oat similarity index 100% rename from hw4/oatprograms/easy_p5.oat rename to hw4/hw4programs/easy_p5.oat diff --git a/hw4/oatprograms/easy_p6.oat b/hw4/hw4programs/easy_p6.oat similarity index 100% rename from hw4/oatprograms/easy_p6.oat rename to hw4/hw4programs/easy_p6.oat diff --git a/hw4/oatprograms/easy_p7.oat b/hw4/hw4programs/easy_p7.oat similarity index 100% rename from hw4/oatprograms/easy_p7.oat rename to hw4/hw4programs/easy_p7.oat diff --git a/hw4/oatprograms/easyrun1.oat b/hw4/hw4programs/easyrun1.oat similarity index 100% rename from hw4/oatprograms/easyrun1.oat rename to hw4/hw4programs/easyrun1.oat diff --git a/hw4/oatprograms/easyrun10.oat b/hw4/hw4programs/easyrun10.oat similarity index 100% rename from hw4/oatprograms/easyrun10.oat rename to hw4/hw4programs/easyrun10.oat diff --git a/hw4/oatprograms/easyrun2.oat b/hw4/hw4programs/easyrun2.oat similarity index 100% rename from hw4/oatprograms/easyrun2.oat rename to hw4/hw4programs/easyrun2.oat diff --git a/hw4/oatprograms/easyrun3.oat b/hw4/hw4programs/easyrun3.oat similarity index 100% rename from hw4/oatprograms/easyrun3.oat rename to hw4/hw4programs/easyrun3.oat diff --git a/hw4/oatprograms/easyrun4.oat b/hw4/hw4programs/easyrun4.oat similarity index 100% rename from hw4/oatprograms/easyrun4.oat rename to hw4/hw4programs/easyrun4.oat diff --git a/hw4/oatprograms/easyrun5.oat b/hw4/hw4programs/easyrun5.oat similarity index 100% rename from hw4/oatprograms/easyrun5.oat rename to hw4/hw4programs/easyrun5.oat diff --git a/hw4/oatprograms/easyrun6.oat b/hw4/hw4programs/easyrun6.oat similarity index 100% rename from hw4/oatprograms/easyrun6.oat rename to hw4/hw4programs/easyrun6.oat diff --git a/hw4/oatprograms/easyrun7.oat b/hw4/hw4programs/easyrun7.oat similarity index 100% rename from hw4/oatprograms/easyrun7.oat rename to hw4/hw4programs/easyrun7.oat diff --git a/hw4/oatprograms/easyrun8.oat b/hw4/hw4programs/easyrun8.oat similarity index 64% rename from hw4/oatprograms/easyrun8.oat rename to hw4/hw4programs/easyrun8.oat index 21cbce6..a5607fd 100644 --- a/hw4/oatprograms/easyrun8.oat +++ b/hw4/hw4programs/easyrun8.oat @@ -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; } diff --git a/hw4/oatprograms/easyrun9.oat b/hw4/hw4programs/easyrun9.oat similarity index 100% rename from hw4/oatprograms/easyrun9.oat rename to hw4/hw4programs/easyrun9.oat diff --git a/hw4/oatprograms/fac.oat b/hw4/hw4programs/fac.oat similarity index 100% rename from hw4/oatprograms/fac.oat rename to hw4/hw4programs/fac.oat diff --git a/hw4/oatprograms/fact.oat b/hw4/hw4programs/fact.oat similarity index 100% rename from hw4/oatprograms/fact.oat rename to hw4/hw4programs/fact.oat diff --git a/hw4/oatprograms/fibo.oat b/hw4/hw4programs/fibo.oat similarity index 100% rename from hw4/oatprograms/fibo.oat rename to hw4/hw4programs/fibo.oat diff --git a/hw4/oatprograms/float_multiply.oat b/hw4/hw4programs/float_multiply.oat similarity index 95% rename from hw4/oatprograms/float_multiply.oat rename to hw4/hw4programs/float_multiply.oat index 2548138..cdb2b00 100644 --- a/hw4/oatprograms/float_multiply.oat +++ b/hw4/hw4programs/float_multiply.oat @@ -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; } \ No newline at end of file diff --git a/hw4/oatprograms/gcd.oat b/hw4/hw4programs/gcd.oat similarity index 100% rename from hw4/oatprograms/gcd.oat rename to hw4/hw4programs/gcd.oat diff --git a/hw4/oatprograms/globals1.oat b/hw4/hw4programs/globals1.oat similarity index 100% rename from hw4/oatprograms/globals1.oat rename to hw4/hw4programs/globals1.oat diff --git a/hw4/oatprograms/globals2.oat b/hw4/hw4programs/globals2.oat similarity index 100% rename from hw4/oatprograms/globals2.oat rename to hw4/hw4programs/globals2.oat diff --git a/hw4/oatprograms/globals3.oat b/hw4/hw4programs/globals3.oat similarity index 100% rename from hw4/oatprograms/globals3.oat rename to hw4/hw4programs/globals3.oat diff --git a/hw4/oatprograms/globals4.oat b/hw4/hw4programs/globals4.oat similarity index 100% rename from hw4/oatprograms/globals4.oat rename to hw4/hw4programs/globals4.oat diff --git a/hw4/oatprograms/globals5.oat b/hw4/hw4programs/globals5.oat similarity index 100% rename from hw4/oatprograms/globals5.oat rename to hw4/hw4programs/globals5.oat diff --git a/hw4/oatprograms/globals6.oat b/hw4/hw4programs/globals6.oat similarity index 100% rename from hw4/oatprograms/globals6.oat rename to hw4/hw4programs/globals6.oat diff --git a/hw4/oatprograms/globals7.oat b/hw4/hw4programs/globals7.oat similarity index 100% rename from hw4/oatprograms/globals7.oat rename to hw4/hw4programs/globals7.oat diff --git a/hw4/oatprograms/gnomesort.oat b/hw4/hw4programs/gnomesort.oat similarity index 100% rename from hw4/oatprograms/gnomesort.oat rename to hw4/hw4programs/gnomesort.oat diff --git a/hw4/oatprograms/hashcode.oat b/hw4/hw4programs/hashcode.oat similarity index 100% rename from hw4/oatprograms/hashcode.oat rename to hw4/hw4programs/hashcode.oat diff --git a/hw4/oatprograms/heap.oat b/hw4/hw4programs/heap.oat similarity index 100% rename from hw4/oatprograms/heap.oat rename to hw4/hw4programs/heap.oat diff --git a/hw4/oatprograms/insertion_sort.oat b/hw4/hw4programs/insertion_sort.oat similarity index 100% rename from hw4/oatprograms/insertion_sort.oat rename to hw4/hw4programs/insertion_sort.oat diff --git a/hw4/oatprograms/is_prime.oat b/hw4/hw4programs/is_prime.oat similarity index 100% rename from hw4/oatprograms/is_prime.oat rename to hw4/hw4programs/is_prime.oat diff --git a/hw4/oatprograms/josh_joyce_test.oat b/hw4/hw4programs/josh_joyce_test.oat similarity index 100% rename from hw4/oatprograms/josh_joyce_test.oat rename to hw4/hw4programs/josh_joyce_test.oat diff --git a/hw4/oatprograms/kmp.oat b/hw4/hw4programs/kmp.oat similarity index 100% rename from hw4/oatprograms/kmp.oat rename to hw4/hw4programs/kmp.oat diff --git a/hw4/oatprograms/lcs.oat b/hw4/hw4programs/lcs.oat similarity index 93% rename from hw4/oatprograms/lcs.oat rename to hw4/hw4programs/lcs.oat index 2bc752b..f2da612 100644 --- a/hw4/oatprograms/lcs.oat +++ b/hw4/hw4programs/lcs.oat @@ -1,3 +1,8 @@ +/* + * CIS 341 Homework 4 + * Thomas Delacour & Max McCarthy + */ + /** * Computes longest common subsequence of two strings a and b. */ diff --git a/hw4/oatprograms/leastsquare.oat b/hw4/hw4programs/leastsquare.oat similarity index 100% rename from hw4/oatprograms/leastsquare.oat rename to hw4/hw4programs/leastsquare.oat diff --git a/hw4/oatprograms/lfsr.oat b/hw4/hw4programs/lfsr.oat similarity index 100% rename from hw4/oatprograms/lfsr.oat rename to hw4/hw4programs/lfsr.oat diff --git a/hw4/oatprograms/lfsr2.oat b/hw4/hw4programs/lfsr2.oat similarity index 100% rename from hw4/oatprograms/lfsr2.oat rename to hw4/hw4programs/lfsr2.oat diff --git a/hw4/oatprograms/lib10.oat b/hw4/hw4programs/lib10.oat similarity index 100% rename from hw4/oatprograms/lib10.oat rename to hw4/hw4programs/lib10.oat diff --git a/hw4/oatprograms/lib11.oat b/hw4/hw4programs/lib11.oat similarity index 100% rename from hw4/oatprograms/lib11.oat rename to hw4/hw4programs/lib11.oat diff --git a/hw4/oatprograms/lib12.oat b/hw4/hw4programs/lib12.oat similarity index 100% rename from hw4/oatprograms/lib12.oat rename to hw4/hw4programs/lib12.oat diff --git a/hw4/oatprograms/lib13.oat b/hw4/hw4programs/lib13.oat similarity index 100% rename from hw4/oatprograms/lib13.oat rename to hw4/hw4programs/lib13.oat diff --git a/hw4/oatprograms/lib14.oat b/hw4/hw4programs/lib14.oat similarity index 100% rename from hw4/oatprograms/lib14.oat rename to hw4/hw4programs/lib14.oat diff --git a/hw4/oatprograms/lib15.oat b/hw4/hw4programs/lib15.oat similarity index 100% rename from hw4/oatprograms/lib15.oat rename to hw4/hw4programs/lib15.oat diff --git a/hw4/oatprograms/lib2.oat b/hw4/hw4programs/lib2.oat similarity index 100% rename from hw4/oatprograms/lib2.oat rename to hw4/hw4programs/lib2.oat diff --git a/hw4/oatprograms/lib3.oat b/hw4/hw4programs/lib3.oat similarity index 100% rename from hw4/oatprograms/lib3.oat rename to hw4/hw4programs/lib3.oat diff --git a/hw4/oatprograms/lib4.oat b/hw4/hw4programs/lib4.oat similarity index 100% rename from hw4/oatprograms/lib4.oat rename to hw4/hw4programs/lib4.oat diff --git a/hw4/oatprograms/lib5.oat b/hw4/hw4programs/lib5.oat similarity index 100% rename from hw4/oatprograms/lib5.oat rename to hw4/hw4programs/lib5.oat diff --git a/hw4/oatprograms/lib6.oat b/hw4/hw4programs/lib6.oat similarity index 100% rename from hw4/oatprograms/lib6.oat rename to hw4/hw4programs/lib6.oat diff --git a/hw4/oatprograms/lib7.oat b/hw4/hw4programs/lib7.oat similarity index 100% rename from hw4/oatprograms/lib7.oat rename to hw4/hw4programs/lib7.oat diff --git a/hw4/oatprograms/lib8.oat b/hw4/hw4programs/lib8.oat similarity index 100% rename from hw4/oatprograms/lib8.oat rename to hw4/hw4programs/lib8.oat diff --git a/hw4/oatprograms/lib9.oat b/hw4/hw4programs/lib9.oat similarity index 100% rename from hw4/oatprograms/lib9.oat rename to hw4/hw4programs/lib9.oat diff --git a/hw4/oatprograms/life.oat b/hw4/hw4programs/life.oat similarity index 100% rename from hw4/oatprograms/life.oat rename to hw4/hw4programs/life.oat diff --git a/hw4/oatprograms/matrixmult.oat b/hw4/hw4programs/matrixmult.oat similarity index 100% rename from hw4/oatprograms/matrixmult.oat rename to hw4/hw4programs/matrixmult.oat diff --git a/hw4/oatprograms/maxsubsequence.oat b/hw4/hw4programs/maxsubsequence.oat similarity index 100% rename from hw4/oatprograms/maxsubsequence.oat rename to hw4/hw4programs/maxsubsequence.oat diff --git a/hw4/oatprograms/msort.oat b/hw4/hw4programs/msort.oat similarity index 100% rename from hw4/oatprograms/msort.oat rename to hw4/hw4programs/msort.oat diff --git a/hw4/oatprograms/msort2.oat b/hw4/hw4programs/msort2.oat similarity index 100% rename from hw4/oatprograms/msort2.oat rename to hw4/hw4programs/msort2.oat diff --git a/hw4/oatprograms/no_of_fac.oat b/hw4/hw4programs/no_of_fac.oat similarity index 94% rename from hw4/oatprograms/no_of_fac.oat rename to hw4/hw4programs/no_of_fac.oat index 8ded4de..1de54d6 100644 --- a/hw4/oatprograms/no_of_fac.oat +++ b/hw4/hw4programs/no_of_fac.oat @@ -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); +} diff --git a/hw4/oatprograms/path1.oat b/hw4/hw4programs/path1.oat similarity index 100% rename from hw4/oatprograms/path1.oat rename to hw4/hw4programs/path1.oat diff --git a/hw4/oatprograms/path2.oat b/hw4/hw4programs/path2.oat similarity index 100% rename from hw4/oatprograms/path2.oat rename to hw4/hw4programs/path2.oat diff --git a/hw4/oatprograms/path3.oat b/hw4/hw4programs/path3.oat similarity index 100% rename from hw4/oatprograms/path3.oat rename to hw4/hw4programs/path3.oat diff --git a/hw4/oatprograms/phase2_1.oat b/hw4/hw4programs/phase2_1.oat similarity index 100% rename from hw4/oatprograms/phase2_1.oat rename to hw4/hw4programs/phase2_1.oat diff --git a/hw4/oatprograms/qs_bs.oat b/hw4/hw4programs/qs_bs.oat similarity index 100% rename from hw4/oatprograms/qs_bs.oat rename to hw4/hw4programs/qs_bs.oat diff --git a/hw4/oatprograms/qsort.oat b/hw4/hw4programs/qsort.oat similarity index 100% rename from hw4/oatprograms/qsort.oat rename to hw4/hw4programs/qsort.oat diff --git a/hw4/oatprograms/regalloctest.oat b/hw4/hw4programs/regalloctest.oat similarity index 100% rename from hw4/oatprograms/regalloctest.oat rename to hw4/hw4programs/regalloctest.oat diff --git a/hw4/oatprograms/regalloctest2.oat b/hw4/hw4programs/regalloctest2.oat similarity index 100% rename from hw4/oatprograms/regalloctest2.oat rename to hw4/hw4programs/regalloctest2.oat diff --git a/hw4/oatprograms/regex.oat b/hw4/hw4programs/regex.oat similarity index 100% rename from hw4/oatprograms/regex.oat rename to hw4/hw4programs/regex.oat diff --git a/hw4/oatprograms/reverse.oat b/hw4/hw4programs/reverse.oat similarity index 100% rename from hw4/oatprograms/reverse.oat rename to hw4/hw4programs/reverse.oat diff --git a/hw4/oatprograms/rod_cutting.oat b/hw4/hw4programs/rod_cutting.oat similarity index 100% rename from hw4/oatprograms/rod_cutting.oat rename to hw4/hw4programs/rod_cutting.oat diff --git a/hw4/oatprograms/run1.oat b/hw4/hw4programs/run1.oat similarity index 100% rename from hw4/oatprograms/run1.oat rename to hw4/hw4programs/run1.oat diff --git a/hw4/oatprograms/run10.oat b/hw4/hw4programs/run10.oat similarity index 100% rename from hw4/oatprograms/run10.oat rename to hw4/hw4programs/run10.oat diff --git a/hw4/oatprograms/run11.oat b/hw4/hw4programs/run11.oat similarity index 100% rename from hw4/oatprograms/run11.oat rename to hw4/hw4programs/run11.oat diff --git a/hw4/oatprograms/run13.oat b/hw4/hw4programs/run13.oat similarity index 100% rename from hw4/oatprograms/run13.oat rename to hw4/hw4programs/run13.oat diff --git a/hw4/oatprograms/run14.oat b/hw4/hw4programs/run14.oat similarity index 100% rename from hw4/oatprograms/run14.oat rename to hw4/hw4programs/run14.oat diff --git a/hw4/oatprograms/run15.oat b/hw4/hw4programs/run15.oat similarity index 100% rename from hw4/oatprograms/run15.oat rename to hw4/hw4programs/run15.oat diff --git a/hw4/oatprograms/run16.oat b/hw4/hw4programs/run16.oat similarity index 100% rename from hw4/oatprograms/run16.oat rename to hw4/hw4programs/run16.oat diff --git a/hw4/oatprograms/run18.oat b/hw4/hw4programs/run18.oat similarity index 100% rename from hw4/oatprograms/run18.oat rename to hw4/hw4programs/run18.oat diff --git a/hw4/oatprograms/run19.oat b/hw4/hw4programs/run19.oat similarity index 100% rename from hw4/oatprograms/run19.oat rename to hw4/hw4programs/run19.oat diff --git a/hw4/oatprograms/run2.oat b/hw4/hw4programs/run2.oat similarity index 100% rename from hw4/oatprograms/run2.oat rename to hw4/hw4programs/run2.oat diff --git a/hw4/oatprograms/run20.oat b/hw4/hw4programs/run20.oat similarity index 100% rename from hw4/oatprograms/run20.oat rename to hw4/hw4programs/run20.oat diff --git a/hw4/oatprograms/run21.oat b/hw4/hw4programs/run21.oat similarity index 100% rename from hw4/oatprograms/run21.oat rename to hw4/hw4programs/run21.oat diff --git a/hw4/oatprograms/run22.oat b/hw4/hw4programs/run22.oat similarity index 100% rename from hw4/oatprograms/run22.oat rename to hw4/hw4programs/run22.oat diff --git a/hw4/oatprograms/run23.oat b/hw4/hw4programs/run23.oat similarity index 100% rename from hw4/oatprograms/run23.oat rename to hw4/hw4programs/run23.oat diff --git a/hw4/oatprograms/run24.oat b/hw4/hw4programs/run24.oat similarity index 100% rename from hw4/oatprograms/run24.oat rename to hw4/hw4programs/run24.oat diff --git a/hw4/oatprograms/run25.oat b/hw4/hw4programs/run25.oat similarity index 100% rename from hw4/oatprograms/run25.oat rename to hw4/hw4programs/run25.oat diff --git a/hw4/oatprograms/run26.oat b/hw4/hw4programs/run26.oat similarity index 100% rename from hw4/oatprograms/run26.oat rename to hw4/hw4programs/run26.oat diff --git a/hw4/oatprograms/run27.oat b/hw4/hw4programs/run27.oat similarity index 100% rename from hw4/oatprograms/run27.oat rename to hw4/hw4programs/run27.oat diff --git a/hw4/oatprograms/run28.oat b/hw4/hw4programs/run28.oat similarity index 100% rename from hw4/oatprograms/run28.oat rename to hw4/hw4programs/run28.oat diff --git a/hw4/oatprograms/run29.oat b/hw4/hw4programs/run29.oat similarity index 100% rename from hw4/oatprograms/run29.oat rename to hw4/hw4programs/run29.oat diff --git a/hw4/oatprograms/run3.oat b/hw4/hw4programs/run3.oat similarity index 100% rename from hw4/oatprograms/run3.oat rename to hw4/hw4programs/run3.oat diff --git a/hw4/oatprograms/run30.oat b/hw4/hw4programs/run30.oat similarity index 100% rename from hw4/oatprograms/run30.oat rename to hw4/hw4programs/run30.oat diff --git a/hw4/oatprograms/run31.oat b/hw4/hw4programs/run31.oat similarity index 100% rename from hw4/oatprograms/run31.oat rename to hw4/hw4programs/run31.oat diff --git a/hw4/oatprograms/run32.oat b/hw4/hw4programs/run32.oat similarity index 100% rename from hw4/oatprograms/run32.oat rename to hw4/hw4programs/run32.oat diff --git a/hw4/oatprograms/run33.oat b/hw4/hw4programs/run33.oat similarity index 100% rename from hw4/oatprograms/run33.oat rename to hw4/hw4programs/run33.oat diff --git a/hw4/oatprograms/run34.oat b/hw4/hw4programs/run34.oat similarity index 100% rename from hw4/oatprograms/run34.oat rename to hw4/hw4programs/run34.oat diff --git a/hw4/oatprograms/run35.oat b/hw4/hw4programs/run35.oat similarity index 100% rename from hw4/oatprograms/run35.oat rename to hw4/hw4programs/run35.oat diff --git a/hw4/oatprograms/run36.oat b/hw4/hw4programs/run36.oat similarity index 100% rename from hw4/oatprograms/run36.oat rename to hw4/hw4programs/run36.oat diff --git a/hw4/oatprograms/run37.oat b/hw4/hw4programs/run37.oat similarity index 100% rename from hw4/oatprograms/run37.oat rename to hw4/hw4programs/run37.oat diff --git a/hw4/oatprograms/run38.oat b/hw4/hw4programs/run38.oat similarity index 100% rename from hw4/oatprograms/run38.oat rename to hw4/hw4programs/run38.oat diff --git a/hw4/oatprograms/run39.oat b/hw4/hw4programs/run39.oat similarity index 100% rename from hw4/oatprograms/run39.oat rename to hw4/hw4programs/run39.oat diff --git a/hw4/oatprograms/run4.oat b/hw4/hw4programs/run4.oat similarity index 100% rename from hw4/oatprograms/run4.oat rename to hw4/hw4programs/run4.oat diff --git a/hw4/oatprograms/run40.oat b/hw4/hw4programs/run40.oat similarity index 100% rename from hw4/oatprograms/run40.oat rename to hw4/hw4programs/run40.oat diff --git a/hw4/oatprograms/run41.oat b/hw4/hw4programs/run41.oat similarity index 100% rename from hw4/oatprograms/run41.oat rename to hw4/hw4programs/run41.oat diff --git a/hw4/oatprograms/run42.oat b/hw4/hw4programs/run42.oat similarity index 100% rename from hw4/oatprograms/run42.oat rename to hw4/hw4programs/run42.oat diff --git a/hw4/oatprograms/run43.oat b/hw4/hw4programs/run43.oat similarity index 100% rename from hw4/oatprograms/run43.oat rename to hw4/hw4programs/run43.oat diff --git a/hw4/oatprograms/run44.oat b/hw4/hw4programs/run44.oat similarity index 100% rename from hw4/oatprograms/run44.oat rename to hw4/hw4programs/run44.oat diff --git a/hw4/oatprograms/run45.oat b/hw4/hw4programs/run45.oat similarity index 100% rename from hw4/oatprograms/run45.oat rename to hw4/hw4programs/run45.oat diff --git a/hw4/oatprograms/run46.oat b/hw4/hw4programs/run46.oat similarity index 100% rename from hw4/oatprograms/run46.oat rename to hw4/hw4programs/run46.oat diff --git a/hw4/oatprograms/run47.oat b/hw4/hw4programs/run47.oat similarity index 100% rename from hw4/oatprograms/run47.oat rename to hw4/hw4programs/run47.oat diff --git a/hw4/oatprograms/run48.oat b/hw4/hw4programs/run48.oat similarity index 100% rename from hw4/oatprograms/run48.oat rename to hw4/hw4programs/run48.oat diff --git a/hw4/oatprograms/run49.oat b/hw4/hw4programs/run49.oat similarity index 100% rename from hw4/oatprograms/run49.oat rename to hw4/hw4programs/run49.oat diff --git a/hw4/oatprograms/run5.oat b/hw4/hw4programs/run5.oat similarity index 100% rename from hw4/oatprograms/run5.oat rename to hw4/hw4programs/run5.oat diff --git a/hw4/oatprograms/run50.oat b/hw4/hw4programs/run50.oat similarity index 100% rename from hw4/oatprograms/run50.oat rename to hw4/hw4programs/run50.oat diff --git a/hw4/oatprograms/run51.oat b/hw4/hw4programs/run51.oat similarity index 100% rename from hw4/oatprograms/run51.oat rename to hw4/hw4programs/run51.oat diff --git a/hw4/oatprograms/run52.oat b/hw4/hw4programs/run52.oat similarity index 100% rename from hw4/oatprograms/run52.oat rename to hw4/hw4programs/run52.oat diff --git a/hw4/oatprograms/run53.oat b/hw4/hw4programs/run53.oat similarity index 100% rename from hw4/oatprograms/run53.oat rename to hw4/hw4programs/run53.oat diff --git a/hw4/oatprograms/run54.oat b/hw4/hw4programs/run54.oat similarity index 100% rename from hw4/oatprograms/run54.oat rename to hw4/hw4programs/run54.oat diff --git a/hw4/oatprograms/run55.oat b/hw4/hw4programs/run55.oat similarity index 100% rename from hw4/oatprograms/run55.oat rename to hw4/hw4programs/run55.oat diff --git a/hw4/oatprograms/run56.oat b/hw4/hw4programs/run56.oat similarity index 100% rename from hw4/oatprograms/run56.oat rename to hw4/hw4programs/run56.oat diff --git a/hw4/oatprograms/run6.oat b/hw4/hw4programs/run6.oat similarity index 100% rename from hw4/oatprograms/run6.oat rename to hw4/hw4programs/run6.oat diff --git a/hw4/oatprograms/run60.oat b/hw4/hw4programs/run60.oat similarity index 86% rename from hw4/oatprograms/run60.oat rename to hw4/hw4programs/run60.oat index 65469d6..3b2d0ae 100644 --- a/hw4/oatprograms/run60.oat +++ b/hw4/hw4programs/run60.oat @@ -1,6 +1,6 @@ global i = 3; int program(int argc, string[] argv) { - i = 42; + i = 341; return i; } diff --git a/hw4/oatprograms/run61.oat b/hw4/hw4programs/run61.oat similarity index 80% rename from hw4/oatprograms/run61.oat rename to hw4/hw4programs/run61.oat index c62c899..b6b7947 100644 --- a/hw4/oatprograms/run61.oat +++ b/hw4/hw4programs/run61.oat @@ -1,4 +1,4 @@ -global s = "42"; +global s = "341"; int program(int argc, string[] argv) { print_string(s); diff --git a/hw4/oatprograms/run7.oat b/hw4/hw4programs/run7.oat similarity index 100% rename from hw4/oatprograms/run7.oat rename to hw4/hw4programs/run7.oat diff --git a/hw4/oatprograms/run8.oat b/hw4/hw4programs/run8.oat similarity index 100% rename from hw4/oatprograms/run8.oat rename to hw4/hw4programs/run8.oat diff --git a/hw4/oatprograms/run9.oat b/hw4/hw4programs/run9.oat similarity index 100% rename from hw4/oatprograms/run9.oat rename to hw4/hw4programs/run9.oat diff --git a/hw4/oatprograms/runtime-fail1.oat b/hw4/hw4programs/runtime-fail1.oat similarity index 100% rename from hw4/oatprograms/runtime-fail1.oat rename to hw4/hw4programs/runtime-fail1.oat diff --git a/hw4/oatprograms/runtime-fail2.oat b/hw4/hw4programs/runtime-fail2.oat similarity index 100% rename from hw4/oatprograms/runtime-fail2.oat rename to hw4/hw4programs/runtime-fail2.oat diff --git a/hw4/oatprograms/runtime-fail3.oat b/hw4/hw4programs/runtime-fail3.oat similarity index 100% rename from hw4/oatprograms/runtime-fail3.oat rename to hw4/hw4programs/runtime-fail3.oat diff --git a/hw4/oatprograms/runtime-fail4.oat b/hw4/hw4programs/runtime-fail4.oat similarity index 100% rename from hw4/oatprograms/runtime-fail4.oat rename to hw4/hw4programs/runtime-fail4.oat diff --git a/hw4/oatprograms/selectionsort.oat b/hw4/hw4programs/selectionsort.oat similarity index 100% rename from hw4/oatprograms/selectionsort.oat rename to hw4/hw4programs/selectionsort.oat diff --git a/hw4/oatprograms/setg.oat b/hw4/hw4programs/setg.oat similarity index 100% rename from hw4/oatprograms/setg.oat rename to hw4/hw4programs/setg.oat diff --git a/hw4/oatprograms/shortest_path_matrix.oat b/hw4/hw4programs/shortest_path_matrix.oat similarity index 100% rename from hw4/oatprograms/shortest_path_matrix.oat rename to hw4/hw4programs/shortest_path_matrix.oat diff --git a/hw4/oatprograms/sieve.oat b/hw4/hw4programs/sieve.oat similarity index 100% rename from hw4/oatprograms/sieve.oat rename to hw4/hw4programs/sieve.oat diff --git a/hw4/oatprograms/sqrt.oat b/hw4/hw4programs/sqrt.oat similarity index 100% rename from hw4/oatprograms/sqrt.oat rename to hw4/hw4programs/sqrt.oat diff --git a/hw4/oatprograms/tc1.oat b/hw4/hw4programs/tc1.oat similarity index 100% rename from hw4/oatprograms/tc1.oat rename to hw4/hw4programs/tc1.oat diff --git a/hw4/oatprograms/tc10.oat b/hw4/hw4programs/tc10.oat similarity index 100% rename from hw4/oatprograms/tc10.oat rename to hw4/hw4programs/tc10.oat diff --git a/hw4/oatprograms/tc11.oat b/hw4/hw4programs/tc11.oat similarity index 100% rename from hw4/oatprograms/tc11.oat rename to hw4/hw4programs/tc11.oat diff --git a/hw4/oatprograms/tc12.oat b/hw4/hw4programs/tc12.oat similarity index 100% rename from hw4/oatprograms/tc12.oat rename to hw4/hw4programs/tc12.oat diff --git a/hw4/oatprograms/tc13.oat b/hw4/hw4programs/tc13.oat similarity index 100% rename from hw4/oatprograms/tc13.oat rename to hw4/hw4programs/tc13.oat diff --git a/hw4/oatprograms/tc14.oat b/hw4/hw4programs/tc14.oat similarity index 100% rename from hw4/oatprograms/tc14.oat rename to hw4/hw4programs/tc14.oat diff --git a/hw4/oatprograms/tc15.oat b/hw4/hw4programs/tc15.oat similarity index 100% rename from hw4/oatprograms/tc15.oat rename to hw4/hw4programs/tc15.oat diff --git a/hw4/oatprograms/tc16.oat b/hw4/hw4programs/tc16.oat similarity index 100% rename from hw4/oatprograms/tc16.oat rename to hw4/hw4programs/tc16.oat diff --git a/hw4/oatprograms/tc17.oat b/hw4/hw4programs/tc17.oat similarity index 100% rename from hw4/oatprograms/tc17.oat rename to hw4/hw4programs/tc17.oat diff --git a/hw4/oatprograms/tc18.oat b/hw4/hw4programs/tc18.oat similarity index 100% rename from hw4/oatprograms/tc18.oat rename to hw4/hw4programs/tc18.oat diff --git a/hw4/oatprograms/tc19.oat b/hw4/hw4programs/tc19.oat similarity index 100% rename from hw4/oatprograms/tc19.oat rename to hw4/hw4programs/tc19.oat diff --git a/hw4/oatprograms/tc2.oat b/hw4/hw4programs/tc2.oat similarity index 100% rename from hw4/oatprograms/tc2.oat rename to hw4/hw4programs/tc2.oat diff --git a/hw4/oatprograms/tc20.oat b/hw4/hw4programs/tc20.oat similarity index 100% rename from hw4/oatprograms/tc20.oat rename to hw4/hw4programs/tc20.oat diff --git a/hw4/oatprograms/tc3.oat b/hw4/hw4programs/tc3.oat similarity index 100% rename from hw4/oatprograms/tc3.oat rename to hw4/hw4programs/tc3.oat diff --git a/hw4/oatprograms/tc4.oat b/hw4/hw4programs/tc4.oat similarity index 100% rename from hw4/oatprograms/tc4.oat rename to hw4/hw4programs/tc4.oat diff --git a/hw4/oatprograms/tc5.oat b/hw4/hw4programs/tc5.oat similarity index 100% rename from hw4/oatprograms/tc5.oat rename to hw4/hw4programs/tc5.oat diff --git a/hw4/oatprograms/tc6.oat b/hw4/hw4programs/tc6.oat similarity index 100% rename from hw4/oatprograms/tc6.oat rename to hw4/hw4programs/tc6.oat diff --git a/hw4/oatprograms/tc7.oat b/hw4/hw4programs/tc7.oat similarity index 100% rename from hw4/oatprograms/tc7.oat rename to hw4/hw4programs/tc7.oat diff --git a/hw4/oatprograms/tc8.oat b/hw4/hw4programs/tc8.oat similarity index 100% rename from hw4/oatprograms/tc8.oat rename to hw4/hw4programs/tc8.oat diff --git a/hw4/oatprograms/tc9.oat b/hw4/hw4programs/tc9.oat similarity index 100% rename from hw4/oatprograms/tc9.oat rename to hw4/hw4programs/tc9.oat diff --git a/hw4/oatprograms/tc_ok1.oat b/hw4/hw4programs/tc_ok1.oat similarity index 100% rename from hw4/oatprograms/tc_ok1.oat rename to hw4/hw4programs/tc_ok1.oat diff --git a/hw4/oatprograms/tc_ok2.oat b/hw4/hw4programs/tc_ok2.oat similarity index 100% rename from hw4/oatprograms/tc_ok2.oat rename to hw4/hw4programs/tc_ok2.oat diff --git a/hw4/oatprograms/tc_ok4.oat b/hw4/hw4programs/tc_ok4.oat similarity index 100% rename from hw4/oatprograms/tc_ok4.oat rename to hw4/hw4programs/tc_ok4.oat diff --git a/hw4/oatprograms/tc_ok5.oat b/hw4/hw4programs/tc_ok5.oat similarity index 100% rename from hw4/oatprograms/tc_ok5.oat rename to hw4/hw4programs/tc_ok5.oat diff --git a/hw4/oatprograms/tc_ok6.oat b/hw4/hw4programs/tc_ok6.oat similarity index 100% rename from hw4/oatprograms/tc_ok6.oat rename to hw4/hw4programs/tc_ok6.oat diff --git a/hw4/oatprograms/tc_ok7.oat b/hw4/hw4programs/tc_ok7.oat similarity index 100% rename from hw4/oatprograms/tc_ok7.oat rename to hw4/hw4programs/tc_ok7.oat diff --git a/hw4/oatprograms/tc_ok8.oat b/hw4/hw4programs/tc_ok8.oat similarity index 100% rename from hw4/oatprograms/tc_ok8.oat rename to hw4/hw4programs/tc_ok8.oat diff --git a/hw4/oatprograms/toascii.oat b/hw4/hw4programs/toascii.oat similarity index 98% rename from hw4/oatprograms/toascii.oat rename to hw4/hw4programs/toascii.oat index 57478c2..8c93026 100644 --- a/hw4/oatprograms/toascii.oat +++ b/hw4/hw4programs/toascii.oat @@ -4,6 +4,8 @@ prints a simple ascii representation of the colors. Optimized for light-text-on-dark-background terminals (inverts the colors), and subsamples the height by .5 to better maintain aspect ratio of square files. + + -- John Hewitt, CIS 341 2017sp */ int program (int argc, string[] argv) { diff --git a/hw4/oatprograms/toposort.oat b/hw4/hw4programs/toposort.oat similarity index 94% rename from hw4/oatprograms/toposort.oat rename to hw4/hw4programs/toposort.oat index 94ecac0..20b2245 100644 --- a/hw4/oatprograms/toposort.oat +++ b/hw4/hw4programs/toposort.oat @@ -1,3 +1,6 @@ +/* Sumit Shyamsukha (ssumit) and Robert Zajac (rzajac) */ +/* CIS341 Spring 2017 */ + /* 0 is white, 1 is gray, 2 is black */ global color = int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; global startTimes = int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; @@ -48,4 +51,4 @@ int program(int argc, string[] argv) { } print_string ("-"); return 0; -} +} \ No newline at end of file diff --git a/hw4/oatprograms/union_find.oat b/hw4/hw4programs/union_find.oat similarity index 100% rename from hw4/oatprograms/union_find.oat rename to hw4/hw4programs/union_find.oat diff --git a/hw4/oatprograms/xor_bool.oat b/hw4/hw4programs/xor_bool.oat similarity index 100% rename from hw4/oatprograms/xor_bool.oat rename to hw4/hw4programs/xor_bool.oat diff --git a/hw4/oatprograms/xor_shift.oat b/hw4/hw4programs/xor_shift.oat similarity index 100% rename from hw4/oatprograms/xor_shift.oat rename to hw4/hw4programs/xor_shift.oat diff --git a/hw4/lib/ll/dune b/hw4/lib/ll/dune new file mode 100644 index 0000000..74784a5 --- /dev/null +++ b/hw4/lib/ll/dune @@ -0,0 +1,7 @@ +(library + (name ll) + (modules ll llutil lllexer llparser llinterp) + (wrapped false)) + +(ocamllex lllexer) +(menhir (modules llparser)) diff --git a/hw4/ll/ll.ml b/hw4/lib/ll/ll.ml similarity index 90% rename from hw4/ll/ll.ml rename to hw4/lib/ll/ll.ml index 9cd2ff8..3b7ddfd 100644 --- a/hw4/ll/ll.ml +++ b/hw4/lib/ll/ll.ml @@ -94,5 +94,7 @@ type ginit = type gdecl = ty * ginit (* LLVMlite Programs *) -type prog = { tdecls : (tid * ty) list; gdecls : (gid * gdecl) list; - fdecls : (gid * fdecl) list; edecls : (gid * ty) list } +type prog = { tdecls : (tid * ty) list; + gdecls : (gid * gdecl) list; + fdecls : (gid * fdecl) list; + edecls : (gid * ty) list } diff --git a/hw4/ll/llinterp.ml b/hw4/lib/ll/llinterp.ml similarity index 92% rename from hw4/ll/llinterp.ml rename to hw4/lib/ll/llinterp.ml index 2e2388b..3fd39a1 100644 --- a/hw4/ll/llinterp.ml +++ b/hw4/lib/ll/llinterp.ml @@ -44,7 +44,7 @@ let mval_of_gdecl (gd:gdecl) : mval = let rec mtree_of_gdecl : gdecl -> mtree = function | ty, GNull -> MWord (VPtr (ty, NullId, [0])) | ty, GGid g -> MWord (VPtr (ty, GlobId g, [0])) - | _, GBitcast (t1, v,t2) -> mtree_of_gdecl (t1, v) + | _, GBitcast (t1, v, _) -> mtree_of_gdecl (t1, v) | _, GInt i -> MWord (VInt i) | _, GString s -> MStr s | _, GArray gs @@ -56,7 +56,7 @@ let mval_of_ty (nt:tid -> ty) (t:ty) : mval = let rec mtree_of_ty : ty -> mtree = function | I1 | I8 | I64 | Ptr _ -> MWord VUndef | Array (n, I8) -> MStr (String.make n '\x00') - | Array (n, t) -> MNode Array.(make n (MWord VUndef) |> to_list) + | Array (n, _t) -> MNode Array.(make n (MWord VUndef) |> to_list) | Struct ts -> MNode (List.map mtree_of_ty ts) | Fun _ | Void -> failwith "mval_of_ty: mval for bad type" | Namedt id -> mtree_of_ty (nt id) @@ -139,7 +139,8 @@ let interp_i1 : sval -> bool = function let rec interp_operand (nt:tid -> ty) (locs:locals) (ty:ty) (o:operand) : sval = match ty, o with - | I64, Const i -> VInt i + | I64, Const i + | I1, Const i -> VInt i | Ptr ty, Null -> VPtr (ty, NullId, [0]) | Ptr ty, Gid g -> VPtr (ty, GlobId g, [0]) | _, Id u -> locs u @@ -183,7 +184,7 @@ let rec load_idxs (m:mval) (idxs:idx list) : mtree = match idxs', List.nth m i with | [], mt -> mt | [0], MStr s -> MStr s (* [n x i8]* %p and gep [n x i8]* %p, 0, 0 alias *) - | _, MWord v -> failwith "load_idxs: attempted to index into word" + | _, MWord _ -> failwith "load_idxs: attempted to index into word" | _, MStr _ -> failwith "load_idxs: attempted to index into string" | _, MNode m' -> load_idxs m' idxs' @@ -195,7 +196,7 @@ let rec store_idxs (m:mval) (idxs:idx list) (mt:mtree) : mval = if len <= i || i < 0 then raise OOBIndexDeref else match idxs', List.nth m i with | [], _ -> replace_nth m i mt - | _, MWord v -> failwith "store_idxs: attempted to index into word" + | _, MWord _ -> failwith "store_idxs: attempted to index into word" | _, MStr _ -> failwith "store_idxs: attempted to index into string" | _, MNode m' -> replace_nth m i @@ MNode (store_idxs m' idxs' mt) @@ -242,7 +243,7 @@ let effective_tag (nt:tid -> ty) (tag, _, idxs :ptr) : ty = | Struct ts, i::idxs' -> if List.length ts <= i then failwith "effective_tag: index oob of struct" else loop (List.nth ts i) idxs' - | Array (n, t), i::idxs' -> loop t idxs' (* Don't check if OOB! *) + | Array (_, t), _::idxs' -> loop t idxs' (* Don't check if OOB! *) | Namedt id, _ -> loop (nt id) idxs | _, _::_ -> failwith "effective_tag: index into non-aggregate" in @@ -274,13 +275,13 @@ let legal_gep (nt:tid -> ty) (sty:ty) (tag:ty) : bool = let gep_ptr (nt:tid -> ty) (ot:ty) (p:ptr) (idxs':idx list) : sval = if not (legal_gep nt ot @@ effective_tag nt p) then VUndef else match p with - | t, NullId, idxs -> VUndef + | _t, NullId, _idxs -> VUndef | t, bid, idxs -> VPtr (t, bid, gep_idxs idxs idxs') (* LLVMlite reference interpreter *) -let interp_prog {tdecls; gdecls; fdecls} (args:string list) : sval = +let interp_prog {tdecls; gdecls; fdecls; _} (args:string list) : sval = let globals = List.map (fun (g,gd) -> g,mval_of_gdecl gd) gdecls in @@ -289,6 +290,12 @@ let interp_prog {tdecls; gdecls; fdecls} (args:string list) : sval = with Not_found -> failwith @@ "interp_prog: undefined named type " ^ id in + let rec effective_type t = + match t with + | Namedt id -> effective_type (nt id) + | _ -> t + in + let interp_op = interp_operand nt in let next_id : unit -> fid = @@ -318,7 +325,7 @@ let interp_prog {tdecls; gdecls; fdecls} (args:string list) : sval = let mv = [MStr (s1 ^ s2)] in let heap = (mid, mv)::c.heap in {c with heap}, VPtr (t, HeapId mid, [0]) - | I64, "ll_ltoa", [VInt i; VPtr dst] -> + | I64, "ll_ltoa", [VInt i; VPtr _dst] -> let mid = next_id () in let mv = [MStr (Int64.to_string i)] in let heap = (mid, mv)::c.heap in @@ -327,7 +334,7 @@ let interp_prog {tdecls; gdecls; fdecls} (args:string list) : sval = in - (* Interprety the body of a function *) + (* Interpret the body of a function *) let rec interp_cfg (k, blocks:cfg) (locs:locals) (c:config) : config * sval = match k.insns, k.term with @@ -358,7 +365,7 @@ let interp_prog {tdecls; gdecls; fdecls} (args:string list) : sval = | (u, Load (Ptr t, o))::insns, _ -> let mt = match interp_op locs (Ptr t) o with | VPtr p -> - if effective_tag nt p <> t + if effective_type (effective_tag nt p) <> effective_type t then raise IncompatTagDeref else load_ptr c p | VUndef -> raise UndefPtrDeref @@ -377,7 +384,7 @@ let interp_prog {tdecls; gdecls; fdecls} (args:string list) : sval = let vd = interp_op locs (Ptr t) od in let c' = match vd with | VPtr p -> - if effective_tag nt p <> t + if effective_type (effective_tag nt p) <> effective_type t then raise IncompatTagDeref else store_ptr c p (MWord vs) | VUndef -> raise UndefPtrDeref @@ -402,7 +409,8 @@ let interp_prog {tdecls; gdecls; fdecls} (args:string list) : sval = let locs' = update locs u v in interp_cfg ({k with insns}, blocks) locs' c - | (u, Gep (Ptr t, o, os))::insns, _ -> + | (u, Gep (ty, o, os))::insns, _ -> + let t = dptr tdecls ty in let idx_of_sval : sval -> idx = function | VInt i -> Int64.to_int i | _ -> failwith "idx_of_sval: non-integer value" @@ -412,7 +420,7 @@ let interp_prog {tdecls; gdecls; fdecls} (args:string list) : sval = let v' = match interp_op locs (Ptr t) o with | VPtr p -> gep_ptr nt t p idxs' | VUndef -> VUndef - | VInt _ -> failwith "non-ptr arg for gep" + | VInt _ -> failwith @@ "non-ptr arg for gep" ^ sot t in let locs' = update locs u v' in interp_cfg ({k with insns}, blocks) locs' c @@ -434,14 +442,14 @@ let interp_prog {tdecls; gdecls; fdecls} (args:string list) : sval = interp_cfg (k', blocks) locs c | (u,i)::_, _ -> failwith @@ "interp_cfg: invalid instruction \"" - ^ string_of_insn i ^ "\" at %" ^ u + ^ string_of_insn tdecls i ^ "\" at %" ^ u and interp_call (ty:ty) (fn:gid) (args:sval list) (c:config) : config * sval = if List.mem fn runtime_fns then runtime_call ty fn args c else - let {f_param; f_cfg} = try List.assoc fn fdecls - with Not_found -> failwith @@ "interp_call: undefined function " ^ fn + let {f_param; f_cfg; _} = try List.assoc fn fdecls + with Not_found -> failwith @@ "interp_call: undefined function " ^ fn in if List.(length f_param <> length args) then failwith @@ "interp_call: wrong no. arguments for " ^ fn; diff --git a/hw4/ll/lllexer.mll b/hw4/lib/ll/lllexer.mll similarity index 91% rename from hw4/ll/lllexer.mll rename to hw4/lib/ll/lllexer.mll index 2fbacba..83a3465 100644 --- a/hw4/ll/lllexer.mll +++ b/hw4/lib/ll/lllexer.mll @@ -1,5 +1,4 @@ -{ open Lexing - open Llparser +{ open Llparser exception SyntaxError of string } @@ -16,7 +15,8 @@ rule token = parse | eof { EOF } | whitespace+ { token lexbuf } | newline+ { token lexbuf } - | "c\"" { read_string (Buffer.create 17) lexbuf } + | "\"" { read_string (Buffer.create 16) lexbuf } + | "c\"" { read_string (Buffer.create 16) lexbuf } | '*' { STAR } | ',' { COMMA } | ':' { COLON } @@ -65,6 +65,8 @@ rule token = parse | "external" { EXTERNAL } | "alloca" { ALLOCA } | "bitcast" { BITCAST } + | "target" { TARGET } + | "triple" { TRIPLE } | '%' ('.' ?) (identifier as i) { UID i } | '@' ('.' ?) (identifier as i) { GID i } | "x" { CROSS } (* for Array types *) @@ -76,6 +78,7 @@ rule token = parse and read_string buf = parse | '\\' "00" '"' { STRING (Buffer.contents buf) } + | '"' { STRING (Buffer.contents buf) } | '\\' { Buffer.add_char buf '\\'; read_string buf lexbuf } | [^ '"' '\\']+ { Buffer.add_string buf (Lexing.lexeme lexbuf) ; read_string buf lexbuf } diff --git a/hw4/ll/llparser.mly b/hw4/lib/ll/llparser.mly similarity index 96% rename from hw4/ll/llparser.mly rename to hw4/lib/ll/llparser.mly index ca28340..4b70a84 100644 --- a/hw4/ll/llparser.mly +++ b/hw4/lib/ll/llparser.mly @@ -56,6 +56,8 @@ %token ALLOCA (* alloca *) %token BITCAST (* bitcast *) %token GEP (* getelementptr *) +%token TARGET (* target *) +%token TRIPLE (* triple *) %token INT (* int64 values *) %token LBL (* labels *) @@ -89,6 +91,11 @@ decls_rev: { { ds with tdecls = t :: ds.tdecls } } | ds=decls_rev e=edecl { { ds with edecls = e :: ds.edecls } } + | ds=decls_rev ttdecl + { ds } + +ttdecl: + TARGET TRIPLE EQUALS STRING {} fdecl: | DEFINE t=ty l=GID LPAREN a=arg_list RPAREN @@ -134,6 +141,8 @@ ty: { t } ty_list_rev: + | (* empty *) + { [] } | t=ty { [t] } | ts=ty_list_rev COMMA t=ty @@ -252,7 +261,7 @@ insn: { (u, Alloca t) } | u=UID EQUALS LOAD ty COMMA t=ty o=operand { (u, Load (t,o)) } - | STORE t1=ty o1=operand COMMA t2=ty o2=operand + | STORE t1=ty o1=operand COMMA _t2=ty o2=operand { (gensym "store", Store (t1,o1,o2)) } | u=UID EQUALS ICMP c=cnd t=ty o1=operand COMMA o2=operand { (u, Icmp (c,t,o1,o2)) } diff --git a/hw4/ll/llutil.ml b/hw4/lib/ll/llutil.ml similarity index 74% rename from hw4/ll/llutil.ml rename to hw4/lib/ll/llutil.ml index 044d536..c487b9b 100644 --- a/hw4/ll/llutil.ml +++ b/hw4/lib/ll/llutil.ml @@ -20,9 +20,12 @@ let rec string_of_ty : ty -> string = function let sot = string_of_ty -let dptr = function +let rec dptr tdecls = function | Ptr t -> t - | _ -> failwith "PP: expected pointer type" + | Namedt id -> + (try dptr tdecls (List.assoc id tdecls) + with Not_found -> failwith @@ "dptr: undefined named type " ^ id) + | t -> failwith @@ "PP: expected pointer type, got " ^ (sot t) let string_of_operand : operand -> string = function | Null -> "null" @@ -48,11 +51,12 @@ let string_of_gep_index : operand -> string = function | Const i -> "i32 " ^ Int64.to_string i | o -> "i64 " ^ soo o -let string_of_insn : insn -> string = function +let string_of_insn (tdecls:(tid * ty) list) (i:insn) : string = + match i with | Binop (b, t, o1, o2) -> pp "%s %s %s, %s" (string_of_bop b) (sot t) (soo o1) (soo o2) | Alloca t -> pp "alloca %s" (sot t) - | Load (t, o) -> pp "load %s, %s %s" (sot (dptr t)) (sot t) (soo o) + | Load (t, o) -> pp "load %s, %s %s" (sot (dptr tdecls t)) (sot t) (soo o) | Store (t, os, od) -> pp "store %s %s, %s %s" (sot t) (soo os) (sot (Ptr t)) (soo od) | Icmp (c, t, o1, o2) -> pp "icmp %s %s %s, %s" @@ -60,13 +64,13 @@ let string_of_insn : insn -> string = function | Call (t, o, oa) -> pp "call %s %s(%s)" (sot t) (soo o) (mapcat ", " soop oa) | Bitcast (t1, o, t2) -> pp "bitcast %s %s to %s" (sot t1) (soo o) (sot t2) - | Gep (t, o, oi) -> pp "getelementptr %s, %s %s, %s" (sot (dptr t)) (sot t) (soo o) + | Gep (t, o, oi) -> pp "getelementptr %s, %s %s, %s" (sot (dptr tdecls t)) (sot t) (soo o) (mapcat ", " string_of_gep_index oi) -let string_of_named_insn (u,i:uid * insn) : string = +let string_of_named_insn (tdecls:(tid * ty) list) (u,i:uid * insn) : string = match i with - | Store _ | Call (Void, _, _) -> string_of_insn i - | _ -> pp "%%%s = %s" u (string_of_insn i) + | Store _ | Call (Void, _, _) -> string_of_insn tdecls i + | _ -> pp "%%%s = %s" u (string_of_insn tdecls i) let string_of_terminator : terminator -> string = function | Ret (_, None) -> "ret void" @@ -74,26 +78,42 @@ let string_of_terminator : terminator -> string = function | Br l -> pp "br label %%%s" l | Cbr (o, l, m) -> pp "br i1 %s, label %%%s, label %%%s" (soo o) l m -let string_of_block (b:block) : string = - (mapcat "\n" (prefix " " string_of_named_insn) b.insns ^. "\n") +let string_of_block (tdecls:(tid * ty) list) (b:block) : string = + (mapcat "\n" (prefix " " (string_of_named_insn tdecls)) b.insns ^. "\n") ^ (prefix " " string_of_terminator) (snd b.term) -let string_of_cfg (e,bs:cfg) : string = - let string_of_named_block (l,b) = l ^ ":\n" ^ string_of_block b in - string_of_block e ^ "\n" ^. mapcat "\n" string_of_named_block bs +let string_of_cfg (tdecls:(tid * ty) list) (e,bs:cfg) : string = + let string_of_named_block (l,b) = l ^ ":\n" ^ string_of_block tdecls b in + string_of_block tdecls e ^ "\n" ^. mapcat "\n" string_of_named_block bs -let string_of_named_fdecl (g,f:gid * fdecl) : string = +let string_of_named_fdecl (tdecls:(tid * ty) list) (g,f:gid * fdecl) : string = let string_of_arg (t,u) = pp "%s %%%s" (sot t) u in let ts, t = f.f_ty in pp "define %s @%s(%s) {\n%s\n}\n" (sot t) g (mapcat ", " string_of_arg List.(combine ts f.f_param)) - (string_of_cfg f.f_cfg) + (string_of_cfg tdecls f.f_cfg) + + +(* Utility function to escape strings to use \hh encoding for various characters *) +let escape (s:string) : string = + let buf = Buffer.create (String.length s) in + let add_char c = + match c with + | '\n' -> Buffer.add_string buf "\\0A" + | '\t' -> Buffer.add_string buf "\\09" + | '\r' -> Buffer.add_string buf "\\0D" + | '"' -> Buffer.add_string buf "\\22" + | '\\' -> Buffer.add_string buf "\\5C" + | _ -> Buffer.add_char buf c + in + String.iter add_char s; + Buffer.contents buf let rec string_of_ginit : ginit -> string = function | GNull -> "null" | GGid g -> pp "@%s" g | GInt i -> Int64.to_string i - | GString s -> pp "c\"%s\\00\"" s + | GString s -> pp "c\"%s\\00\"" (escape s) | GArray gis -> pp "[ %s ]" (mapcat ", " string_of_gdecl gis) | GStruct gis -> pp "{ %s }" (mapcat ", " string_of_gdecl gis) | GBitcast (t1,g,t2) -> pp "bitcast (%s %s to %s)" (sot t1) (string_of_ginit g) (sot t2) @@ -116,8 +136,8 @@ let string_of_named_edecl (g,t:gid * ty) : string = let string_of_prog (p:prog) : string = (mapcat "\n" string_of_named_tdecl p.tdecls ^. "\n\n") ^ (mapcat "\n" string_of_named_gdecl p.gdecls ^. "\n\n") - ^ (mapcat "\n" string_of_named_fdecl p.fdecls ^. "\n\n") - ^ (mapcat "\n" string_of_named_edecl p.edecls) + ^ (mapcat "\n" (string_of_named_fdecl p.tdecls) p.fdecls ^. "\n\n") + ^ (mapcat "\n" string_of_named_edecl p.edecls) ^. "\n" (* comparison for testing ----------------------------------------------------- *) @@ -129,7 +149,7 @@ let compare_block (b:block) (c:block) : int = | Call (Void, _, _) -> "", i | _ -> u, i in - let del_term (u,t) = ("", t) + let del_term (_u,t) = ("", t) in Stdlib.compare {insns=List.map del_dummy b.insns; term=del_term b.term} diff --git a/hw4/lib/util/assert.ml b/hw4/lib/util/assert.ml new file mode 100644 index 0000000..8e326a0 --- /dev/null +++ b/hw4/lib/util/assert.ml @@ -0,0 +1,195 @@ +(* CIS341 Assertion Testing and Grading Infrastructure *) +(* Author: Steve Zdancewic *) + +(* Do NOT modify this file -- we will overwrite it *) +(* with our own version when testing your code. *) + +(* An assertion is just a unit->unit function that either *) +(* succeeds silently or throws an Failure exception. *) +type assertion = unit -> unit + +type 'a test = + | GradedTest of string * int * (string * 'a) list + | Test of string * (string * 'a) list + +type suite = assertion test list + +(**************) +(* Assertions *) + +let assert_eq v1 v2 : assertion = + fun () -> if v1 <> v2 then failwith "not equal" else () + + +let assert_eqf f v2 : assertion = + fun () -> if f () <> v2 then failwith "not equal" else () + + +let assert_eqfs f v2 : assertion = + fun () -> + let s1 = f () in + if s1 <> v2 + then failwith @@ Printf.sprintf "not equal\n\texpected:%s\n\tgot:%s\n" v2 s1 + else () + + +let assert_fail : assertion = fun () -> failwith "assert fail" + +exception Timeout + +let timeout_assert (time : int) (a : assertion) : assertion = + fun () -> + let handler = Sys.Signal_handle (fun _ -> raise Timeout) in + let old = Sys.signal Sys.sigalrm handler in + let reset_sigalrm () = Sys.set_signal Sys.sigalrm old in + ignore (Unix.alarm time) ; + try + a () ; + reset_sigalrm () + with + | Timeout -> + reset_sigalrm () ; + failwith @@ Printf.sprintf "Timed out after %d seconds" time + | exc -> + reset_sigalrm () ; + raise exc + + +let timeout_test (time : int) (t : assertion test) : assertion test = + let map_timeout l = List.map (fun (i, a) -> (i, timeout_assert time a)) l in + match t with + | GradedTest (s, i, ls) -> + GradedTest (s, i, map_timeout ls) + | Test (s, ls) -> + Test (s, map_timeout ls) + + +let timeout_suite (time : int) (s : suite) : suite = + List.map (timeout_test time) s + + +(***************************) +(* Generating Test Results *) + +type result = + | Pass + | Fail of string + +type outcome = result test list + +let run_assertion (f : assertion) : result = + try + f () ; + Pass + with + | Failure m -> + Fail m + | e -> + Fail ("test threw exception: " ^ Printexc.to_string e) + + +let run_test (t : assertion test) : result test = + let run_case (cn, f) = (cn, run_assertion f) in + match t with + | GradedTest (n, s, cases) -> + Printf.eprintf "Running test %s\n%!" n ; + GradedTest (n, s, List.map run_case cases) + | Test (n, cases) -> + Printf.eprintf "Running test %s\n%!" n ; + Test (n, List.map run_case cases) + + +let run_suite (s : suite) : outcome = List.map run_test s + +(***********************) +(* Reporting functions *) + +let result_test_to_string (name_pts : string) (r : result test) : string = + let string_of_case (name, res) = + match res with + | Pass -> + "passed - " ^ name + | Fail msg -> + "FAILED - " ^ name ^ ": " ^ msg + in + match r with + | GradedTest (_, _, cases) | Test (_, cases) -> + name_pts + ^ List.fold_left + (fun rest case -> rest ^ "\n" ^ string_of_case case) + "" + cases + + +(* Number of digits of precision for a float x. Argument p is the number of decimal places desired (must be at least 1) *) +let prec_digits p x = (int_of_float @@ floor @@ log10 x) + (1 + p) + +(* returns (name_pts, passed, failed, total, points_earned, max_given, max_hidden) *) +let get_results (t : result test) = + let num_passed cases = + List.fold_left + (fun cnt (_, r) -> match r with Pass -> cnt + 1 | _ -> cnt) + 0 + cases + in + let num_failed cases = + List.fold_left + (fun cnt (_, r) -> match r with Fail _ -> cnt + 1 | _ -> cnt) + 0 + cases + in + match t with + | GradedTest (name, pts, cases) -> + let passed = num_passed cases in + let failed = num_failed cases in + let total = List.length cases in + if total > 0 + then + let points_earned = ((float_of_int passed) /. (float_of_int total)) *. (float_of_int pts) in + let name_pts = + Printf.sprintf "%s (%1.*g/%d points = %d/%d tests)" name (prec_digits 1 points_earned) points_earned pts passed total + in + (name_pts, passed, failed, total, points_earned, pts, 0) + else + let name_pts = Printf.sprintf "%s (?/%d points)" name pts in + (name_pts, passed, failed, total, 0.0, 0, pts) + | Test (name, cases) -> + let total = List.length cases in + let passed = num_passed cases in + let failed = num_failed cases in + (name, passed, failed, total, 0.0, 0, 0) + + +let outcome_to_string (o : outcome) : string = + let sep = "\n---------------------------------------------------\n" in + let helper (passed, failed, total, pts, maxg, maxh, str) (t : result test) = + let name_pts, p, f, tot, s, mg, mh = get_results t in + ( passed + p + , failed + f + , total + tot + , s +. pts + , maxg + mg + , maxh + mh + , str + ^ "\n" + ^ + if f > 0 + then result_test_to_string name_pts t + else if tot > 0 + then name_pts ^ ":\n OK" + else name_pts ^ ":\n Hidden" ) + in + let p, f, tot, pts, maxg, maxh, str = + List.fold_left helper (0, 0, 0, 0.0, 0, 0, "") o + in + str + ^ sep + ^ Printf.sprintf + "Passed: %d/%d\n\ + Failed: %d/%d\n\ + Score: %1.1f/%d (given)\n\ + \ ?/%d (hidden)" + p tot + f tot + pts maxg + maxh diff --git a/hw4/util/assert.mli b/hw4/lib/util/assert.mli similarity index 91% rename from hw4/util/assert.mli rename to hw4/lib/util/assert.mli index 57926a3..9dfa6d0 100644 --- a/hw4/util/assert.mli +++ b/hw4/lib/util/assert.mli @@ -1,3 +1,6 @@ +(* CIS341 Assertion Testing and Grading Infrastructure *) +(* Author: Steve Zdancewic *) + (* Do NOT modify this file -- we will overwrite it *) (* with our own version when testing your code. *) diff --git a/hw4/lib/util/dune b/hw4/lib/util/dune new file mode 100644 index 0000000..aa0f522 --- /dev/null +++ b/hw4/lib/util/dune @@ -0,0 +1,3 @@ +(library + (name util) + (libraries str unix)) \ No newline at end of file diff --git a/hw4/util/platform.ml b/hw4/lib/util/platform.ml similarity index 83% rename from hw4/util/platform.ml rename to hw4/lib/util/platform.ml index 84c4a17..13a96a0 100644 --- a/hw4/util/platform.ml +++ b/hw4/lib/util/platform.ml @@ -9,8 +9,12 @@ exception PlatformError of string * string (* paths -------------------------------------------------------------------- *) let path_sep = "/" +let bin_path = "./bin" + let dot_path = "./" +let executable_name = ref "a.out" + let output_path = ref "output" let libs = ref [] @@ -21,8 +25,6 @@ let lib_search_paths = ref [] let include_paths = ref [] -let executable_name = ref "a.out" - (* unix utility scripts ----------------------------------------------------- *) let pp_cmd = ref "cpp -E " @@ -37,6 +39,11 @@ let os = let () = close_in ic in uname +let cpu = + let ic = Unix.open_process_in "uname -m" in + let cpuname = input_line ic in + let () = close_in ic in + cpuname (* One of "Darwin" or "Linux" *) @@ -102,13 +109,19 @@ let create_output_dir () = (* clang invocation stuff --------------------------------------------------- *) let common_flags = "-Wno-override-module" +let link_flags = "-Wno-unused-command-line-argument -mstackrealign" + let clang_ll_mode = "-S" let as_mode = "-c" +let rosetta_prefix = "arch -x86_64 " + +let prefix = if cpu = "arm64" then rosetta_prefix else "" + let opt_level = ref "-O1 -Wall" -let clang args = Printf.sprintf "clang %s -o " (String.concat " " args) +let clang args = Printf.sprintf "%sclang %s -o " prefix (String.concat " " args) let clang_cmd () = clang [ clang_ll_mode; !opt_level; common_flags; !platform_flags ] @@ -116,7 +129,7 @@ let clang_cmd () = let as_cmd () = clang [ as_mode; !opt_level; common_flags; !platform_flags ] -let link_cmd () = clang [ common_flags; !opt_level; !platform_flags ] +let link_cmd () = clang [ common_flags; !opt_level; !platform_flags; link_flags ] (* filename munging --------------------------------------------------------- *) let path_to_basename_ext (path : string) : string * string = @@ -148,6 +161,20 @@ let sh (cmd : string) (ret : string -> int -> 'a) : 'a = | WSTOPPED i -> raise (PlatformError (cmd, sprintf "Stopped with %d." i)) +(* Platform independent shell command with a timeout (in seconds) *) +let timeout_sh (time: int)(cmd : string) (ret : string -> int -> 'a) : 'a = + let timeout_cmd = sprintf "%s/timeout3 -t %d %s" bin_path time cmd in + verb (sprintf "* %s\n" timeout_cmd) ; + match system timeout_cmd with + | WEXITED i -> + ret cmd i + | WSIGNALED i -> + if i == Sys.sigterm + then raise (PlatformError (cmd, sprintf "Timed-out after %d s" time)) + else raise (PlatformError (cmd, sprintf "Signaled with %d." i)) + | WSTOPPED i -> + raise (PlatformError (cmd, sprintf "Stopped with %d." i)) + (* Generate a file name that does not already exist. basedir includes the path separator diff --git a/hw4/util/range.ml b/hw4/lib/util/range.ml similarity index 100% rename from hw4/util/range.ml rename to hw4/lib/util/range.ml diff --git a/hw4/util/range.mli b/hw4/lib/util/range.mli similarity index 100% rename from hw4/util/range.mli rename to hw4/lib/util/range.mli diff --git a/hw4/lib/x86/dune b/hw4/lib/x86/dune new file mode 100644 index 0000000..abab108 --- /dev/null +++ b/hw4/lib/x86/dune @@ -0,0 +1,3 @@ +(library + (name x86) + (modules x86)) diff --git a/hw4/x86/x86.ml b/hw4/lib/x86/x86.ml similarity index 95% rename from hw4/x86/x86.ml rename to hw4/lib/x86/x86.ml index 802ee18..514a5c5 100644 --- a/hw4/x86/x86.ml +++ b/hw4/lib/x86/x86.ml @@ -56,13 +56,13 @@ type prog = elem list (* Provide some syntactic sugar for writing x86 code in OCaml files. *) module Asm = struct - let (~$) i = Imm (Lit (Int64.of_int i)) (* int64 constants *) + let (~$) i = Imm (Lit (Int64.of_int i)) (* int64 constants *) let (~$$) l = Imm (Lbl l) (* label constants *) - let (~%) r = Reg r (* registers *) + let (~%) r = Reg r (* registers *) (* helper functions for building blocks of data or code *) - let data l ds = { lbl = l; global = true; asm = Data ds } - let text l is = { lbl = l; global = false; asm = Text is } + let data l ds = { lbl = l; global = true; asm = Data ds } + let text l is = { lbl = l; global = false; asm = Text is } let gtext l is = { lbl = l; global = true; asm = Text is } end @@ -127,7 +127,7 @@ let string_of_opcode : opcode -> string = function let map_concat s f l = String.concat s @@ List.map f l let string_of_shift op = function - | [ Imm i ; dst ] as args -> + | [ Imm _i ; _dst ] as args -> "\t" ^ string_of_opcode op ^ "\t" ^ map_concat ", " string_of_operand args | [ Reg Rcx ; dst ] -> Printf.sprintf "\t%s\t%%cl, %s" (string_of_opcode op) (string_of_operand dst) diff --git a/hw4/ll/ll-original.ml b/hw4/ll/ll-original.ml deleted file mode 100644 index c0acb18..0000000 --- a/hw4/ll/ll-original.ml +++ /dev/null @@ -1,81 +0,0 @@ -(* LLVMlite: A simplified subset of the LLVM IR *) - -type uid = string (* Local identifiers *) -type gid = string (* Global identifiers *) -type tid = string (* Named types *) -type lbl = string (* Labels *) - -(* LLVM IR types *) -type ty = - | Void (* mix of unit/bottom from C *) - | I1 | I8 | I64 (* integer types *) - | Ptr of ty (* t* *) - | Struct of ty list (* { t1, t2, ... , tn } *) - | Array of int * ty (* [ NNN x t ] *) - | Fun of fty (* t1, ..., tn -> tr *) - | Namedt of tid (* named type aliases *) - -(* Function type: argument types and return type *) -and fty = ty list * ty - -(* Syntactic Values *) -type operand = - | Null (* null pointer *) - | Const of int64 (* integer constant *) - | Gid of gid (* A global identifier *) - | Id of uid (* A local identifier *) - -(* Type-annotated operands *) - -(* Binary operations *) -type bop = Add | Sub | Mul | Shl | Lshr | Ashr | And | Or | Xor - -(* Comparison Operators *) -type cnd = Eq | Ne | Slt | Sle | Sgt | Sge - -(* Instructions *) -type insn = - | Binop of bop * ty * operand * operand (* bop ty %o1, %o2 *) - | Alloca of ty (* alloca ty *) - | Load of ty * operand (* load ty %u *) - | Store of ty * operand * operand (* store ty %t, ty* %u *) - | Icmp of cnd * ty * operand * operand (* icmp %s ty %s, %s *) - | Call of ty * operand * (ty * operand) list (* fn(%1, %2, ...) *) - | Bitcast of ty * operand * ty (* bitcast ty1 %u to ty2 *) - | Gep of ty * operand * operand list (* getelementptr ty* %u, i64 %vi, ... *) - -(* Block terminators *) -type terminator = - | Ret of ty * operand option (* ret i64 %s *) - | Br of lbl (* br label %lbl *) - | Cbr of operand * lbl * lbl (* br i1 %s, label %l1, label %l2 *) - -(* Basic blocks *) -type block = { insns: (uid * insn) list; terminator: uid * terminator } - -(* Control Flow Graph: a pair of an entry block and a set labeled blocks *) -type cfg = block * (lbl * block) list - -(* Function declarations *) -type fdecl = { fty: fty; param: uid list; cfg: cfg } - -(* Initializers for global data *) -type ginit = - | GNull (* null literal *) - | GGid of gid (* reference another global *) - | GInt of int64 (* global integer value *) - | GString of string (* constant global string *) - | GArray of gdecl list (* global array *) - | GStruct of gdecl list (* global struct *) - -(* Global declaration *) -and gdecl = ty * ginit - -(* LLVMlite programs *) -type prog = - { tdecls: (tid * ty) list (* named types *) - ; gdecls: (gid * gdecl) list (* global data *) - ; fdecls: (gid * fdecl) list (* code *) - ; edecls: (gid * ty) list (* external declarations *) - } - diff --git a/hw4/ll/llruntime.c b/hw4/ll/llruntime.c deleted file mode 100644 index 895fe36..0000000 --- a/hw4/ll/llruntime.c +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include -#include -#include - -/* TODO: if we enforce that all char literals are null-terminated, - and all allocated memory is zero-initialized, are these safe - when llvmlite program does not exhibit UB? */ - -void *ll_malloc(int64_t n, int64_t size) { - return calloc(n, size); -} - -int64_t ll_strlen(int8_t *s) { - return 0; -} - -int8_t *ll_strncopy(int8_t *dst, int8_t *src, int64_t i) { - int64_t src_size = ll_strlen(src); - int64_t dst_size = ll_strlen(dst); - if (i >= dst_size) - return dst; - else - return (int8_t*)strncpy((char *)dst + i, (char *)src, dst_size - i); -} - -void ll_puts(int8_t *s) { - puts((char *)s); -} - -int64_t ll_atol(int8_t *s) { - return atol((char *)s); -} - -int64_t ll_ltoa(int64_t i, int8_t *dst) { - int64_t size = ll_strlen(dst); - return snprintf((char *)dst, size, "%ld", (long)i); -} diff --git a/hw4/studenttests.ml b/hw4/studenttests.ml deleted file mode 100644 index 1ff347f..0000000 --- a/hw4/studenttests.ml +++ /dev/null @@ -1,10 +0,0 @@ -open Assert - -(* These tests are provided by you *) - -(* You should also add additional test cases here to help you *) -(* debug your program. *) - -let provided_tests : suite = [ - -] diff --git a/hw4/submit_zip_contents.txt b/hw4/submit_zip_contents.txt new file mode 100644 index 0000000..b47d67a --- /dev/null +++ b/hw4/submit_zip_contents.txt @@ -0,0 +1,3 @@ +bin/lexer.mll +bin/parser.mly +bin/frontend.ml diff --git a/hw4/test/dune b/hw4/test/dune new file mode 100644 index 0000000..04ead4b --- /dev/null +++ b/hw4/test/dune @@ -0,0 +1,17 @@ +(env + (dev + (flags + (:standard -g -w "+a-4-7-9-26-27-29-30-32..42-44-45-48-50-60-66..70") + ))) + +(library + (name studenttests) + (modules studenttests) + (libraries gradedtests util x86 ll oat)) + +(library + (name gradedtests) + (modules gradedtests progasts + ; + ) + (libraries util x86 ll oat)) diff --git a/hw4/gradedtests.ml b/hw4/test/gradedtests.ml similarity index 68% rename from hw4/gradedtests.ml rename to hw4/test/gradedtests.ml index f1b3d84..4db01d2 100644 --- a/hw4/gradedtests.ml +++ b/hw4/test/gradedtests.ml @@ -1,6 +1,7 @@ +open Oat open Ast open Astlib -open Assert +open Util.Assert open Driver (* Do NOT modify this file -- we will overwrite it with our *) @@ -50,7 +51,7 @@ let parse_exp_tests = ; ("parse exp test 17", exp_test "true [&] false | false [|] true & true" (no_loc (Bop (IOr,no_loc (Bop (IAnd,no_loc (CBool true),no_loc (Bop (Or,no_loc (CBool false),no_loc (CBool false))))),no_loc (Bop (And,no_loc (CBool true),no_loc (CBool true))))))) ; ("parse exp test 18", exp_test "true [|] false [&] true & true | false" (no_loc (Bop (IOr,no_loc (CBool true),no_loc (Bop (IAnd,no_loc (CBool false),no_loc (Bop (Or,no_loc (Bop (And,no_loc (CBool true),no_loc (CBool true))),no_loc (CBool false))))))))) ; ("parse exp test 19", exp_test "new int[3]" (no_loc (NewArr (TInt,no_loc (CInt 3L))))) - ; ("parse exp test 20", exp_test "bar (x, \"compilerdesign\")" (no_loc (Call (no_loc (Id "bar"), [ no_loc (Id ("x")) ; no_loc (CStr "compilerdesign") ])))) + ; ("parse exp test 20", exp_test "bar (x, \"cis341\")" (no_loc (Call (no_loc (Id "bar"), [ no_loc (Id ("x")) ; no_loc (CStr "cis341") ])))) ; ("parse exp test 21", exp_test "new int[3]" (no_loc (NewArr (TInt,no_loc (CInt 3L))))) ; ("parse exp test 22", exp_test "new int[][]{new int[]{10,11},new int[]{20,21},new int[]{30,31}}" (no_loc (CArr (TRef (RArray TInt), [ no_loc (CArr (TInt, [ no_loc (CInt 10L) ; no_loc (CInt 11L) ])) ; no_loc (CArr (TInt, [ no_loc (CInt 20L) ; no_loc (CInt 21L) ])) ; no_loc (CArr (TInt, [ no_loc (CInt 30L) ; no_loc (CInt 31L) ])) ])))) ; ("parse exp test 23", exp_test "proc1 ()" (no_loc (Call (no_loc (Id "proc1"), [ ])))) @@ -82,13 +83,13 @@ let parse_file_test filepath ast = assert_eq_ast Astlib.eq_prog string_of_prog ast (fun () -> Driver.parse_oat_file filepath) let parse_prog_tests = - [ ("parse prog test 1", parse_file_test "oatprograms/easy_p1.oat" Progasts.easy_p1_ast) - ; ("parse prog test 2", parse_file_test "oatprograms/easy_p2.oat" Progasts.easy_p2_ast) - ; ("parse prog test 3", parse_file_test "oatprograms/easy_p3.oat" Progasts.easy_p3_ast) - ; ("parse prog test 4", parse_file_test "oatprograms/easy_p4.oat" Progasts.easy_p4_ast) - ; ("parse prog test 5", parse_file_test "oatprograms/easy_p5.oat" Progasts.easy_p5_ast) - ; ("parse prog test 6", parse_file_test "oatprograms/easy_p6.oat" Progasts.easy_p6_ast) - ; ("parse prog test 7", parse_file_test "oatprograms/easy_p7.oat" Progasts.easy_p7_ast) + [ ("parse prog test 1", parse_file_test "hw4programs/easy_p1.oat" Progasts.easy_p1_ast) + ; ("parse prog test 2", parse_file_test "hw4programs/easy_p2.oat" Progasts.easy_p2_ast) + ; ("parse prog test 3", parse_file_test "hw4programs/easy_p3.oat" Progasts.easy_p3_ast) + ; ("parse prog test 4", parse_file_test "hw4programs/easy_p4.oat" Progasts.easy_p4_ast) + ; ("parse prog test 5", parse_file_test "hw4programs/easy_p5.oat" Progasts.easy_p5_ast) + ; ("parse prog test 6", parse_file_test "hw4programs/easy_p6.oat" Progasts.easy_p6_ast) + ; ("parse prog test 7", parse_file_test "hw4programs/easy_p7.oat" Progasts.easy_p7_ast) ] let parse_tests = parse_consts @@ -108,7 +109,7 @@ let oat_file_test path args = 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 () = Platform.link (dot_ll_file::["bin/runtime.c"]) exec_file in let result = Driver.run_program_error 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 *) @@ -121,144 +122,155 @@ let executed_oat_file tests = tests let 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"); - ("oatprograms/easyrun10.oat", "", "254"); + ("hw4programs/easyrun1.oat", "", "17"); + ("hw4programs/easyrun2.oat", "", "35"); + ("hw4programs/easyrun3.oat", "", "73"); + ("hw4programs/easyrun4.oat", "", "6"); + ("hw4programs/easyrun5.oat", "", "212"); + ("hw4programs/easyrun6.oat", "", "9"); + ("hw4programs/easyrun7.oat", "", "23"); + ("hw4programs/easyrun8.oat", "", "160"); + ("hw4programs/easyrun9.oat", "", "236"); + ("hw4programs/easyrun10.oat", "", "254"); ] let 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"); - ("oatprograms/globals7.oat", "", "3"); + ("hw4programs/globals1.oat", "", "42"); + ("hw4programs/globals2.oat", "", "17"); + ("hw4programs/globals3.oat", "", "17"); + ("hw4programs/globals4.oat", "", "5"); + ("hw4programs/globals5.oat", "", "17"); + ("hw4programs/globals6.oat", "", "15"); + ("hw4programs/globals7.oat", "", "3"); ] let path_tests = [ - ("oatprograms/path1.oat", "", "17"); - ("oatprograms/path2.oat", "", "35"); - ("oatprograms/path3.oat", "", "3"); - ("oatprograms/arrayargs.oat", "", "17"); - ("oatprograms/arrayargs1.oat", "", "17"); - ("oatprograms/arrayargs2.oat", "", "17"); - ("oatprograms/arrayargs3.oat", "", "34"); + ("hw4programs/path1.oat", "", "17"); + ("hw4programs/path2.oat", "", "35"); + ("hw4programs/path3.oat", "", "3"); + ("hw4programs/arrayargs.oat", "", "17"); + ("hw4programs/arrayargs1.oat", "", "17"); + ("hw4programs/arrayargs2.oat", "", "17"); + ("hw4programs/arrayargs3.oat", "", "34"); ] let easy_tests = [ - ("oatprograms/run13.oat", "", "1"); - ("oatprograms/run21.oat", "", "99"); - ("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/run32.oat", "", "33"); - ("oatprograms/run33.oat", "", "1"); - ("oatprograms/run34.oat", "", "66"); - ("oatprograms/run35.oat", "", "66"); - ("oatprograms/run36.oat", "", "0"); - ("oatprograms/run37.oat", "", "2"); - ("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", "", "42"); - ("oatprograms/run61.oat", "", "420"); + ("hw4programs/argassign.oat", "", "18"); + ("hw4programs/run13.oat", "", "1"); + ("hw4programs/run21.oat", "", "99"); + ("hw4programs/run26.oat", "", "0"); + ("hw4programs/run27.oat", "", "99"); + ("hw4programs/run28.oat", "", "18"); + ("hw4programs/run29.oat", "", "1"); + ("hw4programs/run30.oat", "", "9"); + ("hw4programs/run31.oat", "", "9"); + ("hw4programs/run32.oat", "", "33"); + ("hw4programs/run33.oat", "", "1"); + ("hw4programs/run34.oat", "", "66"); + ("hw4programs/run35.oat", "", "66"); + ("hw4programs/run36.oat", "", "0"); + ("hw4programs/run37.oat", "", "2"); + ("hw4programs/run38.oat", "", "31"); + ("hw4programs/run39.oat", "a", "2"); + ("hw4programs/run40.oat", "", "8"); + ("hw4programs/run41.oat", "", "3"); + ("hw4programs/run42.oat", "", "2"); + ("hw4programs/run49.oat", "", "abc0"); + ("hw4programs/run50.oat", "", "abcde0"); + ("hw4programs/run60.oat", "", "85"); + ("hw4programs/run61.oat", "", "3410"); ] let medium_tests = [ - ("oatprograms/fact.oat", "", "1200"); - ("oatprograms/run1.oat", "", "153"); - ("oatprograms/run2.oat", "", "6"); - ("oatprograms/run3.oat", "", "2"); - ("oatprograms/run4.oat", "", "42"); - ("oatprograms/run5.oat", "", "4"); - ("oatprograms/run6.oat", "", "1"); - ("oatprograms/run7.oat", "", "20"); - ("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/run18.oat", "", "231"); - ("oatprograms/run19.oat", "", "231"); - ("oatprograms/run20.oat", "", "19"); - ("oatprograms/run22.oat", "", "abc0"); - ("oatprograms/run23.oat", "", "1230"); - ("oatprograms/run24.oat", "", "0"); - ("oatprograms/run25.oat", "", "nnn0"); - ("oatprograms/run43.oat", "", "42"); - ("oatprograms/run44.oat", "", "hello0"); - ("oatprograms/run45.oat", "", "420"); - ("oatprograms/run46.oat", "", "420"); - ("oatprograms/run47.oat", "", "3"); - ("oatprograms/run48.oat", "", "11"); - ("oatprograms/run53.oat", "", "nnn0"); - ("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"); + ("hw4programs/fact.oat", "", "1200"); + ("hw4programs/run1.oat", "", "153"); + ("hw4programs/run2.oat", "", "6"); + ("hw4programs/run3.oat", "", "2"); + ("hw4programs/run4.oat", "", "42"); + ("hw4programs/run5.oat", "", "4"); + ("hw4programs/run6.oat", "", "1"); + ("hw4programs/run7.oat", "", "20"); + ("hw4programs/run8.oat", "", "2"); + ("hw4programs/run9.oat", "", "4"); + ("hw4programs/run10.oat", "", "5"); + ("hw4programs/run11.oat", "", "7"); + ("hw4programs/run14.oat", "", "16"); + ("hw4programs/run15.oat", "", "19"); + ("hw4programs/run16.oat", "", "13"); + ("hw4programs/run18.oat", "", "231"); + ("hw4programs/run19.oat", "", "231"); + ("hw4programs/run20.oat", "", "19"); + ("hw4programs/run22.oat", "", "abc0"); + ("hw4programs/run23.oat", "", "1230"); + ("hw4programs/run24.oat", "", "0"); + ("hw4programs/run25.oat", "", "nnn0"); + ("hw4programs/run43.oat", "", "42"); + ("hw4programs/run44.oat", "", "hello0"); + ("hw4programs/run45.oat", "", "420"); + ("hw4programs/run46.oat", "", "420"); + ("hw4programs/run47.oat", "", "3"); + ("hw4programs/run48.oat", "", "11"); + ("hw4programs/run53.oat", "", "nnn0"); + ("hw4programs/lib4.oat", "", "53220"); + ("hw4programs/lib5.oat", "", "20"); + ("hw4programs/lib6.oat", "", "56553"); + ("hw4programs/lib7.oat", "", "53"); + ("hw4programs/lib8.oat", "", "Hello world!0"); + ("hw4programs/lib9.oat", "a b c d", "abcd5"); + ("hw4programs/lib11.oat", "", "45"); + ("hw4programs/lib14.oat", "", "~}|{zyxwvu0"); + ("hw4programs/lib15.oat", "123456789", "456780"); ] let 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"); +("hw4programs/fac.oat", "", "120"); +("hw4programs/qsort.oat", "", "kpyf{shomfhkmopsy{255"); +("hw4programs/bsort.oat", "", "y}xotnuw notuwxy}255"); +("hw4programs/msort.oat", "", "~}|{zyxwvu uvwxyz{|}~ 0"); +("hw4programs/msort2.oat", "", "~}|{zyxwvu uvwxyz{|}~ 0"); +("hw4programs/selectionsort.oat", "", "01253065992000"); +("hw4programs/matrixmult.oat", "", "19 16 13 23 \t5 6 7 6 \t19 16 13 23 \t5 6 7 6 \t0"); ] let 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/fibo.oat", "", "0") - ; ("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/gcd.oat", "", "16") - ; ("oatprograms/life.oat", "", "00101001100101000") - ; ("oatprograms/lcs.oat", "", "OAT0") - ; ("oatprograms/insertion_sort.oat", "", "42") - ; ("oatprograms/maxsubsequence.oat", "", "107") + ("hw4programs/binary_search.oat", "", "Correct!0") + ; ("hw4programs/xor_shift.oat", "", "838867572\n22817190600") + ; ("hw4programs/sieve.oat", "", "25") + ; ("hw4programs/count_sort.oat", "", "AFHZAAEYC\nAAACEFHYZ0") + ; ("hw4programs/fibo.oat", "", "0") + ; ("hw4programs/heap.oat", "", "1") + ; ("hw4programs/binary_gcd.oat", "", "3") + ; ("hw4programs/lfsr.oat", "", "TFTF FFTT0") + ; ("hw4programs/gnomesort.oat", "", "01253065992000") + ; ("hw4programs/josh_joyce_test.oat", "", "0") + ; ("hw4programs/gcd.oat", "", "16") + ; ("hw4programs/life.oat", "", "00101001100101000") + ; ("hw4programs/lcs.oat", "", "OAT0") + ; ("hw4programs/insertion_sort.oat", "", "42") + ; ("hw4programs/maxsubsequence.oat", "", "107") ] -let student_tests = [] let tests : suite = + List.map (Util.Assert.timeout_test 10) [ GradedTest("parse tests", 15, parse_tests); GradedTest("easiest tests", 15, executed_oat_file easiest_tests); - GradedTest("globals tests", 10, executed_oat_file globals_tests); + GradedTest("globals tests", 15, executed_oat_file globals_tests); GradedTest("path tests", 10, executed_oat_file path_tests); GradedTest("easy tests", 10, executed_oat_file easy_tests); GradedTest("medium tests", 10, executed_oat_file medium_tests); GradedTest("hard tests", 10, executed_oat_file (hard_tests @ old_student_tests)); - GradedTest("hidden tests", 20, executed_oat_file student_tests); + GradedTest("hidden tests", 5, [] ) ] -let graded_tests : suite = tests +let manual_tests : suite = + List.map (Util.Assert.timeout_test 10) + [ GradedTest ("Posted Public Test Case", 5, + [ ] + ); + GradedTest ("Other Student Public Tests", 5, + [ ] + ) +] + +let graded_tests : suite = tests @ manual_tests diff --git a/hw4/progasts.ml b/hw4/test/progasts.ml similarity index 97% rename from hw4/progasts.ml rename to hw4/test/progasts.ml index 6b7e4db..995a80f 100644 --- a/hw4/progasts.ml +++ b/hw4/test/progasts.ml @@ -1,8 +1,8 @@ -open Ast +open Oat.Ast let easy_p1_ast = [ Gfdecl (no_loc ({ frtyp = RetVal TInt; fname = "f"; args = [ ]; body = [ no_loc (Ret (Some (no_loc (CInt 0L)))) ] })) ] let easy_p2_ast = [ Gfdecl (no_loc ({ frtyp = RetVal TInt; fname = "f"; args = [ (TInt,"x") ]; body = [ no_loc (Decl ("x", no_loc (CInt 0L))) ; no_loc (Assn (no_loc (Id ("x")),no_loc (Bop (IOr,no_loc (Bop (Shl,no_loc (Bop (Shr,no_loc (Bop (Sub,no_loc (Bop (Add,no_loc (Id ("x")),no_loc (Id ("x")))),no_loc (Bop (Mul,no_loc (Id ("x")),no_loc (Id ("x")))))),no_loc (Id ("x")))),no_loc (Id ("x")))),no_loc (Bop (IAnd,no_loc (Id ("x")),no_loc (Bop (Sar,no_loc (Uop (Neg, no_loc (Uop (Bitnot, no_loc (Id ("x")))))),no_loc (Id ("x")))))))))) ; no_loc (Ret (Some (no_loc (Id ("x"))))) ] })) ] -let easy_p3_ast = [ Gfdecl (no_loc ({ frtyp = RetVal (TRef RString); fname = "bar"; args = [ (TInt,"x") ; (TRef RString,"y") ]; body = [ no_loc (Decl ("s",no_loc (CStr "This is a string"))) ; no_loc (Decl ("array", no_loc (CArr (TInt, [ no_loc (CInt 1L) ; no_loc (CInt 3L) ])))) ; no_loc (Decl ("y", no_loc (Index (no_loc (Id ("array")), no_loc (CInt 0L))))) ; no_loc (Ret (Some (no_loc (Id ("s"))))) ] })) ; Gfdecl (no_loc ({ frtyp = RetVoid; fname = "proc1"; args = [ ]; body = [ no_loc (SCall (no_loc (Id "proc2"), [])) ; no_loc (Ret (None)) ] })) ; Gfdecl (no_loc ({ frtyp = RetVoid; fname = "proc2"; args = [ ]; body = [ no_loc (SCall (no_loc (Id "proc1"), [ ])); no_loc (Ret (None)) ] })) ; Gfdecl (no_loc ({ frtyp = RetVal TBool; fname = "foo"; args = [ (TInt,"x") ; (TRef (RArray TInt),"y") ]; body = [ no_loc (Decl ("s", no_loc (Call (no_loc (Id "bar"), [ no_loc (Id ("x")) ; no_loc (CStr "compilerdesign") ])))) ; no_loc (SCall (no_loc (Id "proc1"), [ ])) ; no_loc (Ret (Some (no_loc (CBool true)))) ] })) ] +let easy_p3_ast = [ Gfdecl (no_loc ({ frtyp = RetVal (TRef RString); fname = "bar"; args = [ (TInt,"x") ; (TRef RString,"y") ]; body = [ no_loc (Decl ("s",no_loc (CStr "This is a string"))) ; no_loc (Decl ("array", no_loc (CArr (TInt, [ no_loc (CInt 1L) ; no_loc (CInt 3L) ])))) ; no_loc (Decl ("y", no_loc (Index (no_loc (Id ("array")), no_loc (CInt 0L))))) ; no_loc (Ret (Some (no_loc (Id ("s"))))) ] })) ; Gfdecl (no_loc ({ frtyp = RetVoid; fname = "proc1"; args = [ ]; body = [ no_loc (SCall (no_loc (Id "proc2"), [])) ; no_loc (Ret (None)) ] })) ; Gfdecl (no_loc ({ frtyp = RetVoid; fname = "proc2"; args = [ ]; body = [ no_loc (SCall (no_loc (Id "proc1"), [ ])); no_loc (Ret (None)) ] })) ; Gfdecl (no_loc ({ frtyp = RetVal TBool; fname = "foo"; args = [ (TInt,"x") ; (TRef (RArray TInt),"y") ]; body = [ no_loc (Decl ("s", no_loc (Call (no_loc (Id "bar"), [ no_loc (Id ("x")) ; no_loc (CStr "cis341") ])))) ; no_loc (SCall (no_loc (Id "proc1"), [ ])) ; no_loc (Ret (Some (no_loc (CBool true)))) ] })) ] let easy_p4_ast = [ Gfdecl (no_loc ({ frtyp = RetVal (TRef RString); fname = "f"; args = [ ]; body = [ no_loc (Decl ("s", no_loc (CArr (TRef (RArray (TRef RString)), [ no_loc (CArr (TRef RString, [ no_loc (CStr "s00:\n+\n=2*\n") ; no_loc (CStr "s01:this is not a comment in string.*") ; no_loc (CStr "s02:\"\\t\\n\\\\?\"") ])) ; no_loc (CArr (TRef RString, [ no_loc (CStr "s10:\133\134") ; no_loc (CStr "s11") ; no_loc (CStr "s12") ])) ])))) ; no_loc (Ret (Some (no_loc (Index (no_loc (Index (no_loc (Id ("s")), no_loc (CInt 0L))), no_loc (CInt 1L)))))) ] })) ; Gfdecl (no_loc ({ frtyp = RetVal (TRef (RArray (TRef (RArray TInt)))); fname = "g"; args = [ (TRef (RArray (TRef (RArray TInt))),"x") ]; body = [ no_loc (Decl ("y", no_loc (CArr (TRef (RArray TInt), [ no_loc (CArr (TInt, [ no_loc (CInt 0L) ; no_loc (CInt 1L) ])) ; no_loc (CArr (TInt, [ no_loc (CInt 2L) ; no_loc (CInt 3L) ])) ])))) ; no_loc (Decl ("i", no_loc (CInt 0L))) ; no_loc (Assn (no_loc (Index (no_loc (Index (no_loc (Id ("x")),no_loc (CInt 0L))) ,no_loc (CInt 0L))),no_loc (Bop (Add,no_loc (Id ("i")),no_loc (Index (no_loc (Index (no_loc (Id ("y")), no_loc (CInt 1L))), no_loc (CInt 1L))))))) ; no_loc (Assn (no_loc (Id ("i")),no_loc (Uop (Neg, no_loc (Uop (Lognot, no_loc (Uop (Bitnot, no_loc (Index (no_loc (Index (no_loc (Id ("x")), no_loc (CInt 0L))), no_loc (CInt 0L))))))))))) ; no_loc (Ret (Some (no_loc (Id ("x"))))) ] })) ] let easy_p5_ast = [ Gvdecl (no_loc { name="i"; init=no_loc (CInt 19L)}) ; Gvdecl (no_loc { name="b1"; init=no_loc (CBool true)}) ; Gvdecl (no_loc { name="b2"; init=no_loc (CBool false)}) ; Gvdecl (no_loc { name="str"; init=no_loc (CStr "This is a string!")}) ; Gvdecl (no_loc { name="arr1"; init=no_loc (CArr (TInt, [ no_loc (CInt 0L) ; no_loc (CInt 1L) ; no_loc (CInt 2L) ]))}) ; Gvdecl (no_loc { name="arr2"; init=no_loc (CArr (TRef (RArray TInt), [ no_loc (CArr (TInt, [ no_loc (CInt 10L) ; no_loc (CInt 11L) ])) ; no_loc (CArr (TInt, [ no_loc (CInt 20L) ; no_loc (CInt 21L) ])) ; no_loc (CArr (TInt, [ no_loc (CInt 30L) ; no_loc (CInt 31L) ])) ]))}) ; Gvdecl (no_loc { name="arr3"; init=no_loc (CArr (TRef RString, [ no_loc (CStr "String1") ; no_loc (CStr "String2") ; no_loc (CStr "String3") ]))}) ; Gvdecl (no_loc { name="arr4"; init=no_loc (CArr (TRef (RArray (TRef RString)), [ no_loc (CArr (TRef RString, [ no_loc (CStr "String00") ; no_loc (CStr "String01") ])) ; no_loc (CArr (TRef RString, [ no_loc (CStr "String10") ; no_loc (CStr "String11") ])) ; no_loc (CArr (TRef RString, [ no_loc (CStr "String20") ; no_loc (CStr "String21") ])) ]))}) ] let easy_p6_ast = [ Gvdecl (no_loc { name="y"; init=no_loc (CInt 0L)}) ; Gvdecl (no_loc { name="z"; init=no_loc (CInt 0L)}) ; Gfdecl (no_loc ({ frtyp = RetVoid; fname = "f"; args = [ (TInt,"x") ; (TInt,"y") ]; body = [ no_loc (Decl ("x", no_loc (CInt 0L))) ; no_loc (Ret (None)) ] })) ; Gfdecl (no_loc ({ frtyp = RetVoid; fname = "g"; args = [ (TInt,"x") ; (TInt,"y") ]; body = [ no_loc (Decl ("z", no_loc (CInt 0L) )) ; no_loc (Ret (None)) ] })) ] diff --git a/hw4/test/studenttests.ml b/hw4/test/studenttests.ml new file mode 100644 index 0000000..c2f923c --- /dev/null +++ b/hw4/test/studenttests.ml @@ -0,0 +1,12 @@ +open Util.Assert + +(* You should add additional test cases here to help you *) +(* debug your program. *) + +(* NOTE: Your "submitted public test case" belongs over in the + shared git submodule. +*) + +let provided_tests : suite = [ + +] diff --git a/hw4/util/assert.ml b/hw4/util/assert.ml deleted file mode 100644 index 6789b43..0000000 --- a/hw4/util/assert.ml +++ /dev/null @@ -1,160 +0,0 @@ -(* This code is mostly based on a course held at *) -(* University of Pennsylvania (CIS341) by Steve Zdancewic. *) - -(* Author: Steve Zdancewic *) -(* Modified by: Manuel Rigger *) -(* Modified by: Yann Girsberger *) - -(* Do NOT modify this file -- we will overwrite it *) -(* with our own version when testing your code. *) - - - -(* An assertion is just a unit->unit function that either *) -(* succeeds silently or throws an Failure exception. *) -type assertion = (unit -> unit) - -type 'a test = - | GradedTest of string * int * (string * 'a) list - | Test of string * (string * 'a) list - -type suite = (assertion test) list - - -(**************) -(* Assertions *) -exception Timeout - -let timeout_assert (time : int) (a : assertion) : assertion = - fun () -> - let handler = Sys.Signal_handle (fun _ -> raise Timeout) in - let old = Sys.signal Sys.sigalrm handler in - let reset_sigalrm () = Sys.set_signal Sys.sigalrm old in - ignore (Unix.alarm time); - try begin a (); reset_sigalrm () end - with Timeout -> reset_sigalrm (); failwith @@ Printf.sprintf "Timed out after %d seconds" time - | exc -> reset_sigalrm (); raise exc - -let timeout_test (time : int) (t : assertion test) : assertion test = - let map_timeout l = List.map (fun (i, a) -> (i, timeout_assert time a)) l in - match t with - | GradedTest (s, i, ls) -> GradedTest (s, i, map_timeout ls) - | Test (s, ls) -> Test (s, map_timeout ls) - -let timeout_suite (time : int) (s : suite) : suite = - List.map (timeout_test time) s - -let timeout_assert_const (a: assertion) : assertion = - timeout_assert 10 a - -let assert_eq v1 v2 : assertion = - timeout_assert_const (fun () -> if v1 <> v2 then failwith "not equal" else ()) - -let assert_eqf f v2 : assertion = - timeout_assert_const (fun () -> if (f ()) <> v2 then failwith "not equal" else ()) - -let assert_eqfs f v2 : assertion = - timeout_assert_const (fun () -> - let s1 = f () in - if s1 <> v2 then failwith @@ Printf.sprintf "not equal\n\texpected:%s\n\tgot:%s\n" v2 s1 - else ()) - - -let assert_fail : assertion = fun () -> failwith "assert fail" - - -(***************************) -(* Generating Test Results *) - -type result = - | Pass - | Fail of string - -type outcome = (result test) list - -let run_assertion (f:assertion) : result = - try - f (); - Pass - with - | Failure m -> Fail m - | e -> Fail ("test threw exception: " ^ (Printexc.to_string e)) - -let run_test (t:assertion test) : result test = - let run_case (cn, f) = (cn, run_assertion f) in - begin match t with - | GradedTest (n,s,cases) -> - Printf.eprintf "Running test %s\n%!" n; - GradedTest(n,s,List.map run_case cases) - - | Test (n, cases) -> - Printf.eprintf "Running test %s\n%!" n; - Test(n, List.map run_case cases) - end - -let run_suite (s:suite):outcome = - List.map run_test s - - - - - -(***********************) -(* Reporting functions *) - -let result_test_to_string (name_pts:string) (r:result test): string = - let string_of_case (name, res) = - begin match res with - | Pass -> "passed - " ^ name - | Fail msg -> "FAILED - " ^ name ^ ": " ^ msg - end - in - begin match r with - | GradedTest (_, _, cases) - | Test (_, cases) -> - name_pts ^ - (List.fold_left (fun rest -> fun case -> rest ^ "\n" ^ (string_of_case case)) "" cases) - end - -(* returns (name_pts, passed, failed, total, points_earned, max_given, max_hidden) *) -let get_results (t:result test) = - let num_passed cases = - List.fold_left (fun cnt (_,r) -> match r with Pass -> cnt + 1 | _ -> cnt) 0 cases in - let num_failed cases = - List.fold_left (fun cnt (_,r) -> match r with Fail _ -> cnt + 1 | _ -> cnt) 0 cases in - begin match t with - | GradedTest (name,pts,cases) -> - let passed = num_passed cases in - let failed = num_failed cases in - let total = List.length cases in - if total > 0 then - let points_earned = ((float_of_int passed) /. (float_of_int total)) *. (float_of_int pts) in - let name_pts = Printf.sprintf "%s (%1.f/%d points)" name points_earned pts in - (name_pts, passed, failed, total, points_earned, pts, 0) - else - let name_pts = Printf.sprintf "%s (?/%d points)" name pts in - (name_pts, passed, failed, total, 0.0, 0, pts) - | Test(name, cases) -> - let total = List.length cases in - let passed = num_passed cases in - let failed = num_failed cases in - (name, passed, failed, total, 0.0, 0, 0) - end - -let outcome_to_string (o:outcome):string = - let sep = "\n---------------------------------------------------\n" in - let helper (passed, failed, total, pts, maxg, maxh, str) (t:result test) = - let (name_pts, p, f, tot, s, mg, mh) = get_results t in - (passed + p, failed + f, total + tot, s +. pts, maxg + mg, maxh + mh, - str ^ "\n" ^ ( - if f > 0 then (result_test_to_string name_pts t) else - if tot > 0 then (name_pts ^ ":\n OK") else - (name_pts ^ ":\n Hidden") - ) - ) in - let (p,f,tot,pts,maxg, maxh,str) = List.fold_left helper (0,0,0,0.0,0,0,"") o in - str ^ sep ^ (Printf.sprintf "Passed: %d/%d\nFailed: %d/%d\nScore: %1.f/%d (given)\n ?/%d (hidden)" p tot f tot pts maxg maxh) - - - - diff --git a/hw4/x86/testX86.ml b/hw4/x86/testX86.ml deleted file mode 100644 index 1b23983..0000000 --- a/hw4/x86/testX86.ml +++ /dev/null @@ -1,34 +0,0 @@ -open X86 -open Cunit - -let hello_label = mk_lbl_named "hellostr" -let puts_label = mk_lbl_named "_puts" (* gcc on linux/mac uses _ to munge names *) - -let main_seq = [ - Push (esp); - Mov (ebp, esp); - - Add (esp, Imm (-8l)); (* Not sure why this has to be 8 *) - Mov (stack_offset 0l, Lbl hello_label); - Call (Lbl puts_label); - - Mov (esp, ebp); - Pop (ebp); - Ret -] - -let main_bb = { - (mk_insn_block (mk_lbl_named "_main") main_seq) with - global = true -} - -let hello_data = { - link = false; - label = (mk_lbl_named "hellostr"); - value = GStringz "Hello, world!" -} - -let cu = [Data hello_data; Code main_bb] - -let _ = - print_endline (string_of_cunit cu)