private void Assign(Assignment assignment) { if (assignment.IsSimple) { if (assignment.IsGlobal) { this.env.Modify( assignment.Variable, this.evaluator.Evaluate(assignment.Value, this.env) ); } else { this.env.Declcare( assignment.Variable, this.evaluator.Evaluate(assignment.Value, this.env) ); } } else { List <string> accessor = assignment.AccesKey; ExpressionValue MainObject = this.env.Get(accessor [0]) as ExpressionValue; for (int i = 1; i < accessor.Count - 1; i++) { MainObject = MainObject.GetProperty(accessor [i]); } MainObject.SetProperty( accessor [accessor.Count - 1], this.evaluator.Evaluate(assignment.Value, env) ); } }
public ExpressionValue ExecuteFunction(Expression fun) { Function f = null; ExpressionValue obj = null; ExpressionValue last = null; if (fun.AccessKey == null) { f = this.env.Get(fun.FunctionName) as Function; } else { List <string> accessor = fun.AccessKey; obj = last = this.env.Get(accessor [0]) as ExpressionValue; for (int i = 1; i < accessor.Count; i++) { last = obj; obj = obj.GetProperty(accessor [i]); } f = obj.Function; } if (f == null) { if (this.IsSystemFunction(fun.FunctionName)) { return(this.ExecuteSystemFunction(fun)); } else { return(null); } } this.env.PushEnvironment(); for (int i = 0; i < fun.Parameters.Count; i++) { this.env.Declcare( f.ParametersNames [i], this.evaluator.Evaluate(fun.Parameters [i], this.env) ); } if (obj != null) { this.env.Declcare("this", last); } ExpressionValue ev = this.ExecuteStatements(f.InnerStatements); this.env.PopEnvironment(); return(ev); }
public ExpressionValue Evaluate(Expression exp, Environment env) { if (exp == null) { return(new ExpressionValue(ExpressionValueType.BOOLEAN, false)); } switch (exp.Type) { case (ExpressionType.FUNCTION): { return(this.vm.ExecuteFunction(exp)); } case (ExpressionType.FUNCTION_DECLARATION): { return(new ExpressionValue(ExpressionValueType.FUNCTION, exp.Function)); } case (ExpressionType.OBJECT): { return(new ExpressionValue(ExpressionValueType.OBJECT)); } case (ExpressionType.OBJECT_ACCESSOR): { List <string> accessor = exp.AccessKey; ExpressionValue v = env.Get(accessor [0]) as ExpressionValue; for (int i = 1; i < accessor.Count; i++) { v = v.GetProperty(accessor [i]); } return(v); } case (ExpressionType.IDENTIFIER): { string id = exp.Value; return(env.Get(id) as ExpressionValue); } case (ExpressionType.BOOL): { return(exp.EvaluatedValue); } case (ExpressionType.STRING): { return(exp.EvaluatedValue); } case (ExpressionType.INTEGER): { return(exp.EvaluatedValue); } case (ExpressionType.PLUS): { ExpressionValue v1 = this.Evaluate(exp.Expression1, env); ExpressionValue v2 = this.Evaluate(exp.Expression2, env); if (v1.IsString) { return(new ExpressionValue(ExpressionValueType.STRING, v1.String + v2.String)); } else { return(new ExpressionValue(ExpressionValueType.NUMBER, v1.Number + v2.Number)); } } case (ExpressionType.MINUS): { ExpressionValue v1 = this.Evaluate(exp.Expression1, env); ExpressionValue v2 = this.Evaluate(exp.Expression2, env); return(new ExpressionValue(ExpressionValueType.NUMBER, v1.Number - v2.Number)); } case (ExpressionType.TIMES): { ExpressionValue v1 = this.Evaluate(exp.Expression1, env); ExpressionValue v2 = this.Evaluate(exp.Expression2, env); return(new ExpressionValue(ExpressionValueType.NUMBER, v1.Number * v2.Number)); } case (ExpressionType.DIVISION): { ExpressionValue v1 = this.Evaluate(exp.Expression1, env); ExpressionValue v2 = this.Evaluate(exp.Expression2, env); return(new ExpressionValue(ExpressionValueType.NUMBER, v1.Number / v2.Number)); } case (ExpressionType.AND): { ExpressionValue v1 = this.Evaluate(exp.Expression1, env); ExpressionValue v2 = this.Evaluate(exp.Expression2, env); return(new ExpressionValue(ExpressionValueType.BOOLEAN, v1.Bool && v2.Bool)); } case (ExpressionType.OR): { ExpressionValue v1 = this.Evaluate(exp.Expression1, env); ExpressionValue v2 = this.Evaluate(exp.Expression2, env); return(new ExpressionValue(ExpressionValueType.BOOLEAN, v1.Bool || v2.Bool)); } case (ExpressionType.EQUAL): { ExpressionValue v1 = this.Evaluate(exp.Expression1, env); ExpressionValue v2 = this.Evaluate(exp.Expression2, env); return(new ExpressionValue(ExpressionValueType.BOOLEAN, (v1.Bool == v2.Bool) && (v1.Number == v2.Number) && (v1.String == v2.String))); } case (ExpressionType.DISEQUAL): { ExpressionValue v1 = this.Evaluate(exp.Expression1, env); ExpressionValue v2 = this.Evaluate(exp.Expression2, env); return(new ExpressionValue(ExpressionValueType.BOOLEAN, (v1.Bool != v2.Bool) && (v1.Number != v2.Number) && (v1.String != v2.String))); } case (ExpressionType.LESS): { ExpressionValue v1 = this.Evaluate(exp.Expression1, env); ExpressionValue v2 = this.Evaluate(exp.Expression2, env); return(new ExpressionValue(ExpressionValueType.BOOLEAN, v1.Number < v2.Number)); } case (ExpressionType.GREATER): { ExpressionValue v1 = this.Evaluate(exp.Expression1, env); ExpressionValue v2 = this.Evaluate(exp.Expression2, env); return(new ExpressionValue(ExpressionValueType.NUMBER, v1.Number > v2.Number)); } case (ExpressionType.LESS_OR_EQUAL): { ExpressionValue v1 = this.Evaluate(exp.Expression1, env); ExpressionValue v2 = this.Evaluate(exp.Expression2, env); return(new ExpressionValue(ExpressionValueType.NUMBER, v1.Number <= v2.Number)); } case (ExpressionType.GREATER_OR_EQUAL): { ExpressionValue v1 = this.Evaluate(exp.Expression1, env); ExpressionValue v2 = this.Evaluate(exp.Expression2, env); return(new ExpressionValue(ExpressionValueType.NUMBER, v1.Number >= v2.Number)); } default: return(null); } }