void Interpret( void ) { INSTRUCTION current; int addr, nextaddr; current = Pmem[PC]; nextaddr = PC+1; switch ( current.opcode ) { case HALT: WriteOut( "!! HALT encountered\n\n" ); Running = 0; break; case ADD: BinaryOp( ADD ); break; case SUB: BinaryOp( SUB ); break; case MULT: BinaryOp( MULT ); break; case DIV: BinaryOp( DIV ); break; case NEG: Dmem[SP] = -Dmem[SP]; break; case BR: nextaddr = Branch( BR ); break; case BGZ: nextaddr = Branch( BGZ ); break; case BG: nextaddr = Branch( BG ); break; case BLZ: nextaddr = Branch( BLZ ); break; case BL: nextaddr = Branch( BL ); break; case BZ: nextaddr = Branch( BZ ); break; case BNZ: nextaddr = Branch( BNZ ); break; case CALL: Push( nextaddr ); nextaddr = CodeAddr( current.offset ); break; case RET: nextaddr = CodeAddr( Pop() ); break; case BSF: BuildStackFrame(); break; case RSF: RemoveStackFrame(); break; case LDP: LoadDisplayPointer(); break; case RDP: RestoreDisplayPointer(); break; case INC: SP = DataAddr( SP + current.offset ); break; case DEC: SP = Decrement( SP, current.offset ); break; case PUSHFP: Push( FP ); break; case LOADI: Push( current.offset ); break; case LOADA: addr = DataAddr( current.offset ); Push( Dmem[addr] ); break; case LOADFP: addr = DataAddr( FP + current.offset ); Push( Dmem[addr] ); break; case LOADSP: addr = DataAddr( Dmem[SP] + current.offset ); Dmem[SP] = Dmem[addr]; break; case STOREA: addr = DataAddr( current.offset ); Dmem[addr] = Pop(); break; case STOREFP: addr = DataAddr( FP + current.offset ); Dmem[addr] = Pop(); break; case STORESP: addr = DataAddr( Pop() ); addr = DataAddr( addr + current.offset ); Dmem[addr] = Pop(); break; case READ: ReadInteger(); break; case WRITE: WriteInteger(); break; default: DisplayError( !FATAL, "Error, unknown opcode encountered\n" ); DisplayError( FATAL, "PC = %d, SP = %d, FP = %d, opcode = %d\n", PC, SP, FP, current.opcode ); break; } PC = nextaddr; }
NODE * Div( NODE *n1, NODE *n2 ) { if( n1 == 0 ) return BinaryOp( DIV, Const(1), n2 ); if( n2 == 0 ) return n1; if( IsConst( n2, 1 ) ) { n2->sign *= n1->sign; FreeNode( n2 ); return n1; } return BinaryOp( DIV, n1, n2 ); }
NODE * Sub( NODE *n1, NODE *n2 ) { if( n1 == 0 ) return BinaryOp( SUB, 0, n2 ); if( n2 == 0 ) return n1; if( IsConst( n1, 0 ) ) { FreeNode( n1 ); return BinaryOp( SUB, 0, n2 ); } if( IsConst( n2, 0 ) ) { FreeNode( n2 ); return n1; } return BinaryOp( SUB, n1, n2 ); }
NODE * Mul( NODE *n1, NODE *n2 ) { if( n1 == 0 ) return n2; if( n2 == 0 ) return n1; if( IsConst( n1, 1 ) ) { n2->sign *= n1->sign; FreeNode( n1 ); return n2; } if( IsConst( n2, 1 ) ) { n2->sign *= n1->sign; FreeNode( n2 ); return n1; } if( IsConst( n1, 0 ) ) { FreeNode( n2 ); return n1; } if( IsConst( n2, 0 ) ) { FreeNode( n1 ); return n2; } return BinaryOp( MUL, n1, n2 ); }
inline core::String& binary_op_name(BinaryOp op) { static core::String names[] = { "*", "/", "+", "-", "<<", ">>", "=", "<>", "<", ">", "<=", ">=", "&", "|", "^", "%" }; core::certify(op < BinaryOp(sizeof(names)/sizeof(*names))); return names[core::int64(op)]; }
NODE * Add( NODE *n1, NODE *n2 ) { if( n1 == 0 ) return n2; if( n2 == 0 ) return n1; if( IsConst( n1, 0 ) ) { FreeNode( n1 ); return n2; } if( IsConst( n2, 0 ) ) { FreeNode( n2 ); return n1; } return BinaryOp( ADD, n1, n2 ); }
ACExpression *ACDoc::_Expression1(sInt level) { sInt op,pri; ACExpression *a,*b,*c; if(level==0) return _Value(); a = _Expression1(level-1); for(;;) { op = BinaryOp(Scan.Token,pri); if(!op || pri!=level) break; Scan.Scan(); b = _Expression1(level-1); if(op==ACE_COND1) { if(Scan.Token!=':') Scan.Error(L"':' missing in conditional operator"); Scan.Scan(); c = _Expression1(level-1); a = NewExpr(ACE_COND1,a,NewExpr(ACE_COND2,b,c)); } else if(op==ACE_IMPLIES) { a = NewExpr(ACE_OR,NewExpr(ACE_NOT,a,0),b); } else { a = NewExpr(op,a,b); } } return a; }
NODE * Pow( NODE *n1, NODE *n2 ) { if( n1 == 0 ) return n2; if( n2 == 0 ) return n1; return BinaryOp( POW, n1, n2 ); }