ETCompiler::dword VCPU::GetAddress( const std::string& name ) { dword target = 0; target |= (dword)GetReg( name ); target |= (dword)GetVar( name ); target |= (dword)GetConst( name ); return target; }
void VCPU::_call( TokenList& insVector ) { dword label = (dword)GetConst( insVector[ 1 ] ); _push( eip ); // 保存PC eip = *(dword_pointer)label; }
int main() { int arr[GetConst()] = { 0 };//无法使用运行时常量来初始化数组 enum{ e1 = GetConst(), e2 };//也无法使用运行时常量作为枚举值 int arr2[GetConstexpr()] = { 0 };//ok constexpr ConstexprClass mc(0); //必须使用常量表达式赋值 //constexpr ConstexprClass mc = { 0 };等价上一条 //constexpr ConstexprClass mc{ 0 }; 等价上一条 //gcc-5.1报错:"error: passing 'const Date' as 'this' argument discards qualifiers [-fpermissive]" constexpr Date d(1990, 11, 28); constexpr int year = d.GetYear(); constexpr int month = d.GetMonth(); constexpr int day = d.GetDay(); std::cout << "year:" << year << std::endl << "month" << month << std::endl << "day" << day << std::endl; //结构体NotLiteral不是定义了常量表达式构造函数的类型,因此不能够声明为常量表达式值 //而模版函数一旦以NotLiteral作为参数,那么其constexpr关键字就会被忽略 NotLiteral nl; NotLiteral nl1 = ConstExprFun(nl); constexpr NotLiteral nl2 = ConstExprFun(nl);//编译失败 constexpr int a = ConstExprFun(1); constexpr Literal l1; Literal l2 = ConstExprFun(l1);//ok constexpr Literal l3 = ConstExprFun(l1);//ok //constexpr函数递归 int fibs[] = { Fib(11), Fib(12), Fib(13), Fib(14), Fib(15) }; std::copy(std::begin(fibs), std::end(fibs), std::ostream_iterator<int>(std::cout, " "));//89 144 233 377 610 std::cout << std::endl; //使用模板元实现递归编程 int fibs2[] = { Fibo<11>::result, Fibo<12>::result, Fibo<13>::result, Fibo<14>::result, Fibo<15>::result }; std::copy(std::begin(fibs2), std::end(fibs2), std::ostream_iterator<int>(std::cout, " "));//89 144 233 377 610 return 0; }
static void BreakOpn( FCODE routine ) { //========================================= CITNode->opn.ds = DSOPN_LIT; GetConst(); AddConst( CITNode ); GBreak( routine ); AdvanceITPtr(); if( !RecEOS() ) { Error( SX_NUM_OR_LIT ); } }
static bool HexConst(void) { //========================== // Check for a hexadecimal constant specifier. char *hex_data; int hex_len; sym_id sym; hex_data = CITNode->opnd; hex_len = CITNode->opnd_size; if( CITNode->opn.ds != DSOPN_HEX ) { if( !RecName() ) return( false ); if( *hex_data != 'Z' ) return( false ); sym = SymFind( hex_data, hex_len ); if( sym != NULL ) { if( ( sym->u.ns.flags & SY_CLASS ) == SY_PARAMETER ) { return( false ); } } ++hex_data; } --hex_len; hex_len = MkHexConst( hex_data, CITNode->opnd, hex_len ); if( hex_len == 0 ) return( false ); CITNode->opnd_size = hex_len; CITNode->opn.ds = DSOPN_LIT; GetConst(); AddConst( CITNode ); CITNode->typ = FT_HEX; Extension( DA_HEX_CONST ); return( true ); }
/*return option price*/ Float option_price( Ivar vars, /*five floating vars defined in Ivar type*/ long steps, /*number of steps in the binomial tree*/ int type, /*call / put -- American/European*/ int method /*Cox-Ross-Rubinstein or Equiprobability*/ ){ Node *tree; TreeConst constants; /*constants for CRR or EQUIPROB*/ Float up, down; /*constants for CRR or EQUIPROB*/ Float up_prob; /*constants for CRR or EQUIPROB*/ Float down_prob; /*constants for CRR or EQUIPROB*/ long StepPtr; /*dummy: step pointer*/ long SpotPtr; /*dummy: price pointer*/ Float discount; /*discount factor for one time step*/ Float price; /*value to be returned*/ Float dt; /*time step*/ Float *tmp_options,*tmp_spots; struct timespec reqStart,reqEnd; double accum; int i; /******CALCULATE DISCOUNT FACTOR FOR ONE TIME STEP********/ dt = vars.T / (steps - ONE); discount = exp(-vars.mu * dt); /*********************************************************/ /***CALCULATE APPROPRIATE CONSTANTS FOR SPECIFIED METHOD**/ constants = GetConst(vars, method, steps); up = constants.up; down = constants.down; up_prob = constants.prob; down_prob = UNITY - up_prob; /*********************************************************/ /******ALLOCATE SPACE FOR ONE STEP IN BINOMIAL TREE*******/ tree = (Node*)malloc((steps + ONE)*sizeof(Node)); if(NULL == tree){ fprintf(stderr, "ERROR: failure of malloc()\n"); exit(ERROR); } /********************************************************/ /*********FIRST INITIALIZE ZEROTH NODE*******************/ tree[0].spot = vars.S; tree[0].prob = UNITY; /*********************************************************/ tmp_options = malloc(sizeof(Float)*steps); tmp_spots = malloc(sizeof(Float)*steps); //#pragma omp parallel /*********FILL TREE WITH SPOT PRICES**********************/ //#pragma omp for for(StepPtr = ONE; StepPtr < steps; StepPtr++){ tree[StepPtr].spot = tree[StepPtr - ONE].spot * up; #pragma omp parallel for for(SpotPtr = 0; SpotPtr < StepPtr; SpotPtr++){ tree[SpotPtr].spot *= down; } }/**********************************************************/ /********FILL TREE WITH PROBABILITIES**********************/ //#pragma omp for for(StepPtr = ONE; StepPtr < steps; StepPtr++){ //calculate prob for highest spot price tree[StepPtr].prob = tree[StepPtr - ONE].prob * up_prob; //calculate prob for spot price in between* #pragma omp parallel for for(SpotPtr = StepPtr - ONE; SpotPtr > 0; SpotPtr--){ tree[SpotPtr].prob = tree[SpotPtr].prob * down_prob + tree[SpotPtr - ONE].prob * up_prob ; } //calculate prob for lowest spot price* tree[0].prob *= down_prob; } /**********************************************************/ /******CALCULATE OPTION VALUES ON EXPIRATION DATE**********/ if((EUROCALL == type)||(AMERCALL == type)){ #pragma omp parallel for for(SpotPtr = 0; SpotPtr < steps; SpotPtr++){ tree[SpotPtr].option = MAX(0.0, tree[SpotPtr].spot - vars.X); } } else if((EUROPUT == type)||(AMERPUT == type)){ #pragma omp parallel for for(SpotPtr = 0; SpotPtr < steps; SpotPtr++){ tree[SpotPtr].option = MAX(0.0, vars.X - tree[SpotPtr].spot); } } else{ fprintf(stderr, "ERROR: invalid option type\n"); exit(ERROR); } /***********************************************************/ clock_gettime(CLOCK_REALTIME, &reqStart); /*WALK BACKWARDS THROUGH BINOMIAL TREE FROM EXPIRATION TO ORIGIN*/ price=0.0; for(StepPtr = steps - ITWO; StepPtr >=0; StepPtr--){ #pragma omp parallel for for(SpotPtr = 0; SpotPtr < steps; SpotPtr++){ tmp_options[SpotPtr]=tree[SpotPtr].option; tmp_spots[SpotPtr]=tree[SpotPtr].spot; } #pragma omp parallel for for(SpotPtr = 0; SpotPtr <= StepPtr; SpotPtr++){ Float early = 0.0; /*value if exercised early*/ /*calculate weighted average*/ tree[SpotPtr].option = down_prob * tree[SpotPtr].option + up_prob * tmp_options[SpotPtr + ONE]; /*calculate spot price*/ tree[SpotPtr].spot = tmp_spots[SpotPtr+ONE] / up; /*apply discount factor*/ tree[SpotPtr].option *= discount; /*determine if early exercise is desirable*/ if(AMERCALL == type){ early = MAX(0.0, tree[SpotPtr].spot - vars.X); } else if(AMERPUT == type){ early = MAX(0.0, vars.X - tree[SpotPtr].spot); } tree[SpotPtr].option = MAX( tree[SpotPtr].option, early ); } } /*******************************************************************/ clock_gettime(CLOCK_REALTIME, &reqEnd); /*price is...*/ price = tree[0].option; accum = ( reqEnd.tv_sec - reqStart.tv_sec ) + ( reqEnd.tv_nsec - reqStart.tv_nsec ) / BILLION; printf( "\n TIME TAKEN FOR WAlkBack Routine : %lf\n", accum ); /*return the binomial tree to the memory pool and return the result*/ free(tree); return price; }
void VCPU::jump( TokenList& insVector ) { dword label = (dword)GetConst( insVector[ 1 ] ); eip = *(dword_pointer)label; }
void VCPU::Execute() { TokenList& insVector = IR->m_elements; static TokenList lastInst = insVector; std::string& first = insVector[ 0 ]; if ( first == "mov" ) { _mov(insVector); } else if ( first == "lea" ) { dword target = NULL; dword source = NULL; target |= (dword)GetReg( insVector[ 1 ] ); target |= (dword)GetVar( insVector[ 1 ] ); source |= (dword)GetReg( insVector[ 2 ] ); source |= (dword)GetVar( insVector[ 2 ] ); source |= (dword)GetConst( insVector[ 2 ] ); dword_pointer t = (dword_pointer)target; dword_pointer s = (dword_pointer)source; *(dword_pointer)target = source; t = (dword_pointer)target; s = (dword_pointer)source; } else if ( first == "push" || first == "arg" ) { push(insVector); } else if ( first == "pop" ) { pop(insVector); } else if ( first == "add" || first == "sub" || first == "mul" || first == "div" ) { _operator(insVector); } else if ( first == "jmp" ) { jump(insVector); } else if ( first == "jeq" || first == "jlt" || first == "jle" || first == "jne" || first == "jgt" || first == "jge") { _conditionJmp(insVector); } else if ( first == "call" ) { _call(insVector); } else if ( first == "leave" ) { leave(); } else if ( first == "in" ) { } else if ( first == "out" ) { dword target = 0; target |= (dword)GetConst( insVector[ 1 ] ); if ( target ) { if ( *(dword_pointer)target == 0 ) m_log += "\n"; else if ( *(dword_pointer)target == 1 ) m_log += " "; } else { target = GetAddress( insVector[ 1 ] ); char out[ 64 ]; sprintf_s( out, "%d", *(dword_pointer)target ); m_log += out; } } else if ( first == "halt" ) { eip = m_pInstructions->size(); // 程序结束 std::cout << "\nDone!!\n"; } lastInst = insVector; }
//要求4: constexpr int g(){ return GetConst(); } //error,无法在return返回语句中使用非常量表达式的函数