void EvalSubstitution(SubstitutionExpression expr, EvalOption option) { option = new EvalOption(); option.ForWriting = true; var target = Eval(expr.Target, option); var value = Eval(expr.Value, null); if (value is Attribute) { value = (value as Attribute).Value; } var targetAttribute = target as Attribute; if (targetAttribute == null) { throw new InvalidSubstitution(expr.Line); } if (value is Value) { targetAttribute.Value = value; } }
object EvalLabel(LabelExpression expr, EvalOption option) { if (!RootTable.Tables.ContainsKey(expr.Value)) { if (option != null && option.ForWriting) { var attribute = new Attribute(); RootTable.Tables[expr.Value] = attribute; } else { throw new UnknownValueException(expr.Value, expr.Line); } } return(RootTable.Tables[expr.Value]); }
object EvalAttribute(AttributeExpression expr, EvalOption option) { var value = Eval(expr.Value, option); if (value is Attribute) { value = (value as Attribute).Value; } var table = value as SymbolTable; if (table == null) { throw new UnknownValueException(expr.Attribute, expr.Line); } if (!table.Tables.ContainsKey(expr.Attribute)) { throw new UnknownValueException(expr.Attribute, expr.Line); } return(table.Tables[expr.Attribute]); }
object Eval(Expression expression, EvalOption option) { if (expression is AttributeExpression) { return(EvalAttribute(expression as AttributeExpression, option)); } else if (expression is SubstitutionExpression) { EvalSubstitution(expression as SubstitutionExpression, option); return(null); } else if (expression is LabelExpression) { return(EvalLabel(expression as LabelExpression, option)); } else if (expression is NumberExpression) { var expr = expression as NumberExpression; var value = new Value(); var node = new NodeConstantNumber(); node.Expression = expr; node.Value = expr.Value; node.Outputs.Add(value); value.Generator = node; value.Index = 0; return(value); } else if (expression is FunctionExpression) { return(EvalFunction(expression as FunctionExpression, option)); } else if (expression is BinOpExpression) { var expr = expression as BinOpExpression; var node = new NodeOperator(); node.Expression = expr; if (expr.Operator == "+") { node.Type = OperatorType.Add; } if (expr.Operator == "-") { node.Type = OperatorType.Sub; } if (expr.Operator == "*") { node.Type = OperatorType.Mul; } if (expr.Operator == "/") { node.Type = OperatorType.Div; } if (expr.Operator == "%") { node.Type = OperatorType.Mod; } var lhs = Eval(expr.Lhs, null); if (lhs is Attribute) { lhs = (lhs as Attribute).Value; } var rhs = Eval(expr.Rhs, null); if (rhs is Attribute) { rhs = (rhs as Attribute).Value; } if (lhs is SymbolTable) { var retTable = new SymbolTable(); int ind = 0; foreach (var table in (lhs as SymbolTable).Tables) { var ret = new Value(); ret.Index = ind; ret.Generator = node; node.Inputs.Add(table.Value.Value as Value); if (!(table.Value.Value is Value)) { throw new InvalidOperationException(expression.Line); } if (rhs is Value) { node.Inputs.Add(rhs as Value); } else if (rhs is SymbolTable) { var rhs_ = rhs as SymbolTable; if (!rhs_.Tables.ContainsKey(table.Key)) { throw new InvalidOperationException(expression.Line); } var value = rhs_.Tables[table.Key].Value as Value; if (value == null) { throw new InvalidOperationException(expression.Line); } node.Inputs.Add(value); } node.Outputs.Add(ret); retTable.Tables.Add(table.Key, new Attribute(ret)); ind++; } return(retTable); } else if (lhs is Value) { if (!(rhs is Value)) { throw new InvalidOperationException(expression.Line); } var ret = new Value(); ret.Index = 0; ret.Generator = node; node.Inputs.Add(lhs as Value); node.Inputs.Add(rhs as Value); node.Outputs.Add(ret); return(ret); } } else if (expression is UnaryOpExpression) { var expr = expression as UnaryOpExpression; var node = new NodeOperator(); if (expr.Operator == "+") { node.Type = OperatorType.UnaryAdd; } if (expr.Operator == "-") { node.Type = OperatorType.UnarySub; } var input = Eval(expr.Expr, null); if (input is Attribute) { input = (input as Attribute).Value; } if (input is SymbolTable) { var retTable = new SymbolTable(); int ind = 0; foreach (var table in (input as SymbolTable).Tables) { var ret = new Value(); ret.Index = ind; ret.Generator = node; if (!(table.Value.Value is Value)) { throw new InvalidOperationException(expression.Line); } node.Inputs.Add(table.Value.Value as Value); node.Outputs.Add(ret); retTable.Tables.Add(table.Key, new Attribute(ret)); ind++; } return(retTable); } else if (input is Value) { var ret = new Value(); ret.Index = 0; ret.Generator = node; node.Inputs.Add(input as Value); node.Outputs.Add(ret); return(ret); } } throw new Exception(); }
object EvalFunction(FunctionExpression expr, EvalOption option) { var inputs = new List <object>(); for (int i = 0; i < expr.Args.Length; i++) { var input = Eval(expr.Args[i], null); if (input is Attribute) { input = (input as Attribute).Value; } inputs.Add(input); } return(functionDefinitionCollection.Generate(expr, inputs.ToArray())); /* * var node = new NodeOperator(); * node.Expression = expr; * if (expr.Value == "sin") * { * node.Type = OperatorType.Sine; * if (expr.Args.Count() != 1) throw new ArgSizeException(expr.Args.Count(), 1, expr.Line); * } * * if (expr.Value == "cos") * { * node.Type = OperatorType.Cos; * if (expr.Args.Count() != 1) throw new ArgSizeException(expr.Args.Count(), 1, expr.Line); * } * * if (expr.Value == "rand") * { * node.Type = OperatorType.Rand; * * if (expr.Args.Count() == 0) * { * node.Type = OperatorType.Rand; * } * else if (expr.Args.Count() == 1) * { * node.Type = OperatorType.Rand_WithSeed; * } * else * { * throw new ArgSizeException(expr.Args.Count(), new[] { 0, 1 }, expr.Line); * } * } * * if(expr.Value == "step") * { * node.Type = OperatorType.Rand; * if (expr.Args.Count() != 1) throw new ArgSizeException(expr.Args.Count(), 2, expr.Line); * } * * // input * for (int i = 0; i < expr.Args.Length; i++) * { * var input = Eval(expr.Args[i], null); * if (input is Attribute) * { * input = (input as Attribute).Value; * } * * if (input is SymbolTable) * { * var retTable = new SymbolTable(); * int ind = 0; * foreach (var table in (input as SymbolTable).Tables) * { * if (!(table.Value.Value is Value)) * { * throw new InvalidOperationException(expr.Line); * } * * node.Inputs.Add(table.Value.Value as Value); * } * //return retTable; * } * else if (input is Value) * { * node.Inputs.Add(input as Value); * } * else * { * throw new Exception(); * } * } * * // output * if (expr.Args.Count() > 0) * { * var input = Eval(expr.Args[0], null); * if (input is Attribute) * { * input = (input as Attribute).Value; * } * * if (input is SymbolTable) * { * var retTable = new SymbolTable(); * int ind = 0; * foreach (var table in (input as SymbolTable).Tables) * { * var ret = new Value(); * ret.Index = ind; * ret.Generator = node; * node.Outputs.Add(ret); * retTable.Tables.Add(table.Key, new Attribute(ret)); * ind++; * } * return retTable; * } * else if (input is Value) * { * var ret = new Value(); * ret.Index = 0; * ret.Generator = node; * node.Outputs.Add(ret); * return ret; * } * else * { * throw new Exception(); * } * * } * else * { * var ret = new Value(); * ret.Index = 0; * ret.Generator = node; * node.Outputs.Add(ret); * return ret; * } */ }
object EvalFunction(FunctionExpression expr, EvalOption option) { var node = new NodeOperator(); node.Expression = expr; if (expr.Value == "sin") { node.Type = OperatorType.Sine; } if (expr.Value == "cos") { node.Type = OperatorType.Cos; } if (expr.Args.Count() != 1) { throw new ArgSizeException(expr.Args.Count(), 1, expr.Line); } var input = Eval(expr.Args[0], null); if (input is Attribute) { input = (input as Attribute).Value; } if (input is SymbolTable) { var retTable = new SymbolTable(); int ind = 0; foreach (var table in (input as SymbolTable).Tables) { var ret = new Value(); ret.Index = ind; ret.Generator = node; if (!(table.Value.Value is Value)) { throw new InvalidOperationException(expr.Line); } node.Inputs.Add(table.Value.Value as Value); node.Outputs.Add(ret); retTable.Tables.Add(table.Key, new Attribute(ret)); ind++; } return(retTable); } else if (input is Value) { var ret = new Value(); ret.Index = 0; ret.Generator = node; node.Inputs.Add(input as Value); node.Outputs.Add(ret); return(ret); } else { throw new Exception(); } }