Exemplo n.º 1
0
Value AST_eval(AST_Node root)
{
    if (root == NULL) return NOTHING;

    Value vl;
    Value vr;
    Value result;

    if ((root->v.type == OP)) {
        if (root->v.u.op != PAREN) {
            vl = AST_eval(root->left);
            vr = AST_eval(root->right);
            result = Value_combine(vl, root->v.u.op, vr);
            Value_free(&vl);
            Value_free(&vr);
            return result;
        } else {
            return AST_eval(root->right);
        }
    } else if (root->v.type == RELAT_OP) {
        vl = AST_eval(root->left);
        vr = AST_eval(root->right);
        result = Value_relate(vl, root->v.u.rop, vr);
        Value_free(&vl);
        Value_free(&vr);
        return result;
    } else {
        return Value_copy(root->v);
    }
}
Exemplo n.º 2
0
Value* Expression_eval(Expression* expr, Context* ctx) {
	Value* ret;
	Variable* var = expr->var;
	
	if(var->type == VAR_VALUE) {
		/* Evaluate right side */
		ret = Value_eval(var->val, ctx);
		
		/* If an error occurred, bail */
		if(ret->type == VAL_ERR)
			return ret;
		
		/* Variable assignment? */
		if(ret->type == VAL_VAR) {
			/* This means ret must be a function */
			Variable* func = Variable_get(ctx, ret->name);
			if(func == NULL) {
				Value* err = ValErr(varNotFound(ret->name));
				Value_free(ret);
				return err;
			}
			
			if(func->type == VAR_BUILTIN) {
				Value_free(ret);
				return ValErr(typeError("Cannot assign a variable to a builtin value."));
			}
			
			if(var->name != NULL) {
				Context_setGlobal(ctx, var->name, Variable_copy(func));
			}
		}
		else {
			/* This means ret must be a Value */
			Value_free(var->val);
			var->val = Value_copy(ret);
			
			/* Update ans */
			Context_setGlobal(ctx, "ans", Variable_copy(var));
			
			/* Save the newly evaluated variable */
			if(var->name != NULL)
				Context_setGlobal(ctx, var->name, Variable_copy(var));
		}
	}
	else if(var->type == VAR_FUNC) {
		ret = ValVar(var->name);
		Context_setGlobal(ctx, var->name, Variable_copy(var));
	}
	else {
		badVarType(var->type);
	}
	
	return ret;
}
Exemplo n.º 3
0
Arquivo: eval.c Projeto: 7hens/yas
void Interpreter_free () {
	Interpreter i = __interpreterTable;
	if (!i) return;
	while (i = i->next) {
		__interpreterTable->next = i->next;
		Value_free(i->filePath);
		Procedure_free(i->proc);
		Value_free(i->result);
		free(i);
	}
	free(__interpreterTable);
}
Exemplo n.º 4
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));
}
Exemplo n.º 5
0
static Value* eval_abs(const Context* ctx, const ArgList* arglist, bool internal) {
	if(arglist->count != 1) {
		return ValErr(builtinArgs("abs", 1, arglist->count));
	}
	
	Value* val = Value_coerce(arglist->args[0], ctx);
	if(val->type == VAL_ERR) {
		return val;
	}
	
	Value* ret;
	switch(val->type) {
		case VAL_INT:
			ret = ValInt(ABS(val->ival));
			break;
		
		case VAL_REAL:
			ret = ValReal(ABS(val->rval));
			break;
		
		case VAL_FRAC:
			ret = ValFrac(Fraction_new(ABS(val->frac->n), val->frac->d));
			break;
			
		case VAL_VEC:
			ret = Vector_magnitude(val->vec, ctx);
			break;
		
		default:
			badValType(val->type);
	}
	
	Value_free(val);
	return ret;
}
Exemplo n.º 6
0
void AST_free(AST_Node *root)
{
    if (root == NULL || *root == NULL) return;
    AST_free(&(*root)->left);
    AST_free(&(*root)->right);
    Value_free(&(*root)->v);
    free(*root);
}
Exemplo n.º 7
0
void Control_msg_release(Control_msg * msg)
{
  if (msg->label) {
    String_free(&msg->label);
  }

  Value_free(msg->value);
  Mem_free(msg);
}
Exemplo n.º 8
0
void UnOp_free(UnOp* term) {
	if(!term) return;
	
	if(term->a) {
		Value_free(term->a);
	}
	
	free(term);
}
Exemplo n.º 9
0
/* Destructor */
void Dictionary_free(SCDictionary* self) {
	SCDictionary* temp;
	self = _Dictionary_findSelf(self);
	while (self) {
		temp = self->tree_right;
		if (self->key) {
			SCFree(self->key);
			Value_free(self->value);
		}
		SCFree(self);
		self = temp;
	}
}
Exemplo n.º 10
0
void AST_replace_vars(AST_Node root, Env e)
{
    if (root == NULL) return;

    if (root->v.type == VAR) {
        Value v = Env_find(e, root->v.u.name);
        if (v.type != NONE) {
            Value_free(&(root->v));
            root->v = Value_copy(v);
        }
    }

    AST_replace_vars(root->left, e);
    AST_replace_vars(root->right, e);
}
Exemplo n.º 11
0
Value* UnOp_eval(const UnOp* term, const Context* ctx) {
	if(!term) {
		return ValErr(nullError());
	}
	
	Value* a = Value_coerce(term->a, ctx);
	if(a->type == VAL_ERR) {
		return a;
	}
	
	Value* ret = _unop_table[term->type](ctx, a);
	
	Value_free(a);
	return ret;
}
Exemplo n.º 12
0
static Value* subscriptVector(Value* val, const char** expr, parser_cb* cb) {
	/* Move past the '[' character */
	(*expr)++;
	
	/* Parse inside of brackets */
	Value* index = Value_parse(expr, 0, ']', cb);
	if(index->type == VAL_ERR) {
		Value_free(val);
		return index;
	}
	
	/* Use builtin function from vector.c */
	TP(tp);
	return TP_FILL(tp, "@elem(@@, @@)", val, index);
}
Exemplo n.º 13
0
static Value* eval_dot(Context* ctx, ArgList* arglist) {
	if(arglist->count != 2) {
		/* Two vectors are required for a dot product */
		return ValErr(builtinArgs("dot", 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."));
	}
	
	unsigned count = vector1->vec->vals->count;
	if(count != vector2->vec->vals->count) {
		/* Both vectors must have the same number of values */
		return ValErr(mathError("Vectors must have the same dimensions for dot product."));
	}
	
	Value* total = ValInt(0); // store the total value of the dot product
	
	unsigned i;
	for(i = 0; i < count; i++) {
		/* Multiply v1[i] and v2[i] */
		BinOp* mul = BinOp_new(BIN_MUL, Value_copy(vector1->vec->vals->args[i]), Value_copy(vector2->vec->vals->args[i]));
		
		Value* part = BinOp_eval(mul, ctx);
		BinOp_free(mul);
		
		/* Accumulate the sum for all products */
		BinOp* add = BinOp_new(BIN_ADD, part, total);
		total = BinOp_eval(add, ctx);
		BinOp_free(add);
	}
	
	return total;
}
Exemplo n.º 14
0
static Value* callFunc(Value* val, const char** expr, parser_cb* cb) {
	/* Ugly, but parses better. Only variables and the results of calls can be funcs */
	if(val->type != VAL_VAR && val->type != VAL_CALL && val->type != VAL_PLACE) {
		return val;
	}
	
	/* Move past the opening parenthesis */
	(*expr)++;
	
	ArgList* args = ArgList_parse(expr, ',', ')', cb);
	if(args == NULL) {
		Value_free(val);
		return ValErr(ignoreError());
	}
	
	return ValCall(FuncCall_new(val, args));
}
Exemplo n.º 15
0
Value* Value_coerce(const Value* val, const Context* ctx) {
	Value* ret = Value_eval(val, ctx);
	
	if(ret->type == VAL_VAR) {
		Variable* var = Variable_get(ctx, ret->name);
		
		if(var == NULL) {
			Value* tmp = ValErr(varNotFound(ret->name));
			Value_free(ret);
			ret = tmp;
		}
		else {
			ret = Variable_coerce(var, ctx);
		}
	}
	
	return ret;
}
Exemplo n.º 16
0
/* Value Setting */
void Dictionary_setValueForKey(SCDictionary* self, SCValue* value, const char* key) {
	SCDictionary* temp = _Dictionary_findKey(self, key);
	if (temp) {
		Value_free(temp->value);
		temp->value = value;
		return;
	}
	temp = _Dictionary_findLast(self);
	if (temp == self && !temp->key) {
		self->key = strdup(key);
		self->value = value;
		return;
	}
	self = Dictionary_new();
	self->tree_left = temp;
	temp->tree_right = self;
	self->key = strdup(key);
	self->value = value;
}
Exemplo n.º 17
0
static Expression* parseExpr(const char** expr) {
	Variable* var;
	Value* val = Value_parse(expr, 0, 0);
	
	if(val->type == VAL_END) {
		var = VarErr(ignoreError());
	}
	else if(val->type == VAL_ERR) {
		Error* err = Error_copy(val->err);
		var = VarErr(err);
	}
	else {
		var = VarValue(NULL, Value_copy(val));
	}
	
	Value_free(val);
	
	return Expression_new(var);
}
Exemplo n.º 18
0
int main(int argc, char* argv[]) {
	Context* ctx = Context_new();
	register_math(ctx);
	
	for(nextLine(); !feof(stdin); nextLine()) {
		/* Strip trailing newline */
		char* end;
		if((end = strchr(line, '\n')) != NULL) *end = '\0';
		if((end = strchr(line, '\r')) != NULL) *end = '\0';
		if((end = strchr(line, '#')) != NULL) *end = '\0';
		
		const char* p = line;
		
		/* Get verbosity level */
		int verbose = 0;
		while(p[0] == '?') {
			verbose++;
			p++;
		}
		trimSpaces(&p);
		
		if(*p == '~') {
			/* Variable deletion */
			p++;
			
			char* name = nextToken(&p);
			if(name == NULL) {
				/* '~~~' means reset interpreter */
				if(p[0] == '~' && p[1] == '~') {
					/* Wipe out context */
					Context_free(ctx);
					ctx = Context_new();
					register_math(ctx);
					continue;
				}
				
				if(*p == '\0') {
					RAISE(earlyEnd());
					continue;
				}
				
				RAISE(badChar(*p));
				continue;
			}
			
			Context_del(ctx, name);
			
			free(name);
			
			continue;
		}
		
		/* Parse the user's input */
		Expression* expr = Expression_parse(&p);
		
		/* Print expression depending on verbosity */
		Expression_print(expr, ctx, verbose);
		
		/* Error? Go to next loop iteration */
		if(Expression_didError(expr)) {
			Expression_free(expr);
			continue;
		}
		
		/* Evaluate expression */
		Value* result = Expression_eval(expr, ctx);
		Expression_free(expr);
		
		/* Print result */
		Value_print(result, ctx);
		
		Value_free(result);
	}
	
	Context_free(ctx);
	
	return 0;
}
Exemplo n.º 19
0
Expression* Expression_parse(const char** expr) {
	Expression* ret = NULL;
	Variable* var;
	Value* val;
	
	const char* equals = strchr(*expr, '=');
	
	if(equals == NULL) {
		/* No assignment, just a plain expression. */
		return parseExpr(expr);
	}
	
	/* There is an assignment */
	/* First, parse the right side of the assignment */
	equals++;
	val = Value_parse(&equals, 0, 0);
	
	if(val->type == VAL_ERR) {
		/* A parse error occurred */
		var = VarErr(Error_copy(val->err));
		Value_free(val);
		return Expression_new(var);
	}
	
	if(val->type == VAL_END) {
		/* Empty input */
		Value_free(val);
		var = VarErr(earlyEnd());
		return Expression_new(var);
	}
	
	/* Now parse the left side */
	char* name = nextToken(expr);
	if(name == NULL) {
		Value_free(val);
		var = VarErr(syntaxError("No variable to assign to."));
		return Expression_new(var);
	}
	
	trimSpaces(expr);
	
	if(**expr == '(') {
		/* Defining a function */
		(*expr)++;
		
		/* Array of argument names */
		unsigned size = 2;
		char** args = fmalloc(size * sizeof(*args));
		unsigned len = 0;
		
		/* Add each argument name to the array */
		char* arg = nextToken(expr);
		
		if(arg == NULL && **expr != ')') {
			/* Invalid character */
			Value_free(val);
			free(args);
			free(name);
			
			var = VarErr(badChar(**expr));
			return Expression_new(var);
		}
		
		trimSpaces(expr);
		
		if(arg == NULL) {
			/* Empty parameter list means function with no args */
			free(args);
			args = NULL;
			len = 0;
		}
		else {
			/* Loop through each argument in the list */
			while(**expr == ',' || **expr == ')') {
				args[len++] = arg;
				
				if(**expr == ')')
					break;
				
				(*expr)++;
				
				/* Expand argument array if it's too small */
				if(len >= size) {
					size *= 2;
					args = frealloc(args, size * sizeof(*args));
				}
				
				arg = nextToken(expr);
				if(arg == NULL) {
					/* Invalid character */
					Value_free(val);
					free(name);
					/* Free argument names and return */
					unsigned i;
					for(i = 0; i < len; i++) {
						free(args[i]);
					}
					free(args);
					
					var = VarErr(badChar(**expr));
					return Expression_new(var);
				}
				
				trimSpaces(expr);
			}
		}
		
		if(**expr != ')') {
			/* Invalid character inside argument name list */
			Value_free(val);
			free(name);
			
			/* Free argument names and return */
			unsigned i;
			for(i = 0; i < len; i++) {
				free(args[i]);
			}
			free(args);
			
			var = VarErr(badChar(**expr));
			return Expression_new(var);
		}
		
		/* Skip closing parenthesis */
		(*expr)++;
		trimSpaces(expr);
		
		if(**expr != '=') {
			Value_free(val);
			free(name);
			
			unsigned i;
			for(i = 0; i < len; i++) {
				free(args[i]);
			}
			free(args);
			
			var = VarErr(badChar(**expr));
			return Expression_new(var);
		}
		
		/* Construct function and return it */
		Function* func = Function_new(len, args, val);
		var = VarFunc(name, func);
		free(name);
		
		ret = Expression_new(var);
	}
	else {
		/* Defining a variable */
		if(**expr != '=') {
			/* In-place manipulation */
			BINTYPE bin = BinOp_nextType(expr, 0, 0);
			
			/* Still not an equals sign means invalid character */
			if(**expr != '=') {
				Value_free(val);
				free(name);
				
				var = VarErr(badChar(**expr));
				return Expression_new(var);
			}
			
			val = ValExpr(BinOp_new(bin, ValVar(name), val));
		}
		
		var = VarValue(name, val);
		free(name);
		
		ret = Expression_new(var);
	}
	
	return ret;
}
Exemplo n.º 20
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));
}
Exemplo n.º 21
0
Value* Value_parse(const char** expr, char sep, char end, parser_cb* cb) {
	Value* val;
	BINTYPE op = BIN_UNK;
	BinOp* tree = NULL;
	BinOp* prev;
	
	while(1) {
		/* Get next value */
		val = Value_next(expr, end, cb);
		
		/* Error parsing next value? */
		if(val->type == VAL_ERR) {
			if(tree) {
				BinOp_free(tree);
			}
			
			return val;
		}
		
		/* End of input? */
		if(val->type == VAL_END) {
			if(tree) {
				BinOp_free(tree);
			}
			
			return val;
		}
		
		/* Special case: negative value */
		if(val->type == VAL_NEG) {
			Value_free(val);
			
			BinOp* cur = BinOp_new(BIN_MUL, ValInt(-1), NULL);
			
			if(tree) {
				prev->b = ValExpr(cur);
			}
			else {
				tree = cur;
			}
			
			prev = cur;
			continue;
		}
		
		/* Get next operator if it exists */
		op = BinOp_nextType(expr, sep, end);
		
		/* Invalid operator? Return syntax error */
		if(op == BIN_UNK) {
			/* Exit gracefully and return error */
			if(tree) {
				BinOp_free(tree);
			}
			
			Value_free(val);
			return ValErr(badChar(**expr));
		}
		/* End of the statement? */
		else if(op == BIN_END) {
			/* Only skip end character if there's only one value to parse */
			if(!sep && **expr && **expr == end) {
				(*expr)++;
			}
			
			/* If there was only one value, return it */
			if(!tree) {
				return val;
			}
			
			/* Otherwise, place the final value into the tree and break out of the parse loop */
			prev->b = val;
			break;
		}
		
		/* Tree not yet begun? Initialize it! */
		if(tree == NULL) {
			tree = BinOp_new(op, val, NULL);
			prev = tree;
		}
		else {
			/* Tree already started, so add to it */
			treeAddValue(&tree, &prev, op, val);
		}
	}
	
	return ValExpr(tree);
}