private LuaValue PrefixUnaryOperation(string Operator, Term RightOperand, LuaTable enviroment) { LuaValue rightValue = RightOperand.Evaluate(enviroment); switch (Operator) { case "-": var number = rightValue as LuaNumber; if (number != null) { return new LuaNumber(-number.Number); } else { LuaFunction func = GetMetaFunction("__unm", rightValue, null); if (func != null) { return func.Invoke(new LuaValue[] { rightValue }); } } break; case "#": var table = rightValue as LuaTable; if (table != null) { return new LuaNumber(table.Length); } var str = rightValue as LuaString; if (str != null) { return new LuaNumber(str.Text.Length); } if ((rightValue.MetaTable.GetValue("__len") != null) && ((rightValue.MetaTable.GetValue("__len") as LuaFunction) != null)) return (rightValue.MetaTable.GetValue("__len") as LuaFunction).Invoke(new LuaValue[] { }); break; case "not": var rightBool = rightValue as LuaBoolean; if (rightBool != null) { return LuaBoolean.From(!rightBool.BoolValue); } break; } return LuaNil.Nil; }
// Operator-precedence parsing algorithm private static Term BuildExpressionTree(Term leftTerm, LinkedListNode<object> node) { string oper = node.Value as string; var rightNode = node.Next; Term rightTerm = rightNode.Value as Term; if (rightNode.Next == null) // last node { return new Operation(oper, leftTerm, rightTerm); } else { string nextOper = rightNode.Next.Value as string; if (OperTable.IsPrior(oper, nextOper)) { return BuildExpressionTree(new Operation(oper, leftTerm, rightTerm), rightNode.Next); } else { return new Operation(oper, leftTerm, BuildExpressionTree(rightTerm, rightNode.Next)); } } }
public Operation(string oper, Term left, Term right) { this.Operator = oper; this.LeftOperand = left == null ? null : left.Simplify(); this.RightOperand = right == null ? null : right.Simplify(); }
private LuaValue InfixBinaryOperation(Term LeftOperand, string Operator, Term RightOperand, LuaTable enviroment) { LuaValue leftValue = LeftOperand.Evaluate(enviroment); LuaValue rightValue = RightOperand.Evaluate(enviroment); switch (Operator) { case "+": var left = leftValue as LuaNumber; var right = rightValue as LuaNumber; if (left != null && right != null) { return new LuaNumber(left.Number + right.Number); } else { LuaFunction func = GetMetaFunction("__add", leftValue, rightValue); if (func != null) { return func.Invoke(new LuaValue[] { leftValue, rightValue }); } } break; case "-": left = leftValue as LuaNumber; right = rightValue as LuaNumber; if (left != null && right != null) { return new LuaNumber(left.Number - right.Number); } else { LuaFunction func = GetMetaFunction("__sub", leftValue, rightValue); if (func != null) { return func.Invoke(new LuaValue[] { leftValue, rightValue }); } } break; case "*": left = leftValue as LuaNumber; right = rightValue as LuaNumber; if (left != null && right != null) { return new LuaNumber(left.Number * right.Number); } else { LuaFunction func = GetMetaFunction("__mul", leftValue, rightValue); if (func != null) { return func.Invoke(new LuaValue[] { leftValue, rightValue }); } } break; case "/": left = leftValue as LuaNumber; right = rightValue as LuaNumber; if (left != null && right != null) { return new LuaNumber(left.Number / right.Number); } else { LuaFunction func = GetMetaFunction("__div", leftValue, rightValue); if (func != null) { return func.Invoke(new LuaValue[] { leftValue, rightValue }); } } break; case "%": left = leftValue as LuaNumber; right = rightValue as LuaNumber; if (left != null && right != null) { return new LuaNumber(left.Number % right.Number); } else { LuaFunction func = GetMetaFunction("__mod", leftValue, rightValue); if (func != null) { return func.Invoke(new LuaValue[] { leftValue, rightValue }); } } break; case "^": left = leftValue as LuaNumber; right = rightValue as LuaNumber; if (left != null && right != null) { return new LuaNumber(Math.Pow(left.Number, right.Number)); } else { LuaFunction func = GetMetaFunction("__pow", leftValue, rightValue); if (func != null) { return func.Invoke(new LuaValue[] { leftValue, rightValue }); } } break; case "==": return LuaBoolean.From(leftValue.Equals(rightValue)); case "~=": return LuaBoolean.From(leftValue.Equals(rightValue) == false); case "<": int? compare = Compare(leftValue, rightValue); if (compare != null) { return LuaBoolean.From(compare < 0); } else { LuaFunction func = GetMetaFunction("__lt", leftValue, rightValue); if (func != null) { return func.Invoke(new LuaValue[] { leftValue, rightValue }); } } break; case ">": compare = Compare(leftValue, rightValue); if (compare != null) { return LuaBoolean.From(compare > 0); } else { LuaFunction func = GetMetaFunction("__gt", leftValue, rightValue); if (func != null) { return func.Invoke(new LuaValue[] { leftValue, rightValue }); } } break; case "<=": compare = Compare(leftValue, rightValue); if (compare != null) { return LuaBoolean.From(compare <= 0); } else { LuaFunction func = GetMetaFunction("__le", leftValue, rightValue); if (func != null) { return func.Invoke(new LuaValue[] { leftValue, rightValue }); } } break; case ">=": compare = Compare(leftValue, rightValue); if (compare != null) { return LuaBoolean.From(compare >= 0); } else { LuaFunction func = GetMetaFunction("__ge", leftValue, rightValue); if (func != null) { return func.Invoke(new LuaValue[] { leftValue, rightValue }); } } break; case "..": if ((leftValue is LuaString || leftValue is LuaNumber) && (rightValue is LuaString || rightValue is LuaNumber)) { return new LuaString(string.Concat(leftValue, rightValue)); } else { LuaFunction func = GetMetaFunction("__concat", leftValue, rightValue); if (func != null) { return func.Invoke(new LuaValue[] { leftValue, rightValue }); } } break; case "and": bool leftBool = leftValue.GetBooleanValue(); bool rightBool = rightValue.GetBooleanValue(); if (leftBool == false) { return leftValue; } else { return rightValue; } case "or": leftBool = leftValue.GetBooleanValue(); rightBool = rightValue.GetBooleanValue(); if (leftBool == true) { return leftValue; } else { return rightValue; } } return null; }
public void Add(Term term) { Terms.AddLast(term); }