void execute_tablegetelem(instruction* instr){ //printf("exec_tableget\n"); avm_memcell* lv = avm_translate_operand(&instr->result,(avm_memcell*) 0); avm_memcell* t = avm_translate_operand(&instr->arg1,(avm_memcell*) 0); avm_memcell* i = avm_translate_operand(&instr->arg2,&ax); assert(lv && (&stack[AVM_STACKSIZE-1] >= lv && lv > &stack[top] || lv == &retval)); assert(t && &stack[AVM_STACKSIZE-1] >= t && t > &stack[top]); assert(i); avm_memcellclear(lv); lv->type = nil_m; if(t->type != table_m){ avm_error("illigal use of type as table!"); } else{ avm_memcell* content = avm_tablegetelem(t->data.tableVal,i); if(content) avm_assign(lv,content); else{ char* ts = avm_tostring(t); char* is = avm_tostring(i); avm_warning("not found!"); free(ts); free(is); } } }
void execute_tablegetelem (instruction* instr){ avm_memcell* lv = avm_translate_operand(&instr->result, (avm_memcell*) 0); avm_memcell* t = avm_translate_operand(&instr->arg1, (avm_memcell*) 0); avm_memcell* i = avm_translate_operand(&instr->result, &ax); // assert(lv && &stack[N-1] >= lv && lv > &stack[top] || lv == &retval); // assert(t && stack[N-1] >= t && t > &stack[top]); assert(i); avm_memcellclear(lv); lv->type = nil_m; if(t->type != table_m) { avm_error("illegal use of type %s as table!\n", typeStrings[t->type]); executionFinished = 1; } else { avm_memcell* content = avm_tablegetelem(t->data.tableVal, i); if(content) { avm_assign(lv, content); } else { char* ts = avm_tostring(t); char* is = avm_tostring(i); avm_warning("%s[%s] not found!\n", ts, is); free(ts); free(is); } } }
void avm_assign(avm_memcell* lv, avm_memcell* rv){ if(lv == rv) { return; } if((lv->type == table_m)&&(rv->type == table_m)&&(lv->data.tableVal == rv->data.tableVal)) { return; } if(rv->type == undef_m) { avm_warning("Assigning from 'undef' content!\n"); } avm_memcellclear(lv); memcpy(lv, rv, sizeof(avm_memcell)); if(lv->type == string_m) { lv->data.strVal = strdup(rv->data.strVal); } else if(lv->type = table_m) { avm_tableincrefcounter(lv->data.tableVal); } }
void avm_tablebucketsdestroy(avm_table_bucket** p){ unsigned i; avm_table_bucket* b; for(i = 0; i < AVM_TABLE_HASHSIZE; i++) { for(b = *p; b;) { avm_table_bucket* del = b; b = b->next; avm_memcellclear(&del->key); avm_memcellclear(&del->value); free(del); } p[i] = (avm_table_bucket*) 0; } }
void execute_funcexit(instruction *unused){ unsigned oldTop=top; top=avm_get_envvalue(topsp+AVM_SAVEDTOP_OFFSET); pc=avm_get_envvalue(topsp+AVM_SAVEDPC_OFFSET); topsp=avm_get_envvalue(topsp+AVM_SAVEDTOPSP_OFFSET); while (oldTop++<=top) avm_memcellclear(&stack[oldTop]); }
void execute_newtable(instruction* instr){ //printf("exec_newtable\n"); avm_memcell* lv = avm_translate_operand(&instr->result,(avm_memcell*) 0); assert(lv && (&stack[AVM_STACKSIZE-1] >= lv && lv > &stack[top] || lv == &retval)); avm_memcellclear(lv); lv->type = table_m; lv->data.tableVal = avm_tablenew(); avm_tableincrefcounter(lv->data.tableVal); }
void libfunc_typeof(void){ unsigned n = avm_totalactuals(); if(n != 1) avm_error("one argument expected in 'typeof'!"); else{ avm_memcellclear(&retval); retval.type = string_m; retval.data.strVal = strdup(typeStrings[avm_getactual(0)->type]); } }
void libfunc_totalarguments(void){ unsigned p_topsp = avm_get_envvalue(topsp + AVM_SAVEDTOPSP_OFFSET); avm_memcellclear(&retval); if(!p_topsp){ avm_error("'totalarguments' called outside a function!"); retval.type = nil_m; } else{ retval.type = number_m; retval.data.numVal = avm_get_envvalue(p_topsp + AVM_NUMACTUALS_OFFSET); } }
void libfunc_input(void){ unsigned n=avm_totalactuals(); if(n!=0){ avm_error("no argument expected at 'input'"); return ; } char* input=malloc(sizeof(char)*100); fgets(input,99,stdin); avm_memcellclear(&retval); retval.type=string_m; retval.data.strVal=input; }
void libfunc_totalarguments(void){ unsigned p_topsp=avm_get_envvalue(topsp+AVM_SAVEDTOPSP_OFFSET); avm_memcellclear(&retval); unsigned i; if(p_topsp>=AVM_STACKSIZE-1-programVarOffset){ avm_error("'totalarguments' called outside of a function"); retval.type=nil_m; } else { retval.type=number_m; retval.data.numVal=avm_get_envvalue(p_topsp+AVM_NUMACTUALS_OFFSET); } }
void libfunc_strtonum(void){ unsigned n=avm_totalactuals(); avm_memcellclear(&retval); if(n==0){ avm_error("too few arguments for strtonum"); retval.type=nil_m; return; } avm_memcell* m=avm_getactual(0); if(m->type!=string_m){ avm_error("argument of strtonum must be a string"); retval.type=nil_m; return; } retval.type=number_m; retval.data.numVal=atof(m->data.strVal); }
void execute_arithmetic (instruction* instr) { avm_memcell* lv = avm_translate_operand(instr->result,(avm_memcell*)0); avm_memcell* rv1= avm_translate_operand(instr->arg1,&ax); avm_memcell* rv2= avm_translate_operand(instr->arg2,&bx); assert(lv && ( (&stack[AVM_STACKSIZE]>= lv && &stack[top]<lv )|| lv==&retval )); assert(rv1 && rv2); if (rv1->type !=number_m || rv2->type !=number_m ) { avm_error("not a number arithmetic!\n"); executionFinished=1; } else { arithmetic_func_t op=arithmeticFuncs[instr->opcode - add_v]; avm_memcellclear(lv); lv->type = number_m; lv->data.numVal = (*op)(rv1->data.numVal,rv2->data.numVal); } //printf("DEBUG VALUE:%d\n",(int)lv->data.numVal); }
void libfunc_argument(void){ unsigned p_topsp=avm_get_envvalue(topsp+AVM_SAVEDTOPSP_OFFSET); avm_memcellclear(&retval); unsigned i; if(p_topsp>=AVM_STACKSIZE-1-programVarOffset){ avm_error("'argument' called outside of a function"); retval.type=nil_m; } unsigned n=avm_totalactuals(); if(n!=1){ avm_error("one argument expected at 'argument'"); return ; } avm_memcell* m=avm_getactual(0); if(m->type!=number_m){ avm_error("argument of 'argument' must be a number"); return; } int doubletoint=m->data.numVal; retval=stack[p_topsp+AVM_STACKENV_SIZE +1 +doubletoint]; }