コード例 #1
0
ファイル: vector.c プロジェクト: 0xaced/SuperCalc
Value* Vector_eval(const Vector* vec, const Context* ctx) {
    ArgList* args = ArgList_eval(vec->vals, ctx);
    if(args == NULL) {
        return ValErr(ignoreError());
    }
    return ValVec(Vector_new(args));
}
コード例 #2
0
ファイル: vector.c プロジェクト: 0xaced/SuperCalc
static Value* vecCompOp(const Vector* vector1, const Vector* vector2, const Context* ctx, BINTYPE bin) {
    unsigned count = vector1->vals->count;
    if(count != vector2->vals->count && vector2->vals->count > 1) {
        return ValErr(mathError("Cannot %s vectors of different sizes.", binop_verb[bin]));
    }

    ArgList* newv = ArgList_new(count);

    unsigned i;
    for(i = 0; i < count; i++) {
        /* Perform the specified operation on each matching component */
        Value* val2;
        if(vector2->vals->count == 1) {
            val2 = vector2->vals->args[0];
        }
        else {
            val2 = vector2->vals->args[i];
        }

        BinOp* op = BinOp_new(bin, Value_copy(vector1->vals->args[i]), Value_copy(val2));
        Value* result = BinOp_eval(op, ctx);
        BinOp_free(op);

        /* Error checking */
        if(result->type == VAL_ERR) {
            ArgList_free(newv);
            return result;
        }

        /* Store result */
        newv->args[i] = result;
    }

    return ValVec(Vector_new(newv));
}
コード例 #3
0
static Value* eval_map(Context* ctx, ArgList* arglist) {
	if(arglist->count != 2) {
		return ValErr(builtinArgs("map", 2, arglist->count));
	}
	
	Value* func = Value_copy(arglist->args[0]);
	if(func->type != VAL_VAR) {
		Value* val = Value_eval(func, ctx);
		Value_free(func);
		
		if(val->type == VAL_ERR)
			return val;
		
		if(val->type != VAL_VAR) {
			Value_free(val);
			return ValErr(typeError("Builtin 'map' expects a callable as its first argument."));
		}
		
		func = val;
	}
	
	Value* vec = Value_eval(arglist->args[1], ctx);
	if(vec->type == VAL_ERR) {
		Value_free(func);
		return vec;
	}
	
	if(func->type != VAL_VAR) {
		Value_free(func);
		Value_free(vec);
		return ValErr(typeError("Builtin 'map' expects a callable as its first argument."));
	}
	
	if(vec->type != VAL_VEC) {
		Value_free(func);
		Value_free(vec);
		return ValErr(typeError("Builtin 'map' expects a vector as its second argument."));
	}
	
	ArgList* mapping = ArgList_new(vec->vec->vals->count);
	
	/* Don't evaluate the call now. Let Builtin_eval do this for us */
	unsigned i;
	for(i = 0; i < mapping->count; i++) {
		ArgList* arg = ArgList_create(1, Value_copy(vec->vec->vals->args[i]));
		Value* call = ValCall(FuncCall_new(func->name, arg));
		
		mapping->args[i] = call;
	}
	
	Value_free(func);
	Value_free(vec);
	
	return ValVec(Vector_new(mapping));
}
コード例 #4
0
ファイル: value.c プロジェクト: C0deH4cker/SuperCalc
Value* Value_copy(const Value* val) {
	Value* ret;
	
	switch(val->type) {
		case VAL_INT:
			ret = ValInt(val->ival);
			break;
		
		case VAL_REAL:
			ret = ValReal(val->rval);
			break;
		
		case VAL_FRAC:
			ret = ValFrac(Fraction_copy(val->frac));
			break;
		
		case VAL_EXPR:
			ret = ValExpr(BinOp_copy(val->expr));
			break;
		
		case VAL_CALL:
			ret = ValCall(FuncCall_copy(val->call));
			break;
		
		case VAL_UNARY:
			ret = ValUnary(UnOp_copy(val->term));
			break;
		
		case VAL_VAR:
			ret = ValVar(val->name);
			break;
		
		case VAL_VEC:
			ret = ValVec(Vector_copy(val->vec));
			break;
		
		case VAL_NEG:
			/* Shouldn't be reached, but so easy to code */
			ret = ValNeg();
			break;
		
		case VAL_ERR:
			ret = ValErr(Error_copy(val->err));
			break;
		
		default:
			typeError("Unknown value type: %d.", val->type);
			ret = NULL;
			break;
	}
	
	return ret;
}
コード例 #5
0
Value* Vector_parse(const char** expr) {
	ArgList* vals = ArgList_parse(expr, ',', '>');
	if(vals == NULL)
		return ValErr(ignoreError());
	
	if(vals->count < 2) {
		ArgList_free(vals);
		return ValErr(syntaxError("Vector must have at least 2 components."));
	}
	
	return ValVec(Vector_new(vals));
}
コード例 #6
0
ファイル: vector.c プロジェクト: 0xaced/SuperCalc
Value* Vector_parse(const char** expr, parser_cb* cb) {
    ArgList* vals = ArgList_parse(expr, ',', '>', cb);

    if(vals == NULL) {
        /* Error occurred and has already been raised */
        return ValErr(ignoreError());
    }

    if(vals->count < 1) {
        ArgList_free(vals);
        return ValErr(syntaxError("Vector must have at least 1 component."));
    }

    return ValVec(Vector_new(vals));
}
コード例 #7
0
ファイル: vector.c プロジェクト: 0xaced/SuperCalc
static Value* vecScalarOp(const Vector* vec, const Value* scalar, const Context* ctx, BINTYPE bin) {
    ArgList* newv = ArgList_new(vec->vals->count);

    unsigned i;
    for(i = 0; i < vec->vals->count; i++) {
        /* Perform operation */
        BinOp* op = BinOp_new(bin, Value_copy(vec->vals->args[i]), Value_copy(scalar));
        Value* result = BinOp_eval(op, ctx);
        BinOp_free(op);

        /* Error checking */
        if(result->type == VAL_ERR) {
            ArgList_free(newv);
            return result;
        }

        /* Store result */
        newv->args[i] = result;
    }

    return ValVec(Vector_new(newv));
}
コード例 #8
0
Value* Vector_eval(Vector* vec, Context* ctx) {
	return ValVec(Vector_new(ArgList_eval(vec->vals, ctx)));
}
コード例 #9
0
static Value* eval_cross(Context* ctx, ArgList* arglist) {
	if(arglist->count != 2) {
		/* Two vectors are required for a cross product */
		return ValErr(builtinArgs("cross", 2, arglist->count));
	}
	
	Value* vector1 = Value_eval(arglist->args[0], ctx);
	if(vector1->type == VAL_ERR) {
		return vector1;
	}
	
	Value* vector2 = Value_eval(arglist->args[1], ctx);
	if(vector2->type == VAL_ERR) {
		Value_free(vector1);
		return vector2;
	}
	
	if(vector1->type != VAL_VEC || vector2->type != VAL_VEC) {
		/* Both values must be vectors */
		return ValErr(typeError("Builtin dot expects two vectors."));
	}
	
	if(vector1->vec->vals->count != 3) {
		/* Vectors must each have a size of 3 */
		return ValErr(mathError("Vectors must each have a size of 3 for cross product."));
	}
	
	/* First cross multiplication */
	BinOp* i_pos_op = BinOp_new(BIN_MUL, Value_copy(vector1->vec->vals->args[1]), Value_copy(vector2->vec->vals->args[2]));
	BinOp* i_neg_op = BinOp_new(BIN_MUL, Value_copy(vector1->vec->vals->args[2]), Value_copy(vector2->vec->vals->args[1]));
	
	/* Evaluate multiplications */
	Value* i_pos = BinOp_eval(i_pos_op, ctx);
	Value* i_neg = BinOp_eval(i_neg_op, ctx);
	
	BinOp_free(i_pos_op);
	BinOp_free(i_neg_op);
	
	/* Error checking */
	if(i_pos->type == VAL_ERR) {
		Value_free(vector1);
		Value_free(vector2);
		Value_free(i_neg);
		return i_pos;
	}
	if(i_neg->type == VAL_ERR) {
		Value_free(vector1);
		Value_free(vector2);
		Value_free(i_pos);
		return i_neg;
	}
	
	/* Subtract products */
	BinOp* i_op = BinOp_new(BIN_SUB, i_pos, i_neg);
	Value* i_val = BinOp_eval(i_op, ctx);
	BinOp_free(i_op);
	
	if(i_val->type == VAL_ERR) {
		Value_free(vector1);
		Value_free(vector2);
		return i_val;
	}
	
	/* Part 2 */
	BinOp* j_pos_op = BinOp_new(BIN_MUL, Value_copy(vector1->vec->vals->args[0]), Value_copy(vector2->vec->vals->args[2]));
	BinOp* j_neg_op = BinOp_new(BIN_MUL, Value_copy(vector1->vec->vals->args[2]), Value_copy(vector2->vec->vals->args[0]));
	
	Value* j_pos = BinOp_eval(j_pos_op, ctx);
	Value* j_neg = BinOp_eval(j_neg_op, ctx);
	
	BinOp_free(j_pos_op);
	BinOp_free(j_neg_op);
	
	if(j_pos->type == VAL_ERR) {
		Value_free(vector1);
		Value_free(vector2);
		Value_free(j_neg);
		return j_pos;
	}
	if(j_neg->type == VAL_ERR) {
		Value_free(vector1);
		Value_free(vector2);
		Value_free(j_pos);
		return j_neg;
	}
	
	BinOp* j_op = BinOp_new(BIN_SUB, j_pos, j_neg);
	Value* j_val = BinOp_eval(j_op, ctx);
	BinOp_free(j_op);
	
	if(j_val->type == VAL_ERR) {
		Value_free(vector1);
		Value_free(vector2);
		return j_val;
	}
	
	/* Part 3 */
	BinOp* k_pos_op = BinOp_new(BIN_MUL, Value_copy(vector1->vec->vals->args[0]), Value_copy(vector2->vec->vals->args[1]));
	BinOp* k_neg_op = BinOp_new(BIN_MUL, Value_copy(vector1->vec->vals->args[1]), Value_copy(vector2->vec->vals->args[0]));
	
	Value* k_pos = BinOp_eval(k_pos_op, ctx);
	Value* k_neg = BinOp_eval(k_neg_op, ctx);
	
	BinOp_free(k_pos_op);
	BinOp_free(k_neg_op);
	
	if(k_pos->type == VAL_ERR) {
		Value_free(vector1);
		Value_free(vector2);
		Value_free(k_neg);
		return k_pos;
	}
	if(k_neg->type == VAL_ERR) {
		Value_free(vector1);
		Value_free(vector2);
		Value_free(k_pos);
		return k_neg;
	}
	
	BinOp* k_op = BinOp_new(BIN_SUB, k_pos, k_neg);
	Value* k_val = BinOp_eval(k_op, ctx);
	BinOp_free(k_op);
	
	if(k_val->type == VAL_ERR) {
		Value_free(vector1);
		Value_free(vector2);
		return k_val;
	}
	
	ArgList* args = ArgList_create(3, i_val, j_val, k_val);
	return ValVec(Vector_new(args));
}
コード例 #10
0
ファイル: reifiedoutput_impl.cpp プロジェクト: RayHuo/iASP
	void RulePrinter::end()
	{
		uint32_t body = output_->addSet();
		output_->popSet();
		const ReifiedOutput::Set &head = output_->getSet();
		assert(head.size() <= 1);
		out() << "rule(";
		if(head.empty()) { out() << "pos(false)"; }
		else             { output_->val(head.front()).print(output()->storage(), out()); }
		out() << ",pos(conjunction(" << body << "))).\n";
		Val val;
		val = Val::create(Val::NUM, int(body));
		val = Val::create(Val::FUNC, output_->storage()->index(Func(output_->storage(), output_->storage()->index("conjunction"), ValVec(1, val))));
		val = Val::create(Val::FUNC, output_->storage()->index(Func(output_->storage(), output_->storage()->index("pos"), ValVec(1, val))));
		size_t conjunction = output_->symbol(val);
		output_->popSet();
		output_->addDep(conjunction, 2);
		output_->popDep(true, 2); // lits -> body -> head
		output_->popDep(false);
	}
