예제 #1
0
void libfunc_objecttotalmembers(void){
	if(avm_totalactuals()!=1){
		avm_error("one argument  expected at 'objecttotalmembers'");
		return;
	}
	avm_memcell* m =avm_getactual(0);
	if(m==NULL|| m->type!=table_m){
		avm_error("argument of 'objecttotalmemers' must be a table");
		return;
	}
	retval.type=number_m;
	retval.data.numVal=(int)m->data.tableVal->total;
}
예제 #2
0
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);
			}
		}
}
예제 #3
0
void execute_call(instruction* instr){
	//printf("exec_call\n");
	avm_memcell* func = avm_translate_operand(&instr->result, &ax);
	assert(func);
	avm_callsaveenviroment();

	switch (func->type){		
		case userfunc_m: {
			pc = func->data.funcVal;
			assert(pc < AVM_ENDING_PC);
			assert(instr[pc].opcode = funcenter_v);
			break;
		}
		
		case string_m: {
			avm_calllibfunc(func->data.strVal);
			break;
		}
		
		case libfunc_m: {
			avm_calllibfunc(func->data.strVal);
			break;
		}
		
		default: {
			char *s = (char*) malloc(sizeof(char));
			s = avm_tostring(func);
			avm_error("call: cannot bind '%s' to function!");
			free(s);
			executionFinished = 1;
		}
	}
}
예제 #4
0
void avm_dec_top(void){
	if(!top){
		avm_error("stack overflow");
		executionFinished=1;
	}
	else --top;
}
예제 #5
0
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);
		}
	}
}
예제 #6
0
void execute_call (instruction* instr){
	avm_memcell* func = avm_translate_operand(&instr->result, &ax);
	assert(func);
	avm_callsaveenvironment();

	char* s;
	switch(func->type)
		{
		case userfunc_m:
			pc = func->data.funcVal;
			assert(pc < AVM_ENDING_PC);
			assert(code[pc].opcode == funcenter_v);
			break;
		case string_m:
			avm_calllibfunc(func->data.strVal);
			break;
		case libfunc_m:
			avm_calllibfunc(func->data.libfuncVal);
			break;
		default:
			s = avm_tostring(func);
			avm_error("call: can not bind '%s' to function!\n", s);
			free(s);
			executionFinished = 1;
		}
}
예제 #7
0
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);
}
예제 #8
0
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]);
	}
}
예제 #9
0
double mod_impl(double x, double y){
	if(y == 0)
		{
		avm_error("Can not mod with 0!\n");
		executionFinished = 1;
		}
	else
		{
		return ((unsigned) x) % ((unsigned) y);
		}
}
예제 #10
0
double div_impl(double x, double y){
	if(y == 0)
		{
		avm_error("Can not div with 0!\n");
		executionFinished = 1;
		}
	else
		{
		return x / y;
		}
}
예제 #11
0
void execute_tablesetelem(instruction* instr){
	//printf("exec_tableset\n");
	avm_memcell* t = avm_translate_operand(&instr->arg1,(avm_memcell*) 0);
	avm_memcell* i = avm_translate_operand(&instr->arg2,&ax);
	avm_memcell* c = avm_translate_operand(&instr->result,&bx);
	assert(t && &stack[AVM_STACKSIZE-1] >= t && t > &stack[top]);
	assert(i && c);
	if(t->type != table_m)
		avm_error("illigal use of type as table!");
	else
		avm_tablesetelem(t->data.tableVal, i, c);
}
예제 #12
0
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;
}
예제 #13
0
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);
	}
}
예제 #14
0
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];
}
예제 #15
0
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);
	}
}
예제 #16
0
void execute_tablesetelem (instruction* instr){
	avm_memcell* t = avm_translate_operand(&instr->result, (avm_memcell*) 0);
	avm_memcell* i = avm_translate_operand(&instr->arg1, &ax);
	avm_memcell* c = avm_translate_operand(&instr->arg2, &bx);

//	assert(t && &stack[N-1] >= t && t > &stack[top]);
	assert(i && c);

	if(t->type != table_m)
		{
		avm_error("illegal use of type %s as table!\n", typeStrings[t->type]);
		executionFinished = 1;
		}
	else
		{
		avm_tablesetelem(t->data.tableVal, i, c);
		}
}
예제 #17
0
void avm_calllibfunc(char *id){
    library_func_t f = avm_getlibraryfunc(id);

    if(!f){
        avm_error("unsupported lib func");
        executionFinished = 1;
    }else{
        topsp = top;
        totalActuals = 0;

        (*f)();

        if(!executionFinished)
            execute_funcexit(NULL);
    }

    return;
}
예제 #18
0
void avm_calllibfunc(char* funcName){
	library_func_t f = avm_getlibraryfunc(funcName);	

	if(!f)
		{
		avm_error("unsupported lib func '%s' called!\n", funcName);
		executionFinished = 1;
		}
	else
		{
		topsp = top;
		totalActuals = 0;
		(*f)();
		if(!executionFinished)
			{
			execute_funcexit((instruction*) 0);
			}
		}
}
예제 #19
0
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);
}
예제 #20
0
void execute_jne (instruction* instr){
	assert(instr->result.type == label_a);

	avm_memcell* rv1 = avm_translate_operand(&instr->arg1, &ax);
	avm_memcell* rv2 = avm_translate_operand(&instr->arg2, &bx);

	unsigned char result = 0;

	if(rv1->type == undef_m){
                rv1->type=number_m;
        }
        if(rv2->type == undef_m){
                rv1->type=number_m;
        }

	if((rv1->type == undef_m)||(rv2->type == undef_m))
		{
		avm_error("'undef' involved in equality!\n");
		executionFinished = 1;
		}
	else if((rv1->type == nil_m)||(rv2->type == nil_m))
		{
		result = (rv1->type == nil_m) && (rv2->type == nil_m);
		}
	else if((rv1->type == bool_m)||(rv2->type == bool_m))
		{
		result = (avm_tobool(rv1) == avm_tobool(rv2));
		}
	else if(rv1->type != rv2->type)
		{
		avm_error("%s == %s is illegal!\n", typeStrings[rv1->type], typeStrings[rv2->type]);
		executionFinished = 1;
		}
	else if(rv1->type == number_m)
		{
		if(rv1->data.numVal != rv2->data.numVal)
			{
			result = 1;
			}
		}
	else if(rv1->type == string_m)
		{
		if(strcmp(rv1->data.strVal, rv2->data.strVal) != 0)
			{
			result = 1;
			}
		}
	else if(rv1->type == table_m)
		{
		if(rv1->data.tableVal->total != rv2->data.tableVal->total)
			{
			result = 1;
			}
		}
	else if(rv1->type == userfunc_m)
		{
		// ?
		}
	else if(rv1->type == libfunc_m)
		{
		// ?
		}

	if(!executionFinished && result)
		{
		pc = instr->result.val;
		}
}
예제 #21
0
double div_impl( double x, double y ) {
    if( y == 0) {
        avm_error("Error:Division with zero attempted.\n");
    }
    return x/y;
}
예제 #22
0
double mod_impl( double x, double y ) {
    if( y == 0) {
        avm_error("Error:Division with zero attempted.\n");
    }
    return (( unsigned ) x ) % (( unsigned ) y );
}