Marking
- This assignment will be worth 5% of your final grade.
- You will be marked on the last version pushed to coursegit. Make sure you have pushed your assignment by 4:30PM on Thursday February 27.
You will be marked on
- correctness and implementation detail: Pay attention to the way you are asked to implement things.
- functional JavaScript: Part of the point of the assignment is to see that a certain tasks can be accomplished in a very similar way in JavaScript as in Racket. So don’t go crazy with mutation.
- testing: Remember to have full test coverage (according to
node --experimental-test-coverage
).
For detailed marking scheme, see javascript-assignment.
Background
- This assignment is mainly based on Chapters 3-5 of Eloquent JavaScript.
- We also make extensive use of const; it turns out this is not enough to prevent modifying objects. For more details see MDN
- You will need to add the following lines to the top of your file to enable the test framework:
const test=require("node:test");
const assert=require("assert");
What to hand in, and how to hand it in
- Make a directory
~/cs2613/assigments/A3
(i.e. in your git repo for this class). All files related to this assignment should be saved in that directory. - Make sure you commit and push all your work using coursegit by the due date.
Expression
class
Write an Expression
class to represent arithmetic expressions.
Your Expression
class should pass the following tests; you will also need
to need to write an appropriate function Plus
.
test("Plus", (t) => assert.strictEqual(Plus(1,2), 3));
const one = new Expression(Plus,0,1);
test("not null", (t) => assert.notStrictEqual(one,null));
test("not undefined", (t) => assert.notStrictEqual(one,undefined));
test("op", (t) => assert.strictEqual(one.op, Plus));
test("left", (t) => assert.strictEqual(one.left,0));
test("right", (t) => assert.strictEqual(one.right,1));
eval
method
The eval
method returns the number equivalent to the given object
without modifying the input object. Your eval
method should pass
the following tests, and use recursion to do the actual evaluation.
You will need to define appropriate Times
, Minus
, Divide
functions.
const six_plus_nine = new Expression(Plus, 6, 9);
const six_times_nine = new Expression(Times, 6, 9);
const six_minus_nine = new Expression(Minus, 6, 9);
const sixteen_div_eight = new Expression(Divide, 16, 8);
test("+", () => assert.strictEqual(six_plus_nine.eval(),15));
test("-", () => assert.strictEqual(six_minus_nine.eval(),-3));
test("*", () => assert.strictEqual(six_times_nine.eval(),54));
test("/", () => assert.strictEqual(sixteen_div_eight.eval(),2));
const compound1 = new Expression(Plus, six_times_nine, six_plus_nine)
const compound2 = new Expression(Times, six_times_nine, compound1)
const compound3 = new Expression(Plus, compound2, 3)
test("compound1", (t) => assert.strictEqual(compound1.eval(),69));
test("compound2", (t) => assert.strictEqual(compound2.eval(),3726));
test("compound3", () => assert.strictEqual(compound3.eval(),3729));
clone
method
Write a function clone
to do a deep copy of an Expression object
Use recursion, not a library function.
Your clone
method should pass the following tests
test("structural equality", function(t) {
const copy3=compound3.clone(compound3);
assert.deepStrictEqual(compound3,copy3);
});
test("independence",
function(t) {
const copy4=compound2.clone();
copy4.op=Minus;
assert.notDeepStrictEqual(compound2,copy4);
});
test("immutability", function(t) {
const copy5=compound3.clone();
const val = compound3.eval();
assert.deepStrictEqual(compound3,copy5);
})
test("deep copy", function(t) {
const copy6=compound3.clone();
let copy7=copy6.clone();
copy7.left.left=1;
assert.notDeepStrictEqual(copy6,copy7);
});