コード例 #11
0
ファイル: reifiedoutput_impl.cpp プロジェクト: RayHuo/iASP
	void JunctionAggrLitPrinter::end()
	{
		if(head_)
		{
			if(output_->getSet().size() == 1)
			{
				size_t sym = output_->getSet().back();
				output_->popSet();
				output_->addToSet(sym);
			}
			else if(output_->getSet().size() > 0)
			{
				uint32_t set = output_->addSet();
				output_->popSet();
				Val val;
				val = Val::create(Val::NUM, (int)set);
				val = Val::create(Val::FUNC, output_->storage()->index(Func(output_->storage(), output_->storage()->index("disjunction"), ValVec(1, val))));
				val = Val::create(Val::FUNC, output_->storage()->index(Func(output_->storage(), output_->storage()->index("pos"), ValVec(1, val))));
				output_->addToSet(output_->symbol(val));
			}
			else { output_->popSet(); }
		}
	}
コード例 #12
0
ファイル: reifiedoutput_impl.cpp プロジェクト: RayHuo/iASP
	void ParityAggrLitPrinter::end()
	{
		uint32_t list = output_->addList();
		output_->popList();
		Val val;
		val = Val::create(Val::NUM, (int)list);
		val = Val::create(Val::FUNC, output_->storage()->index(Func(output_->storage(), output_->storage()->index(even_ ? "even" : "odd"), ValVec(1, val))));
		val = Val::create(Val::FUNC, output_->storage()->index(Func(output_->storage(), output_->storage()->index(sign_ ? "neg" : "pos"), ValVec(1, val))));
		size_t parity = output_->symbol(val);
		output_->addToSet(parity);
		if(!head_ && !sign_)
		{
			output_->addDep(parity, 2);
			output_->popDep(true);
			output_->popDep(false);
			output_->addDep(parity);
		}
	}
