void awlval_maybe_promote_numeric(awlval* a, awlval* b) { if (!(ISNUMERIC(a->type) && ISNUMERIC(b->type))) { return; } if (a->type == AWLVAL_FLOAT || b->type == AWLVAL_FLOAT) { awlval_promote_numeric(a); awlval_promote_numeric(b); } }
Data* parse_numeric( char** p ) { double ret = 0; if( ISNUMERIC(**p) ) while( ISNUMERIC(**p) ) { ret = ret * 10 + (**p) - '0'; (*p)++; } if( **p == '.' ) { (*p)++; double scale = .1; while( ISNUMERIC(**p) ) { ret = ret + scale * ( **p - '0' ); scale /= 10; (*p)++; } } if( **p == 'E' ) { int sign = 1; int exponent = 0; (*p)++; if( **p == '-' ) sign = -1 , (*p)++; else if( **p == '+' ) (*p)++; while( ISNUMERIC(**p) ) { exponent = exponent * 10 + **p - '0'; (*p)++; } #ifndef __WIN32 if(sign > 0) ret *= exp10(exponent); else ret /= exp10(exponent); #else if(sign > 0) ret *= exp(log(10)*exponent); else ret /= exp(log(10)*exponent); #endif } return Data_new( TYPE_REAL , (Storage)ret , 1 ); }
char* parse_id(char **p) { char* ret = (char*)malloc(32); int len = 0; while( ISNUMERIC(**p) || ISALPHA(**p) || **p == '_' ) { if( len < 30) ret[len++] = **p; (*p)++; } if(**p == '%' || **p == '$') ret[len++] = *((*p)++); ret[len] = 0; return ret; }
Data* parse_factor( char** p) { Data* ret; int curves = 0; while(1) { parse_ws(p); if( **p == '(' ) curves ++; else break; (*p)++; break; } if( curves ) {/* (((...(( parsed , expression expected */ ret = parse_expression(p); if( ret->type == TYPE_ERROR ) {/* error occured*/ return ret; } while(curves--) { /*check ')'*/ parse_ws(p); if( **p != ')' ) {/*syntax error , curves dose not match*/ dispose(ret); return Raise(SYNTAX); } (*p)++; } } else {/* Constant , Variable , Array and Functions*/ /* INKEY$*/ parse_ws(p); if( **p == '"' ) ret = parse_string(p); else if(ISNUMERIC(**p) || **p == '.') ret = parse_numeric(p); else if( ISALPHA(**p) || **p == '_' ) { char* id = parse_id(p); parse_ws(p); if(**p == '(' ) { Subscript *arg; Function* f; arg = parse_arg(p); f = get_fun(id); if( f == NULL ) return Raise(SYNTAX); if( arg == NULL ) return Raise(SYNTAX); if( arg->dimension[arg->dimensions-1]->type == TYPE_ERROR ) { ret = Data_new( TYPE_ERROR , (Storage)arg->dimension[--arg->dimensions]->storage, 1); free(arg); } else { if( f->is_function ) {/*function call*/ ret = f->f.foo( arg ); } else {/*array*/ ret = get_arr_element( &f->f.arr , arg ); } dispose_arg(arg); } } else { /*variable*/ if( strcmp( id , "INKEY$") == 0 ) { ret = Data_new( TYPE_STRING , (Storage)(char*)malloc(2) , 1 ); ret->storage.String[0] = inkey(); ret->storage.String[1] = 0; } else if( strcmp( id , "__LASTERR$" ) == 0 ) { ret = Data_new( TYPE_STRING , (Storage)(char*)malloc(strlen(err_str[Last_Error.id])) , 1 ); strcpy( ret->storage.String , err_str[Last_Error.id] ); } else if( strcmp( id, "__LASTERRNO") == 0 ) { ret = Data_new( TYPE_REAL , (Storage)(double)Last_Error.id,1); } else ret = get_var(id); } free(id); } else { ret =Raise(SYNTAX); } } return ret; }