/* iGASM example */ /* Evaluates expressions with binary operators using stack & Rear Polish Notation. */ UNIVERSES Operator = {"+","-","*","/","(",")"}; Mode = { init, /*input string*/ tokenize, /*dividing into lexems*/ trans, /*translating to RPN*/ eval, /*evaluating*/ end}; /*ending with writing result*/ FUNCTIONS curMode : Mode; Arg1, Arg2 : Number; tape : List; st : Stack; rpn : Stack; static priority : Operator -> Number; str : String; instr : String; counter : Number; INITIAL curMode := init; tape := emptyList; st := emptyStack; rpn := emptyStack; priority("+") := 2; priority("-") := 2; priority("*") := 3; priority("/") := 3; priority("(") := 1; priority(")") := 1; str := ""; counter := 0; FINAL curMode = undef; RULES IF curMode = init THEN IF instr = undef THEN instr := readln("Enter an expression"); ELSE curMode := tokenize; ENDIF ELSEIF curMode = tokenize THEN if counter= priority(listHead(tape)) ) THEN /*st->tape*/ st := stPop(st); rpn := stPush(rpn, stTop(st)); ELSE st := stPush(st, listHead(tape)); tape := listTail(tape); ENDIF ELSEIF Number(listHead(tape)) THEN tape := listTail(tape); rpn := stPush(rpn, listHead(tape)); ELSE /*error*/ curMode := undef; writeln := "Error: undefined symbol :"; writeln := listHead(tape); ENDIF ELSEIF st!=emptyStack THEN st := stPop(st); rpn := stPush(rpn, stTop(st)); ELSE curMode := eval; tape := toList(rpn); /* rpn -> tape */ ENDIF ELSEIF curMode = eval THEN if Number(listHead(tape)) then st := stPush(st, listHead(tape)); tape := listTail(tape); elseif Operator(listHead(tape)) then if Arg1=undef then Arg1 := stTop(st); st := stPop(st); elseif Arg2=undef then Arg2 := stTop(st); st := stPop(st); else st := stPush(st, apply(listHead(tape), Arg2, Arg1)); tape := listTail(tape); Arg1 := undef; Arg2 := undef; endif else curMode := end; endif ELSEIF curMode = end THEN curMode := undef; writeln := "Result: \n\t"+ instr + " = " + toString(stTop(st)); ENDIF