コード例 #13
0
ファイル: reifiedoutput_impl.cpp プロジェクト: RayHuo/iASP
	void MinMaxAggrLitPrinter::end()
	{
		uint32_t list = output_->addList();
		output_->popList();
		ValVec vals;
		vals.push_back(hasLower_ ? lower_ : max_ ? Val::inf() : Val::sup());
		vals.push_back(Val::create(Val::NUM, (int)list));
		vals.push_back(hasUpper_ ? upper_ : max_ ? Val::sup() : Val::inf());
		Val val;
		val = Val::create(Val::FUNC, output_->storage()->index(Func(output_->storage(), output_->storage()->index(max_ ? "max" : "min"), vals)));
		val = Val::create(Val::FUNC, output_->storage()->index(Func(output_->storage(), output_->storage()->index(sign_ ? "neg" : "pos"), ValVec(1, val))));
		size_t minmax = output_->symbol(val);
		output_->addToSet(minmax);
		if(!head_ && !sign_)
		{
			if((hasLower_ && max_) || (hasUpper_ && !max_))
			{
				output_->addDep(minmax, 2);
				output_->popDep(true);
				output_->popDep(false);
				output_->addDep(minmax);
			}
			else { output_->popDep(false, 2); }
		}
	}
コード例 #14
0
ファイル: reifiedoutput_impl.cpp プロジェクト: RayHuo/iASP
	void AvgAggrLitPrinter::end()
	{
		uint32_t list = output_->addList();
		output_->popList();
		ValVec vals;
		vals.push_back(Val::create(Val::NUM, hasLower_ ? lower_ : min_));
		vals.push_back(Val::create(Val::NUM, (int)list));
		vals.push_back(Val::create(Val::NUM, hasUpper_ ? upper_ : max_));
		Val val;
		val = Val::create(Val::FUNC, output_->storage()->index(Func(output_->storage(), output_->storage()->index("avg"), vals)));
		val = Val::create(Val::FUNC, output_->storage()->index(Func(output_->storage(), output_->storage()->index(sign_ ? "neg" : "pos"), ValVec(1, val))));
		size_t avg = output_->symbol(val);
		output_->addToSet(avg);
		if(!head_ && !sign_)
		{
			output_->addDep(avg, 2);
			output_->popDep(true);
			output_->popDep(false);
			output_->addDep(avg);
		}
	}
コード例 #15
0
ファイル: reifiedoutput_impl.cpp プロジェクト: RayHuo/iASP
	void SumAggrLitPrinter::end()
	{
		uint32_t list = output_->addList();
		output_->popList();
		ValVec vals;
		vals.push_back(Val::create(Val::NUM, hasLower_ ? lower_ : min_));
		vals.push_back(Val::create(Val::NUM, (int)list));
		vals.push_back(Val::create(Val::NUM, hasUpper_ ? upper_ : max_));
		Val val;
		val = Val::create(Val::FUNC, output_->storage()->index(Func(output_->storage(), output_->storage()->index("sum"), vals)));
		val = Val::create(Val::FUNC, output_->storage()->index(Func(output_->storage(), output_->storage()->index(sign_ ? "neg" : "pos"), ValVec(1, val))));
		size_t sum = output_->symbol(val);
		output_->addToSet(sum);
		if(!sign_ && !head_)
		{
			if(hasNeg_ || hasLower_)
			{
				output_->addDep(sum, 2);
				output_->popDep(true);
				output_->popDep(false);
				output_->addDep(sum);
			}
			else { output_->popDep(false, 2); }
		}
	}