PA5

Run Settings
LanguageF#
Language Version
Run Command
(* Hope Crosier CPSC 3400 HW 5 All of the code you turn in must have been written by you without immediate reference to another solution to the problem you are solving. That means that you can look at other programs to see how someone solved a similar problem, but you shouldn't have any code written by someone else visible when you write yours (and you shouldn't have looked at a solution just a few seconds before you type!). You should compose the code you write based on your understanding of how the features of the language you are using can be used to implement the algorithm you have chosen to solve the problem you are addressing. Doing it this way is "real programming" - in contrast to just trying to get something to work by cutting and pasting stuff you don't actually understand. It is the only way to achieve the learning objectives of the course. I attest to the statement above *) /// Takes in a key x and a head value (y,z) to see if x and y are equal let checkChar (x: char) ((y,z): string*int) = let k = string(x) if k = y then true else false /// Takes in a head value (a,b) and returns only b let getChar ((a,b): string*int) = b /// takes a string and a list of bindings and returns the first value in the list /// bound to the key of the first character of the string let rec scanString (x: string) list = if list = [] then 0 else let hd :: tl = list // see if current hd values match key if (checkChar x.[0] hd) then // get the integer value from current hd getChar hd // otherwise ignore current hd and continue to rest of list else scanString x tl /// given a stack and an integer value, appends the integer onto the front of the stack let push stack x = x :: stack /// given a stack, pops the first value off the stack and returns it /// does not return the remaining stack since this function is intended to only /// be called when the expr has been fully evaluated let popAnswer stack = match stack with | [] -> -1 | hd :: tl -> hd /// given a stack, returns the top value and the remaining stack let pop stack = match stack with | [] -> (0, stack) | hd :: tl -> (hd, tl) /// given a stack, returns the top two values and the remaining stack let doublePop stack = match stack with | [] -> (0, 0, stack) //check not a number | hd1 :: hd2 :: tl -> (hd1, hd2, tl) /// given a list of variable bindings and a string expression, recursively evaluates the /// answer of the expression based on the symbols, letters, and appropriate bindings /// from the string expression let eval vars expr = let rec innerEval vars stack (expr: string) = if expr = "" then popAnswer stack else match expr.[0] with // if there is a space in the string, ignore it | ' ' -> innerEval vars stack expr.[1..] // create new binding based on value on top of stack | '@' -> let letter = string(expr.[1]) let num, newStack = pop stack let newVars = (letter,num)::vars innerEval newVars newStack expr.[2..] // swaps the position of the top two values on the stack | '$' -> let num1, num2, tempStack = doublePop stack let temp2Stack = push stack num1 let newStack = push temp2Stack num2 innerEval vars newStack expr.[1..] // adds the top two vales on the stack | '+' -> let (num1: int), (num2: int), tempStack = doublePop stack let newStack = push tempStack (num1 + num2) innerEval vars newStack expr.[1..] // subtracts the top two values on the stack | '-' -> let num1, num2, tempStack = doublePop stack let newStack = push tempStack (num2 - num1) innerEval vars newStack expr.[1..] // multiplies the top two values on the stack | '*' -> let num1, num2, tempStack = doublePop stack let newStack = push tempStack (num1 * num2) innerEval vars newStack expr.[1..] // divides the top two values on the stack | '/' -> let num1, num2, tempStack = doublePop stack let newStack = push tempStack (num1 / num2) innerEval vars newStack expr.[1..] // catch all case when there is a letter in the string to add matching value of // to stack | _ -> // add integer binding from character to stack innerEval vars (push stack (scanString expr vars)) expr.[1..] innerEval vars [] expr let testEval = eval [("a",5);("b",2);("c",9)] let exprList = [ "ca- @b bc$-"; "bbb @q bqbq*****"; "ab-ab*ab+--" ] let resultList = List.map testEval exprList printfn "%A" resultList
Editor Settings
Theme
Key bindings
Full width
Lines