% $Id: BoundVarIdsTest.oz,v 1.14 2012/01/17 11:50:53 leavens Exp leavens $ % AUTHOR: Gary T. Leavens \insert 'MyOzParser.oz' \insert 'BoundVarIds.oz' \insert 'TestingNoStop.oz' %% from the course library \insert 'CommaSeparate.oz' %% From homework 3 declare % A helping procedure to eliminate repitition in the testing below proc {BVTest Message AST IdList} {System.showInfo "BV(" # Message # ") == {" # {CommaSeparate {Map IdList AtomToString}} # "}"} {Assert {Equal {BoundVarIds AST} {AsSet IdList}}} end proc {BVProgTest FileName Program IdList} % Test the given program AST = {ParseVS Program FileName Reporter} % {Show AST} Res = {BoundVarIdsProgram AST} in % {ReportAbout '\nRunning test '#FileName} {System.showInfo "BV(" # Program # ") == {" # {CommaSeparate {Map {AsList Res} AtomToString}} # "}"} {Assert {Equal Res {AsSet IdList}}} end {StartTesting 'BoundVarIdsTest $Revision: 1.14 $'} {BVTest "skip" skipStmt nil} {BVTest "local A in skip end" localStmt(varId('A') skipStmt) nil} {BVTest "A = B" unifyStmt(varId('A') varId('B')) nil} {BVTest "A = 3" unifyStmt(varId('A') intLit(3)) nil} {BVTest "A = 3 B = C" seqStmt([unifyStmt(varId('A') intLit(3)) unifyStmt(varId('B') varId('C'))]) nil} {BVTest "A = 3 B = C E = A" seqStmt([unifyStmt(varId('A') intLit(3)) unifyStmt(varId('B') varId('C')) unifyStmt(varId('E') varId('A'))]) nil} {BVTest "if B then skip else skip end" ifStmt(varId('B') skipStmt skipStmt) nil} {BVTest "if true then R = true else S = false end" ifStmt(boolExp(true) unifyStmt(varId('R') boolExp(true)) unifyStmt(varId('S') boolExp(false))) nil } {BVTest "if 3 then skip else skip end" ifStmt(intLit(3) skipStmt skipStmt) nil} {BVTest "if 3 then A = B else skip end" ifStmt(intLit(3) unifyStmt(varId('A') varId('B')) skipStmt) nil} {BVTest "if X then A = B else skip end" ifStmt(varId('X') unifyStmt(varId('A') varId('B')) skipStmt) nil} {BVTest "if X then A = B else D = Z end" ifStmt(varId('X') unifyStmt(varId('A') varId('B')) unifyStmt(varId('D') varId('Z'))) nil} {BVTest "local A in A = B end" localStmt(varId('A') unifyStmt(varId('A') varId('B'))) ['A']} {BVTest "local A in A = 3 end" localStmt(varId('A') unifyStmt(varId('A') intLit(3))) ['A']} {BVTest "local A in A = A end" localStmt(varId('A') unifyStmt(varId('A') varId('A'))) ['A']} {BVTest "local A in B = C end" localStmt(varId('A') unifyStmt(varId('B') varId('C'))) nil} {BVTest "case C of ok then skip else skip end" caseStmt(varId('C') atomPat(ok) skipStmt skipStmt) nil} {BVTest "case C of X then skip else skip end" caseStmt(varId('C') varIdPat('X') skipStmt skipStmt) nil} {BVTest "case C of X then B = X else skip end" caseStmt(varId('C') varIdPat('X') unifyStmt(varId('B') varId('X')) skipStmt) ['X']} {BVTest "case C of X then B = X else D = 7 end" caseStmt(varId('C') varIdPat('X') unifyStmt(varId('B') varId('X')) unifyStmt(varId('D') intLit(7))) ['X']} {BVTest "case C of nowXisFree then B = X else D = 7 end" caseStmt(varId('C') atomPat(nowXisFree) unifyStmt(varId('B') varId('X')) unifyStmt(varId('D') intLit(7))) nil} {BVTest "case C of Q then B = X else Z = Q end" caseStmt(varId('C') varIdPat('Q') unifyStmt(varId('B') varId('X')) unifyStmt(varId('Z') varId('Q'))) nil} {BVTest "case C of foo() then B = X else D = 7 end" caseStmt(varId('C') recordPat(atomExp(foo) nil) unifyStmt(varId('B') varId('X')) unifyStmt(varId('D') intLit(7))) nil} {BVTest "case C of foo(X Y) then B = X else D = Y end" caseStmt(varId('C') recordPat(atomExp(foo) [posFld(varIdPat('X')) posFld(varIdPat('Y'))]) unifyStmt(varId('B') varId('X')) unifyStmt(varId('D') varId('Y'))) ['X']} {BVTest "case C of foo(f1:X f2:Y) then B = X else D = Y end" caseStmt(varId('C') recordPat(atomExp(foo) [colonFld(atomExp(f1) varIdPat('X')) colonFld(atomExp(f2) varIdPat('Y'))]) unifyStmt(varId('B') varId('X')) unifyStmt(varId('D') varId('Y'))) ['X']} {BVTest "case C of foo(f1:bar(f2:X f3:Y f4:Z))" # " then B = X if Z then D = Y else skip end" # " else skip end" caseStmt(varId('C') recordPat(atomExp(foo) [colonFld(atomExp(f1) recordPat(atomExp(bar) [colonFld(atomExp(f2) varIdPat('X')) colonFld(atomExp(f3) varIdPat('Y')) colonFld(atomExp(f4) varIdPat('Z'))]))]) seqStmt([unifyStmt(varId('B') varId('X')) ifStmt(varId('Z') unifyStmt(varId('D') varId('Y')) skipStmt)]) skipStmt) ['X' 'Y' 'Z']} {BVTest "case C of foo(f1:bar(f2:X f3:Y f4:Q))" # " then B = X if Z then D = Y else skip end" # " else skip end" caseStmt(varId('C') recordPat(atomExp(foo) [colonFld(atomExp(f1) recordPat(atomExp(bar) [colonFld(atomExp(f2) varIdPat('X')) colonFld(atomExp(f3) varIdPat('Y')) colonFld(atomExp(f4) varIdPat('Q'))]))]) seqStmt([unifyStmt(varId('B') varId('X')) ifStmt(varId('Z') unifyStmt(varId('D') varId('Y')) skipStmt)]) skipStmt) ['X' 'Y']} {BVTest "{P}" applyStmt(varId('P') nil) nil} {BVTest "{Browse 3}" applyStmt(varId('Browse') [intLit(3)]) nil} {BVTest "{Map Ls F}" applyStmt(varId('Map') [varId('Ls') varId('F')]) nil} {BVTest "{Map 3|nil F}" applyStmt(varId('Map') [recordExp(atomExp('|') [posFld(intLit(3)) posFld(atomExp(nil))]) varId('F')]) nil} {BVTest "{Map 3|nil proc {$ X R} {Browse X} R = X end}" applyStmt(varId('Map') [recordExp(atomExp('|') [posFld(intLit(3)) posFld(atomExp(nil))]) procExp([varIdPat('X') varIdPat('R')] seqStmt([applyStmt(varId('Browse') [varId('X')]) unifyStmt(varId('R') varId('X'))]))]) ['X' 'R']} {BVTest "{Map 3|nil proc {$ X R} {Browse X} R = Y end}" applyStmt(varId('Map') [recordExp(atomExp('|') [posFld(intLit(3)) posFld(atomExp(nil))]) procExp([varIdPat('X') varIdPat('R')] seqStmt([applyStmt(varId('Browse') [varId('X')]) unifyStmt(varId('R') varId('Y'))]))]) ['X' 'R']} {BVTest "Three = proc {$ R} R = 3 end" unifyStmt(varId('Three') procExp([varIdPat('R')] unifyStmt(varId('R') intLit(3)))) ['R']} {BVTest "fun {Three} 3 end" namedFunStmt('Three' nil intLit(3)) nil} {BVTest "fun {Add X Y} {Plus X Y} end" namedFunStmt('Add' [varIdPat('X') varIdPat('Y')] applyExp(varId('Plus') [varId('X') varId('Y')])) ['X' 'Y']} {BVTest "fun {Add X Y} {Plus X X Z} end" namedFunStmt('Add' [varIdPat('X') varIdPat('Y')] applyExp(varId('Plus') [varId('X') varId('X') varId('Z')])) ['X']} {BVTest "fun {F X} proc {$ F R} R = {F A} end end" namedFunStmt('F' [varIdPat('X')] procExp([varIdPat('F') varIdPat('R')] unifyStmt(varId('R') applyExp(varId('F') [varId('A')])))) ['F' 'R']} {BVTest "InTest = proc {$ Tree R} node(X Y) = Tree in R = {Plus X Y} end" unifyStmt(varId('InTest') procExp([varIdPat('Tree') varIdPat('R')] inStmt(recordPat(atomExp(node) [posFld(varIdPat('X')) posFld(varIdPat('Y'))]) varId('Tree') unifyStmt(varId('R') applyExp(varId('Plus') [varId('X') varId('Y')]))))) ['Tree' 'R' 'X' 'Y']} {BVTest "fun {First X#Y} X end" namedFunStmt('First' [recordPat(atomExp('#') [posFld(varIdPat('X')) posFld(varIdPat('Y'))])] varId('X')) ['X']} {BVTest "fun {RevPair X#Y} Y#X end" namedFunStmt('RevPair' [recordPat(atomExp('#') [posFld(varIdPat('X')) posFld(varIdPat('Y'))])] recordExp(atomExp('#') [posFld(varId('Y')) posFld(varId('X'))])) ['X' 'Y']} {BVTest "fun {RevPair P} case P of X#Y then Y#X else error end end" namedFunStmt('RevPair' [varIdPat('P')] caseExp(varId('P') recordPat(atomExp('#') [posFld(varIdPat('X')) posFld(varIdPat('Y'))]) recordExp(atomExp('#') [posFld(varId('Y')) posFld(varId('X'))]) atomExp(error))) ['P' 'X' 'Y']} {BVTest "fun {FirstOnly P} case P of Q then X else Q end end" namedFunStmt('FirstOnly' [varIdPat('P')] caseExp(varId('P') varIdPat('Q') varId('X') varId('Q'))) ['P']} {BVTest "fun {T N} if {Odd N} then {Div {Plus {Mult 3 N} 1} 2}" # " else {Div N 2} end end" namedFunStmt('T' [varIdPat('N')] ifExp(applyExp(varId('Odd') [varId('N')]) applyExp(varId('Div') [applyExp(varId('Plus') [applyExp(varId('Mult') [intLit(3) varId('N')]) intLit(1)]) intLit(2)]) applyExp(varId('Div') [varId('N') intLit(2)]))) ['N']} local ParsedFigExample = % (Figure 2 of homework 3a) namedFunStmt('AddToEach' [recordPat(atomExp('#') [posFld(varIdPat('A')) posFld(varIdPat('B'))]) varIdPat('Ls')] caseExp(varId('Ls') recordPat(atomExp('|') [posFld(recordPat(atomExp('#') [posFld(varIdPat('X')) posFld(varIdPat('Y'))])) posFld(varIdPat('T'))]) recordExp(atomExp('|') [posFld(recordExp(atomExp('#') [posFld(applyExp(varId('Plus') [varId('A') varId('X')])) posFld(applyExp(varId('Plus') [varId('B') varId('Y')]))])) posFld(applyExp(varId('AddToEach') [recordExp(atomExp('#') [posFld(varId('A')) posFld(varId('B'))]) varId('T')]))]) atomExp(nil))) in {BVTest "fun {AddToEach A#B Ls}" # " case Ls of X#Y|T then {Plus A X}#{Plus B Y}|{AddToEach A#B T}" # " else nil end" # " end" ParsedFigExample ['A' 'B' 'Ls' 'X' 'Y' 'T']} end {BVTest "thread X = proc {$ Z} Z = 3 end end" threadStmt(unifyStmt(varId('X') procExp([varIdPat('Z')] unifyStmt(varId('Z') intLit(3))))) ['Z']} {BVTest "X = thread proc {$ Z} Z = 3 end end" unifyStmt(varId('X') threadExp(procExp([varIdPat('Z')] unifyStmt(varId('Z') intLit(3))))) ['Z']} {BVProgTest 'declare1' "declare X = 3" ['X']} {BVProgTest 'declare2' "declare X = 3 Y = X Z = Y" ['X' 'Y' 'Z']} {BVProgTest 'declareIn1' "declare X = 3 Y = X in Z = Y" ['X' 'Y']} {BVProgTest 'declare3' "declare fun {Id X} X end" ['Id' 'X']} {BVProgTest 'declare4' "declare fun {Add X Y} {Plus X Y} end {Plus 3 4}" ['Add' 'X' 'Y']} {DoneTesting}