4.7 KiB
4.7 KiB
CMP-7009A Reassessment 001 - Interpreter + Maths Visualiser
How to open and run
- Open CMP7009A.sln in Visual Studio 2022 (with the ".NET desktop development" and "F# desktop language support" workloads installed).
- Set GUI as the startup project (right-click GUI project -> "Set as Startup Project").
- Press F5 to build and run. The
GUIproject referencesInterpreterdirectly (project reference), so both build together.
If you prefer the command line (with the .NET SDK installed):
dotnet build CMP7009A.sln
dotnet run --project GUI
Project layout
CMP7009A.sln
Interpreter/
Interpreter.fsproj F# class library
Interpreter.fs Tokenizer, parser, evaluator, public Engine class
GUI/
GUI.csproj C# WPF application (references Interpreter)
App.xaml / App.xaml.cs
MainWindow.xaml Input box, output box, drawing canvas
MainWindow.xaml.cs Wires the UI to Engine; draws axes and lines
Using the app
Type into the input box and press Enter or click Run:
3 + 4 x 2-> expression evaluation (xis multiplication) ->11a = 5-> assignment, output showsa = 5;ais remembereda x 2 + 1-> uses the stored variablea->11y = 2x + 1-> parsed as a line equation and drawn on the canvasy = x + 5-> coefficient defaults to 1y = -2x - 3-> negative coefficient/intercept supportedy = ax + b(afteraandbhave been assigned) -> uses their values
BNF grammar (for the report's Implementation section)
<statement> ::= <ident> "=" <expr> | <expr>
<expr> ::= <term> { ("+" | "-") <term> }
<term> ::= <factor> { ("x" | "/") <factor> }
<factor> ::= <number> | <ident> | "(" <expr> ")" | "-" <factor>
<number> ::= <integer> | <float>
<integer> ::= <digit> [<digit> [<digit>]] (1 to 3 digits)
<float> ::= <digit> [<digit>] "." <digit> [<digit>] (1-2 digits . 1-2 digits)
<ident> ::= <letter> [<alnum> [<alnum> [<alnum>]]] (max 4 characters)
<digit> ::= "0" | "1" | ... | "9"
<letter> ::= "a" | ... | "z" | "A" | ... | "Z"
<alnum> ::= <digit> | <letter>
Separate line-drawing syntax (parsed directly from raw characters in
Engine.ParseLine, since x is already the multiplication operator token
in the grammar above):
<line> ::= "y" "=" [ "-" ] [ <coefValue> ] ("x"|"X") ("+"|"-") <interceptValue>
<coefValue> ::= <number> | <ident>
<interceptValue> ::= <number> | <ident>
Design notes (for the report)
- No library parsing functions are used. The tokenizer builds integer
and float values digit-by-digit using manual accumulator recursion
(see
buildIntValue/buildFracValueinInterpreter.fs); it does not callInt32.Parse,Double.Parse,TryParse,String.Split, or any regular expression. Identifiers are built character-by-character with a recursivebuildStrhelper instead ofSubstring. - No collection-library functions are used. List reversal
(
reverseAcc) and the variable environment lookup/update (lookupVar/updateEnv) are hand-written recursive functions over a plain association list, rather thanList.rev,Map, orDictionary. - The only library/framework usage is the WPF
Canvasand shape classes (Line,TextBlock) inMainWindow.xaml.cs, which the assignment brief explicitly permits. - Class diagram / sequence diagram: the report should show
MainWindow->Engine.Evaluate/Engine.ParseLine-> internaltokenize->parseTokens->evalExprpipeline for the class diagram, and a sequence diagram for the line-drawing path:User -> MainWindow.RunInput -> Engine.ParseLine -> MainWindow.DrawLine -> Canvas. - Line-drawing algorithm: the line is drawn using two endpoint
coordinates computed analytically from
y = ax + bat the left and right edges of the visible canvas, converted from maths coordinates to pixel coordinates via a fixedScale(pixels per unit) and the canvas centre as the origin, then rendered with WPF's built-inLineshape (this is the permitted library use for the canvas itself - no custom rasterisation algorithm like Bresenham is needed because WPF's vectorLineelement handles anti-aliased rendering).
Testing suggestions (for the report's Testing section)
Arithmetic:
1 + 2,10 - 4,6 x 7,20 / 4,(1 + 2) x 3,10 / (5 - 5)(division by zero error)999(max 3-digit int, valid),1000(should error - exceeds 3 digits)99.99(max digits, valid),100.5(should error - integer part too long)ab1=5(valid 3-char identifier),abcde(should error - exceeds 4 chars)
Line drawing:
y = 2x + 1,y = -x + 3,y = 0.5x - 2,y = ax + bafter assigningaandb