-
Notifications
You must be signed in to change notification settings - Fork 5
/
coursework6.fsx
150 lines (106 loc) · 4.24 KB
/
coursework6.fsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
(*
ITT8060 -- Advanced Programming 2013
Department of Computer Science
Tallinn University of Technology
------------------------------------
Coursework 6: F# for .NET libraries
------------------------------------
Name:
Student ID:
------------------------------------
Answer the questions below. You answers to questions should be
correct F# code written after the question. This file is an F#
script file, it should be possible to load the whole file at
once. If you can't then you have introduced a syntax error
somewhere.
This coursework will be graded. When submitting the coursework,
call the file you submit "Lastname_Firstname.fsx" with your first
and last name appropriately, attach it to an e-mail with
subject line "[ITT8060] Coursework 6", and send it to
itt8060@cs.ttu.ee.
The coursework is due on November 1.
The task this week is to write a calculator (for integers and
addition) library to be used from .NET.
First you will build some of the internal components
*)
// We have defined two internal representations of arithmetic
// expressions, one is closed (contains no variables) and one is open
// (may contain variables)
open System
type CExp =
| CVal of int
| CAdd of CExp * CExp
type Exp =
| Val of int
| Var of string
| Add of Exp * Exp
// We have also provided a parser that converts string such as "1 + 2
// + 3 + x" into the internal representation of an expression
// (abstract syntax)
let tokenize (str:string) =
let value = str.Replace(" ", "")
let value = value.Replace("+", " + ")
value.Trim().Split([|' '|]) |> Seq.toList |> List.filter (fun e -> e.Length > 0)
let parseExp strexp =
let rec parseExpSub tokens =
match tokens with
| [] -> failwith "can't parse an expression"
| a :: [] ->
let b,r = Int32.TryParse a
match b with
| true -> Val r
| false -> Var a
| a::b::[] -> failwith "can't parse an expression"
| a::b::tail ->
match b with
| "+" ->
let b,r = Int32.TryParse a
match b with
| true -> Add (Val r, parseExpSub tail)
| false -> Add (Var a, parseExpSub tail)
| _ -> failwith "can't parse an expression"
parseExpSub (tokenize strexp)
// Now your turn!
//1) Implement a lookup function that looks up a variable in a lookup
// table (environment) represented as a list of pairs of variable names
// and values
let rec lookup (x : string)(env : (string * int) list) : int option = ?
// examples
lookup "x" [("x", 1); ("y", 2)]
// returns Some 1
lookup "z" [("x", 1); ("y", 2)]
// return None
// 2) Write a function that converts from open expressions to closed
// ones by replacing all variables with their values from the
// environment
let rec close (e : Exp)(env : (string * int) list) : CExp option = ?
// examples
close (Add (Var "x", Var "y")) [("x", 1); ("y", 2)]
// returns Some (CAdd (CVal 1,CVal 2))
close (Add (Var "x", Var "z")) [("x", 1); ("y", 2)]
// returns None
// 3) Write an evaluator that takes a (closed) expression and returns an int.
let rec eval (e : CExp) : int = ?
// example
eval (CAdd (CVal 1, CVal 2))
// returns 3
// Here is a calculator type which contains an environment and has
// some member functions which haven't been defined yet.
type Calc =
{ Env : (string * int) list}
// 4) write an Eval member that takes an expression and returns a pair
// of bool (whether it succeeds) and int (the calculated result)
member x.Eval (e : Exp) : bool * int = ?
// 5) write a greater than test that returns a pair of a bool
// (success/failure) and another bool (the result of the test)
member x.GreaterThan (e1 : Exp, e2 : Exp) : bool * bool = ?
// 6) write an update function that adds/updates a variable+value pair
// to the environment and returns a new Calc (recall that Calc is immutable)
member x.Update(y : string, i : int) : Calc = ?
// 7) write an evaluator that takes a string as input. (use provided parser)
member x.EvalString (e : string) : bool * int = ?
//examples
let str = "22 + value + 4 + y"
let calc = { Env = [("value", 1); ("y", 2)]}
calc.EvalString str
// 8) **BONUS** experiment with using your calculator library from C#.