This commit is contained in:
NikolajDanger
2022-06-09 12:41:00 +02:00
parent 5ff8dd409a
commit 7c20bc1c2c
5 changed files with 1 additions and 162 deletions

View File

@ -258,13 +258,6 @@ let rec compileExp (e : TypedExp)
let code2 = compileExp e2 vtable t2
code1 @ code2 @ [Mips.SUB (place,t1,t2)]
(* TODO project task 1:
Look in `AbSyn.fs` for the expression constructors `Times`, ...
`Times` is very similar to `Plus`/`Minus`.
For `Divide`, you may ignore division by zero for a quick first
version, but remember to come back and clean it up later.
`Not` and `Negate` are simpler; you can use `Mips.XORI` for `Not`
*)
| Times (e1, e2, pos) ->
let t1 = newReg "times_L"
let t2 = newReg "times_R"
@ -397,13 +390,6 @@ let rec compileExp (e : TypedExp)
let code2 = compileExp e2 vtable t2
code1 @ code2 @ [Mips.SLT (place,t1,t2)]
(* TODO project task 1:
Look in `AbSyn.fs` for the expression constructors of `And` and `Or`.
The implementation of `And` and `Or` is more complicated than `Plus`
because you need to ensure the short-circuit semantics, e.g.,
in `e1 || e2` if the execution of `e1` will evaluate to `true` then
the code of `e2` must not be executed. Similarly for `And` (&&).
*)
| And (e1, e2, pos) ->
let R0 = Mips.RS "0"
let label = newLab "false"
@ -589,31 +575,6 @@ let rec compileExp (e : TypedExp)
; Mips.LABEL loop_end
]
(* TODO project task 2:
`replicate (n, a)`
`filter (f, arr)`
`scan (f, ne, arr)`
Look in `AbSyn.fs` for the shape of expression constructors
`Replicate`, `Filter`, `Scan`.
General Hint: write down on a piece of paper the C-like pseudocode
for implementing them, then translate that to Mips pseudocode.
To allocate heap space for an array you may use `dynalloc` defined
above. For example, if `sz_reg` is a register containing an integer `n`,
and `ret_type` is the element-type of the to-be-allocated array, then
`dynalloc (sz_reg, arr_reg, ret_type)` will alocate enough space for
an n-element array of element-type `ret_type` (including the first
word that holds the length, and the necessary allignment padding), and
will place in register `arr_reg` the start address of the new array.
Since you need to allocate space for the result arrays of `Replicate`,
`Map` and `Scan`, then `arr_reg` should probably be `place` ...
`replicate(n,a)`: You should allocate a new (result) array, and execute a
loop of count `n`, in which you store the value hold into the register
corresponding to `a` into each memory location corresponding to an
element of the result array.
If `n` is less than `0` then remember to terminate the program with
an error -- see implementation of `iota`.
*)
| Replicate (n_exp, a_exp, a_type, (line, _)) ->
let a_size = getElemSize a_type
@ -668,21 +629,6 @@ let rec compileExp (e : TypedExp)
@ loop_replicate
@ loop_footer
(* TODO project task 2: see also the comment to replicate.
(a) `filter(f, arr)`: has some similarity with the implementation of map.
(b) Use `applyFunArg` to call `f(a)` in a loop, for every element `a` of `arr`.
(c) If `f(a)` succeeds (result in the `true` value) then (and only then):
- set the next element of the result array to `a`, and
- increment a counter (initialized before the loop)
(d) It is useful to maintain two array iterators: one for the input array `arr`
and one for the result array. (The latter increases slower because
some of the elements of the input array are skipped because they fail
under the predicate).
(e) The last step (after the loop writing the elments of the result array)
is to update the logical size of the result array to the value of the
counter computed in step (c). You do this of course with a
`Mips.SW(counter_reg, place, 0)` instruction.
*)
| Filter (farg, arr_exp, a_type, pos) ->
let size_reg = newReg "size_reg" (* size of input/output array *)
let arr_reg = newReg "arr_reg" (* address of array *)
@ -737,13 +683,6 @@ let rec compileExp (e : TypedExp)
@ loop_map
@ loop_footer
(* TODO project task 2: see also the comment to replicate.
`scan(f, ne, arr)`: you can inspire yourself from the implementation of
`reduce`, but in the case of `scan` you will need to also maintain
an iterator through the result array, and write the accumulator in
the current location of the result iterator at every iteration of
the loop.
*)
| Scan (farg, e_exp, arr_exp, a_type, pos) ->
let size_reg = newReg "size_reg" (* size of input/output array *)
let arr_reg = newReg "arr_reg" (* address of array *)