コード例 #1
0
ファイル: CodeRules.cs プロジェクト: mvaganov/StrParse
 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);
 }
コード例 #2
0
        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);
        }
コード例 #3
0
ファイル: CodeRules.cs プロジェクト: mvaganov/StrParse
 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);
     }
 }
コード例 #4
0
ファイル: CodeRules.cs プロジェクト: mvaganov/StrParse
 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);
 }
コード例 #5
0
ファイル: CodeRules.cs プロジェクト: mvaganov/StrParse
 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);
 }
コード例 #6
0
        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);
        }
コード例 #7
0
        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);
        }
コード例 #8
0
ファイル: Parser.cs プロジェクト: mvaganov/20210131_ggj2021
        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);
        }