/******************************************************************** Constraint-based Graphical Programming in B-Prolog % a working calculator *********************************************************************/ go:- calculator(Display,Os), cgWindow(Win,"calculator"),Win^topMargin #= 30, Win^leftMargin #= 10, handleWindowClosing(Win), cgSame(Os,window,Win), cgShow(Os). handleWindowClosing(Win),{windowClosing(Win)} => cgClose(Win). calculator(Display,Os):- % components cgTextField(Display), Display^fontSize #= 16, cgSetEditable(Display,0), % Buttons=[B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,Bc,Bdiv,Bmul,Bsub,Badd,Beq,Bdot], Ts=["0","1","2","3","4","5","6","7","8","9","C","/","*","-","+","=","."], cgButton(Buttons,Ts), Display^width #= B0^width*2, B0^width #>50, % cgFont(F),F^size#=20,F^style#=bold, cgSame(Buttons,font,F), cgAbove(Display,Bc), cgGrid([[Bc,Bdiv,Bmul,Bsub], [B7,B8, B9, Badd], [B4,B5, B6, Badd], [B1,B2, B3, Beq], [B0,B0, Bdot,Beq]],1,1), % Cal=cal(Display,0,"+",result_is_on), handleButtons(Buttons,Cal), Os=[Display|Buttons]. %% handleButtons([],Cal). handleButtons([B|Bs],Cal):- handleButton(B,Cal), handleButtons(Bs,Cal). handleButton(B,Cal),{actionPerformed(B)} => cgGetText(B,Text), catch(handleButtonAction(Text,Cal),_,true). handleButtonAction("C",Cal):-!, Cal=cal(Display,_Acc,_Op,_OnDisplay), setarg(2,Cal,0), % acc setarg(3,Cal,"+"), % op setarg(4,Cal,result_is_on), % result on display cgSetText(Display,""), cgShow(Display). handleButtonAction(Op,Cal):-operator(Op),!, (Cal=cal(_Display,_Acc,_Op,operand_is_on)->applyOperation(Cal);true), setarg(3,Cal,Op). handleButtonAction("=",Cal):-!, applyOperation(Cal). handleButtonAction(X,Cal):- appendInput(X,Cal). %% operations on Cal appendInput(X,Cal):- Cal=cal(Display,_Acc,_Op,result_is_on),!, % result is on display cgSetText(Display,""), setarg(4,Cal,operand_is_on), appendInput(X,Cal). appendInput(".",Cal):- Cal=cal(Display,_Acc,_Op,OnDisplay), cgGetText(Display,Operand), member(0'.,Operand),!. %0'.=X -> [X]="0" appendInput([D],Cal):- Cal=cal(Display,_Acc,_Op,OnDisplay), cgGetText(Display,CurText), append(CurText,[D],NewText), cgSetText(Display,NewText), cgShow(Display). applyOperation(Cal):- Cal=cal(Display,Acc,Op,OnDisplay), cgGetText(Display,String), number_codes(Operand,String), applyOperation(Op,Acc,Operand,NewAcc), number_codes(NewAcc,NewString), cgSetText(Display,NewString), setarg(2,Cal,NewAcc), setarg(4,Cal,result_is_on), cgShow(Display). operator("+"). operator("-"). operator("/"). operator("*"). applyOperation("+",Op1,Op2,Res):-Res is Op1+Op2. applyOperation("-",Op1,Op2,Res):-Res is Op1-Op2. applyOperation("*",Op1,Op2,Res):-Res is Op1*Op2. applyOperation("/",Op1,Op2,Res):-Res is Op1/Op2.