public static object op_mod(Tokenizer tok, Context.Entry e, object scope) { op_BinaryArgs(tok, e, scope, out object left, out object right, out Type lType, out Type rType); do { if (lType == typeof(string)) { string format = left as string; List <object> args; if (rType != typeof(List <object>)) { args = new List <object>(); args.Add(right); } else { args = right as List <object>; } return(Format(format, args, scope, tok, e.tokens[0].index)); } if (lType == typeof(string) || rType == typeof(string)) { break; } if (CodeConvert.IsConvertable(lType) && CodeConvert.IsConvertable(rType)) { CodeConvert.TryConvert(ref left, typeof(double)); CodeConvert.TryConvert(ref right, typeof(double)); return(((double)left) % ((double)right)); } } while (false); tok.AddError(e.tokens[1], "unable to modulo " + lType + " and " + rType + " : " + left + " % " + right); return(e); }
public static object op_mul(Tokenizer tok, Context.Entry e, object scope) { object left, right; Type lType, rType; op_BinaryArgs(tok, e, scope, out left, out right, out lType, out rType); do { bool lString = lType == typeof(string); bool rString = rType == typeof(string); // if one of them is a string, there is some string multiplication logic to do! if (lString != rString) { string meaningfulString; double meaningfulNumber; if (lString) { if (!CodeConvert.IsConvertable(rType)) { break; } meaningfulString = left.ToString(); CodeConvert.TryConvert(ref right, typeof(double)); meaningfulNumber = (double)right; } else { if (!CodeConvert.IsConvertable(lType)) { break; } meaningfulString = right.ToString(); CodeConvert.TryConvert(ref left, typeof(double)); meaningfulNumber = (double)left; } StringBuilder sb = new StringBuilder(); for (int i = 0; i < meaningfulNumber; ++i) { sb.Append(meaningfulString); } meaningfulNumber -= (int)meaningfulNumber; int count = (int)(meaningfulString.Length * meaningfulNumber); if (count > 0) { sb.Append(meaningfulString.Substring(0, count)); } return(sb.ToString()); } if (CodeConvert.IsConvertable(lType) && CodeConvert.IsConvertable(rType)) { CodeConvert.TryConvert(ref left, typeof(double)); CodeConvert.TryConvert(ref right, typeof(double)); return(((double)left) * ((double)right)); } } while (false); tok.AddError(e.tokens[1], "unable to multiply " + lType + " and " + rType); return(e); }
public static void op_BinaryArgs(Tokenizer tok, Context.Entry e, object scope, out object left, out object right, out Type lType, out Type rType) { op_ResolveToken(tok, e.tokens[0], scope, out left, out lType); op_ResolveToken(tok, e.tokens[2], scope, out right, out rType); // upcast to double. all the math operations expect doubles only, for algorithm simplicity if (lType != typeof(string) && lType != typeof(double) && CodeConvert.IsConvertable(lType)) { CodeConvert.TryConvert(ref left, typeof(double)); lType = typeof(double); } if (rType != typeof(string) && rType != typeof(double) && CodeConvert.IsConvertable(rType)) { CodeConvert.TryConvert(ref right, typeof(double)); rType = typeof(double); } }
public static object op_add(Tokenizer tok, Context.Entry e, object scope) { op_BinaryArgs(tok, e, scope, out object left, out object right, out Type lType, out Type rType); if (lType == typeof(string) || rType == typeof(string)) { return(left.ToString() + right.ToString()); } if (CodeConvert.IsConvertable(lType) && CodeConvert.IsConvertable(rType)) { CodeConvert.TryConvert(ref left, typeof(double)); CodeConvert.TryConvert(ref right, typeof(double)); return(((double)left) + ((double)right)); } tok.AddError(e.tokens[1], "unable to add " + lType + " and " + rType + " : " + left + " + " + right); return(e); }
public static object op_pow(Tokenizer tok, Context.Entry e, object scope) { op_BinaryArgs(tok, e, scope, out object left, out object right, out Type lType, out Type rType); do { if (lType == typeof(string) || rType == typeof(string)) { break; } if (CodeConvert.IsConvertable(lType) && CodeConvert.IsConvertable(rType)) { CodeConvert.TryConvert(ref left, typeof(double)); CodeConvert.TryConvert(ref right, typeof(double)); return(Math.Pow((double)left, (double)right)); } } while (false); tok.AddError(e.tokens[1], "unable to exponent " + lType + " and " + rType + " : " + left + " ^^ " + right); return(e); }
public static object op_div(Tokenizer tok, Context.Entry e, object scope) { object left, right; Type lType, rType; op_BinaryArgs(tok, e, scope, out left, out right, out lType, out rType); do { if (lType == typeof(string) || rType == typeof(string)) { break; } if (CodeConvert.IsConvertable(lType) && CodeConvert.IsConvertable(rType)) { CodeConvert.TryConvert(ref left, typeof(double)); CodeConvert.TryConvert(ref right, typeof(double)); return(((double)left) / ((double)right)); } } while (false); tok.AddError(e.tokens[1], "unable to divide " + lType + " and " + rType + " : " + left + " / " + right); return(e); }
protected bool TryGetValue() { memberValue = null; Token token = Current.Token; object meta = token.meta; if (SkipStructuredDelimiters(meta as Delim)) { return(true); } Context.Entry context = meta as Context.Entry; if (context != null) { bool subContextUsingSameList = context.tokens == Current.tokens; if (context.IsText()) { memberValue = context.GetText(); } else { int index = Current.tokenIndex; List <Token> parseNext = subContextUsingSameList ? Current.tokens.GetRange(index, context.tokenCount) : context.tokens; if (memberType == typeof(Expression)) { memberValue = new Expression(new List <Token>() { token }); } else { if (CodeConvert.IsConvertable(memberType)) { //Show.Log(memberId + " :: " + memberValue); memberValue = context.Resolve(tok, scope); } else { //Show.Log(memberId+" : "+memberValue); if (!CodeConvert.TryParseTokens(memberType, parseNext, ref memberValue, scope, tok)) { return(false); } } } } if (subContextUsingSameList) { Current.tokenIndex += context.tokenCount - 1; // -1 because increment happens after this method } return(true); } string s = meta as string; if (s != null) { memberValue = token.ToString(s); if (!CodeConvert.TryConvert(ref memberValue, memberType)) { AddError("unable to convert (" + memberValue + ") to type '" + memberType + "'"); return(false); } return(true); } TokenSubstitution sub = meta as TokenSubstitution; if (sub != null) { memberValue = sub.value; if (!memberType.IsAssignableFrom(memberValue.GetType()) && !CodeConvert.TryConvert(ref memberValue, memberType)) { AddError("unable to convert substitution (" + memberValue + ") to type '" + memberType + "'"); return(false); } return(true); } AddError("unable to parse token with meta data " + meta); return(false); }
private bool TryGetValue_Syntax(Token token, SyntaxTree syntax) { bool subContextUsingSameList = syntax.tokens == Current.tokens; if (syntax.IsTextLiteral) { memberValue = syntax.GetText(); } else { int index = Current.tokenIndex; List <Token> parseNext = subContextUsingSameList ? Current.tokens.GetRange(index, syntax.TokenCount) : syntax.tokens; if (memberType == typeof(Expression)) { Expression expr = new Expression(new List <Token>() { token }); if (scope != null) { List <object> resolved = expr.Resolve(tok, scope); if (resolved.Count == 1) { switch (resolved[0]) { case string partiallyResolvedExpressionAsString: expr = new Expression(partiallyResolvedExpressionAsString); break; case Expression partiallyResolvedExpression: expr = partiallyResolvedExpression; break; } } //Show.Log(resolved.JoinToString() + " " + resolved[0].GetType()+ " >><< " + expr+ " " + expr.GetType()); } memberValue = expr; } else { if (CodeConvert.IsConvertable(memberType)) { //Show.Log(memberId + " :: " + memberValue); memberValue = syntax.Resolve(tok, scope); } else { //Show.Log(memberId+" : "+memberValue); if (!CodeConvert.TryParseTokens(memberType, parseNext, ref memberValue, scope, tok)) { return(false); } } } } if (subContextUsingSameList) { Current.tokenIndex += syntax.TokenCount - 1; // -1 because increment happens after this method } return(true); }