UNB/ CS/ David Bremner/ teaching/ cs2613/ assignments/ CS2613 Assignment 3

Marking

Background

const test=require("node:test");
const assert=require("assert");

What to hand in, and how to hand it in

expression function

Conceptually expression is like one of the make-thing functions defined for Racket structs. It takes an ordered list of parameters, and returns an object allowing access to those same values by name. You can also think of it as a constructor, although we will see that constructors in JavaScript typically do more.

Your expression function should pass the following tests; you will need to need to write an appropriate function Plus (more about this below).

const one = 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));
test('object',
     (t)=>assert.deepStrictEqual(expression(Plus,6,7),
                                 {op: Plus, left: 6, right: 7}));

eval function

The eval function returns the number equivalent to the given object without modifying the input object. Your eval function 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 = expression(Plus, 6, 9);
const six_times_nine = expression(Times, 6, 9);
const six_minus_nine = expression(Minus, 6, 9);
const sixteen_div_eight = expression(Divide, 16, 8);

test("+", () => assert.strictEqual(eval(six_plus_nine),15));
test("-", () => assert.strictEqual(eval(six_minus_nine),-3));
test("*", () => assert.strictEqual(eval(six_times_nine),54));
test("/", () => assert.strictEqual(eval(sixteen_div_eight),2));


const compound1 = expression(Plus, six_times_nine, six_plus_nine)
const compound2 = expression(Times, six_times_nine, compound1)
const compound3 = expression(Plus, compound2, 3)

test("compound1", (t) => assert.strictEqual(eval(compound1),69));
test("compound2", (t) => assert.strictEqual(eval(compound2),3726));
test("compound3", () => assert.strictEqual(eval(compound3),3729));

clone_expression function

Write a function clone_expression to do a deep copy of an object created by expression. Use recursion, not a library function.

Your clone_expression function should pass the following tests

test("structural equality", function(t) {
    const copy3=clone_expression(compound3);
    assert.deepStrictEqual(compound3,copy3);
});

test("independence",
     function(t) {
         const copy4=clone_expression(compound2);
         copy4.op=Minus;
         assert.notDeepStrictEqual(compound2,copy4);
     });

test("immutability", function(t) {
    const copy5=clone_expression(compound3);
    const val = eval(compound3);
    assert.deepStrictEqual(compound3,copy5);
})

test("deep copy", function(t) {
    const copy6=clone_expression(compound3);
    let copy7=clone_expression(copy6);
    copy7.left.left=1;
    assert.notDeepStrictEqual(copy6,copy7);
});