예제 #1
0
        public void Visit(FuncCall funcCall)
        {
            Replace(ref funcCall.Func);

            if (funcCall.Func is Overload overload)
            {
                var localCopy = new Overload(overload);
                funcCall.Func = localCopy;

                foreach (var func in overload.Funcs)
                {
                    if (RemoveDef(func))
                    {
                        func.Accept(this);
                    }
                }
            }
            else if (funcCall.Func is TypeObj typeObj)
            {
                var localCopy = new Overload(typeObj);
                funcCall.Func = localCopy;

                foreach (var func in typeObj.Initializers)
                {
                    if (RemoveDef(func))
                    {
                        func.Accept(this);
                    }
                }
            }
            else
            {
                throw new CompilationError(ErrorType.ObjectIsNotCallable);
            }

            var args = funcCall.Args;

            for (var i = 0; i < args.Count; i += 1)
            {
                var arg = args[i];
                Replace(ref arg);
                args[i] = arg;
            }
        }
예제 #2
0
        public string Visit(FuncCall node)
        {
            var sb       = new StringBuilder();
            var funcName = node.AnchorToken.Lexeme;

            level += 1;

            sb.Append(Visit((dynamic)node[0]));
            sb.Append($"    call ${funcName}\n");

            level -= 1;

            if (!(funcName == "reads" || funcName == "readi" || funcName == "new" || funcName == "size" || funcName == "get") && level == 0)
            {
                sb.Append($"    drop\n");
            }

            return(sb.ToString());
        }
예제 #3
0
        public static FuncCall CreateFuncCall(CodeElement elem, Scope scope)
        {
            // funcCall    = identifier '(' [exp {',' exp}] ')';

            CodeElement idElem = elem.Codes("identifier").First();
            string      name   = idElem.Value;

            Function theFunc = scope.GetFunction(name);

            var parameters = new List <ExpBase>();
            int i          = -1;

            foreach (CodeElement item in elem.Codes().Where(e => e != idElem))
            {
                var parm = CreateExpression(item, scope);
                if (++i == theFunc.Parameters.Count)
                {
                    throw new Exception(string.Format("Too many parameters for function '{0}', {1}", name, item.GetLineAndColumn()));
                }
                if (theFunc.Parameters[i].TheType == DefType.Int && !ExpBase.IsInt(parm))
                {
                    throw new Exception(string.Format("The parameter for function '{0}' must be an integer, {1}", name, item.GetLineAndColumn()));
                }
                if (theFunc.Parameters[i].TheType == DefType.Bool && !ExpBase.IsBool(parm))
                {
                    throw new Exception(string.Format("The parameter for function '{0}' must be a boolean, {1}", name, item.GetLineAndColumn()));
                }
                if (theFunc.Parameters[i].TheType == DefType.Bool && !ExpBase.IsNumber(parm))
                {
                    throw new Exception(string.Format("The parameter for function '{0}' must be a number, {1}", name, item.GetLineAndColumn()));
                }

                parameters.Add(parm);
            }
            if (i + 1 != theFunc.Parameters.Count)
            {
                throw new Exception(string.Format("Too few parameters for function '{0}', {1}", name, elem.GetLineAndColumn()));
            }

            var call = new FuncCall(theFunc, parameters);

            return(call);
        }
예제 #4
0
        private static TypeDesc ResolveType(FuncCall call, Environment env, CodePosition position)
        {
            TypeDesc supposedFuncType = env.LookupId(call.Name, position);
            FuncType targetFuncType;

            if (!(supposedFuncType is FuncType))
            {
                throw new TypecheckerError(
                          new EnvironmentError($"Name `{call.Name}` is not a function"),
                          position
                          );
            }

            targetFuncType = (FuncType)supposedFuncType;

            if (call.Arguments.Count() != targetFuncType.Domain.Count())
            {
                throw new TypecheckerError(
                          new EnvironmentError($"Function `{call.Name}` takes {targetFuncType.Domain.Count()} arguments"),
                          position
                          );
            }

            for (int i = 0; i < call.Arguments.Count(); i++)
            {
                TypeDesc callArgType         = ResolveType(call.Arguments[i], env, position);
                TypeDesc targetFuncParamType = targetFuncType.Domain[i];

                if (callArgType.GetType() != targetFuncParamType.GetType())
                {
                    throw new TypecheckerError(
                              new MismatchedTypes(targetFuncParamType, callArgType),
                              call.Arguments[i].Position
                              );
                }
            }

            return(targetFuncType);
        }
예제 #5
0
        private static ExpBase CreateExpFuncCall(CodeElement elem, Scope scope)
        {
            // funcCall    = identifier '(' [exp {',' exp}] ')';
            FuncCall call = CreateFuncCall(elem, scope);

            ExpBase expFunc = null;

            switch (call.Func.FuncType)
            {
            case DefType.Int: expFunc = new ExpFuncCall <int>(call); break;

            case DefType.String: expFunc = new ExpFuncCall <string>(call); break;

            case DefType.Float: expFunc = new ExpFuncCall <float>(call); break;

            case DefType.Bool: expFunc = new ExpFuncCall <bool>(call); break;

            default:
                throw new Exception("Unknown variable type.");
            }

            return(expFunc);
        }
        public void BeCreatedAndExecuted()
        {
            var F0 = FuncCall.Create(() => { return(1); });
            var F1 = FuncCall.Create((a) => { return(a + 1); }, 1);
            var F2 = FuncCall.Create((a, b) => { return(a + b + 1); }, 1, 2);
            var F3 = FuncCall.Create((a, b, c) => { return(a + b + c + 1); }, 1, 2, 3);
            var F4 = FuncCall.Create((a, b, c, d) => { return(a + b + c + d + 1); }, 1, 2, 3, 4);
            var F5 = FuncCall.Create((a, b, c, d, e) => { return(a + b + c + d + e + 1); }, 1, 2, 3, 4, 5);

            // First call

            Assert.AreEqual(1, F0.Call().Result);
            Assert.AreEqual(2, F1.Call().Result);
            Assert.AreEqual(4, F2.Call().Result);
            Assert.AreEqual(7, F3.Call().Result);
            Assert.AreEqual(11, F4.Call().Result);
            Assert.AreEqual(16, F5.Call().Result);

            // Second call (not sure we have to support this, but why not)

            Assert.AreEqual(1, F0.Call().Result);
            Assert.AreEqual(2, F1.Call().Result);
            Assert.AreEqual(4, F2.Call().Result);
            Assert.AreEqual(7, F3.Call().Result);
            Assert.AreEqual(11, F4.Call().Result);
            Assert.AreEqual(16, F5.Call().Result);

            // Dynamic call

            Assert.AreEqual(1, F0.GetMakerInfo().Maker.DynamicInvoke(F0.GetArgsArray()));
            Assert.AreEqual(2, F1.GetMakerInfo().Maker.DynamicInvoke(F1.GetArgsArray()));
            Assert.AreEqual(4, F2.GetMakerInfo().Maker.DynamicInvoke(F2.GetArgsArray()));
            Assert.AreEqual(7, F3.GetMakerInfo().Maker.DynamicInvoke(F3.GetArgsArray()));
            Assert.AreEqual(11, F4.GetMakerInfo().Maker.DynamicInvoke(F4.GetArgsArray()));
            Assert.AreEqual(16, F5.GetMakerInfo().Maker.DynamicInvoke(F5.GetArgsArray()));
        }
예제 #7
0
 public new Object DeriveKey <R>(FuncCall <R> Call)
 {
     return(base.DeriveKey(Call));
 }
예제 #8
0
 FuncCall ParseFuncCall(bool fNew, IList<string> name)
 {
     FuncCall funcCall = new FuncCall();
     funcCall.fNew = fNew;
     funcCall.Name = name;
     funcCall.Args = new List<Expr>();
     while (ix < tokens.Count && !Is(")"))
     {
         funcCall.Args.Add(ParseExpr());
         if (Is(",")) ix++;
     }
     Skip(")");
     return funcCall;
 }
예제 #9
0
 public ExpFuncCall(FuncCall call)
 {
     Call = call;
 }
예제 #10
0
        private Answer ParseAnswer(int answerNum, Regex langEndLine, string[] parts, IEnumerable <string> languages, int nodeNum)
        {
            Answer ans = new Answer();

            ans.ToNode = Int32.Parse(parts[0]);
            foreach (String lang in languages)
            {
                Regex langStartLine = new Regex("^\\[" + lang + "\\]");
                ans.Text[lang] = _textStrings.GetMSGValue(nodeNum * 1000 + (answerNum * 10), langStartLine, langEndLine);
            }

            if (parts.Length > 3)
            {
                int     i         = 2;
                bool    noRecheck = false;
                Dynamic dyn       = null;
                do
                {
                    if (parts[i] == "_script")
                    {
                        FuncCall call = new FuncCall();
                        call.ScriptString = parts[++i];
                        int argsNum = Int32.Parse(parts[++i]);
                        if (argsNum != 0)
                        {
                            for (int k = 0; k < argsNum; k++)
                            {
                                call.Args.Add(parts[++i]);
                            }
                        }
                        dyn.FuncCall = call;
                        AddDynamic(ans, dyn, noRecheck);
                    }
                    else if (parts[i] == "_item")
                    {
                        dyn.Item           = new DialogItem();
                        dyn.ForPlayer      = (parts[++i] == "p");
                        dyn.Item.PidDefine = parts[++i];
                        dyn.Operator       = Dialog.Dialog.GetOperator(parts[++i]);
                        dyn.Value          = Int32.Parse(parts[++i]);
                        AddDynamic(ans, dyn, noRecheck);
                    }
                    else if (parts[i] == "_var")
                    {
                        dyn.Var       = new GameVariable();
                        dyn.ForPlayer = (parts[++i] == "p");
                        dyn.Var.Name  = parts[++i];
                        dyn.Operator  = Dialog.Dialog.GetOperator(parts[++i]);
                        dyn.Value     = Int32.Parse(parts[++i]);
                        AddDynamic(ans, dyn, noRecheck);
                    }
                    else if (parts[i] == "_param")
                    {
                        dyn.Param             = new Parameter();
                        dyn.ForPlayer         = (parts[++i] == "p");
                        dyn.Param.ParamDefine = parts[++i];
                        dyn.Operator          = Dialog.Dialog.GetOperator(parts[++i]);
                        dyn.Value             = Int32.Parse(parts[++i]);
                        AddDynamic(ans, dyn, noRecheck);
                    }
                    else if (parts[i] == "no_recheck")
                    {
                        noRecheck = true;
                    }
                    else if (parts[i] == "R")
                    {
                        dyn       = new Result();
                        noRecheck = false;
                    }
                    else if (parts[i] == "D")
                    {
                        dyn       = new Demand();
                        noRecheck = false;
                    }

                    i++;
                } while (i < parts.Length - 1);
            }
            return(ans);
        }
예제 #11
0
    public static Int32 Parse(List<Token> src, Int32 begin, out Expr expr)
    {
        // step 1. match primary_expression
        Int32 current = _primary_expression.Parse(src, begin, out expr);
        if (current == -1) {
            expr = null;
            return -1;
        }

        // step 2. match postfixes
        while (true) {

            if (src[current].type != TokenType.OPERATOR) {
                return current;
            }

            OperatorVal val = ((TokenOperator)src[current]).val;
            switch (val) {
            case OperatorVal.LBRACKET:
                // '['
                current++;

                // 1. match expression
                Expr idx;
                current = _expression.Parse(src, current, out idx);
                if (current == -1) {
                    expr = null;
                    return -1;
                }

                // 2. match ']'
                if (!Parser.IsOperator(src[current], OperatorVal.RBRACKET)) {
                    expr = null;
                    return -1;
                }
                current++;

                // successful match
                expr = new Dereference(new Add(expr, idx));
                // expr = new ArrayElement(expr, idx);
                break;

            case OperatorVal.LPAREN:
                // '('
                current++;

                // 1. match arglist, if no match, assume empty arglist
                List<Expr> args;
                Int32 saved = current;
                current = _argument_expression_list.Parse(src, current, out args);
                if (current == -1) {
                    args = new List<Expr>();
                    current = saved;
                }

                // 2. match ')'
                if (!Parser.IsOperator(src[current], OperatorVal.RPAREN)) {
                    expr = null;
                    return -1;
                }
                current++;

                // successful match
                expr = new FuncCall(expr, args);
                break;

            case OperatorVal.PERIOD:
                // '.'
                current++;

                // match identifier
                if (src[current].type != TokenType.IDENTIFIER) {
                    expr = null;
                    return -1;
                }
                String attrib = ((TokenIdentifier)src[current]).val;
                current++;

                // successful match
                expr = new SyntaxTree.Attribute(expr, new Variable(attrib));
                break;

            case OperatorVal.RARROW:
                // '->'
                current++;

                if (src[current].type != TokenType.IDENTIFIER) {
                    return -1;
                }
                String pattrib = ((TokenIdentifier)src[current]).val;
                current++;

                // successful match
                expr = new SyntaxTree.Attribute(new Dereference(expr), new Variable(pattrib));
                // expr = new PointerAttribute(expr, new Variable(pattrib));
                break;

            case OperatorVal.INC:
                // '++'
                current++;

                // successful match
                expr = new PostIncrement(expr);
                break;

            case OperatorVal.DEC:
                // '--'

                current++;

                // successful match
                expr = new PostDecrement(expr);
                break;

            default:

                // no more postfix
                return current;

            } // case (val)

        } // while (true)
    }
예제 #12
0
 public FuncCallExprParam(bool unary, FuncCall funcCall)
 {
     Unary    = unary;
     FuncCall = funcCall;
 }
예제 #13
0
        public Node ExpressionPrimary()
        {
            switch (CurrentToken)
            {
            case TokenCategory.IDENTIFIER:
                var idToken = Expect(TokenCategory.IDENTIFIER);

                if (CurrentToken == TokenCategory.PARENTHESIS_OPEN)
                {
                    Expect(TokenCategory.PARENTHESIS_OPEN);
                    var exprList = ExprList();
                    Expect(TokenCategory.PARENTHESIS_CLOSE);
                    var result = new FuncCall()
                    {
                        exprList
                    };
                    result.AnchorToken = idToken;
                    return(result);
                }
                else
                {
                    return(new Identifier()
                    {
                        AnchorToken = idToken
                    });
                }

            case TokenCategory.INT_LITERAL:
                return(new IntLiteral()
                {
                    AnchorToken = Expect(TokenCategory.INT_LITERAL)
                });

            case TokenCategory.STRING:
                return(new String()
                {
                    AnchorToken = Expect(TokenCategory.STRING)
                });

            case TokenCategory.CHAR:
                return(new Char()
                {
                    AnchorToken = Expect(TokenCategory.CHAR)
                });

            case TokenCategory.UNICODE_CHAR:
                return(new UnicodeChar()
                {
                    AnchorToken = Expect(TokenCategory.UNICODE_CHAR)
                });

            case TokenCategory.TRUE:
                return(new True()
                {
                    AnchorToken = Expect(TokenCategory.TRUE)
                });

            case TokenCategory.FALSE:
                return(new False()
                {
                    AnchorToken = Expect(TokenCategory.FALSE)
                });

            case TokenCategory.SQUARE_OPEN:
                return(Array());

            case TokenCategory.PARENTHESIS_OPEN:
                Expect(TokenCategory.PARENTHESIS_OPEN);
                var result2 = Expression();
                Expect(TokenCategory.PARENTHESIS_CLOSE);
                return(result2);

            default:
                throw new SyntaxError(firstOfExpression,
                                      tokenStream.Current);
            }
        }
예제 #14
0
        /// <summary>
        /// Core cache proc method [low level].
        /// Will try to find result in cache based on key, else will call the func and store result in cache attached to the key.
        /// </summary>
        /// <typeparam name="R">Function result type</typeparam>
        /// <param name="Key">Key to asssociate with the result</param>
        /// <param name="Factory">Function to produce the result</param>
        /// <returns>Function call result ether actual or cached</returns>
        protected R GetOrMakeWithKey <R>(Object Key, Func <R> Factory)
        {
            Interlocked.Increment(ref CacheStatUseCount);

            CacheItem          CacheEntry;
            FuncCallResult <R> CachedResult = null;

            lock (Cache)
            {
                if (Cache.TryGetValue(Key, out CacheEntry))
                {
                    CachedResult = CacheEntry.CallResult as FuncCallResult <R>;
                    if (CachedResult != null)
                    {
                        // Found and type is valid
                        if (isExpiried(CacheEntry))
                        {
                            CachedResult = null;
                            Cache.Remove(Key); // expiried entry
                            CacheEntry = null;
                        }
                    }
                    else
                    {
                        Cache.Remove(Key); // invalid entry (bug trap)
                        CacheEntry = null;
                    }
                }
                else
                {
                    CacheEntry = null;
                }
            }

            if (CachedResult == null)
            {
                // not found in cache

                CachedResult = FuncCall.Call(Factory); // That may take long time and we are not locked

                var Now = GetLongTickCount();

                CacheEntry = new CacheItem
                {
                    MakeTimestamp       = Now,
                    LastAccessTimestamp = Now,
                    CallResult          = CachedResult
                };

                CacheStatLastAccessTimestamp = Now;

                lock (Cache)
                {
                    try
                    {
                        Cache.Add(Key, CacheEntry);
                    }
                    catch
                    {
                        // Someone already added result (earlier)
                        try
                        {
                            // Refresh
                            Cache.Remove(Key);
                            Cache.Add(Key, CacheEntry);
                        }
                        catch
                        {
                            // Failed to remove/add?
                            // This should not be a case since we are in lock
                            throw;
                        }
                    }
                }
            }
            else
            {
                // Found in cache
                var Now = GetLongTickCount();
                Interlocked.Increment(ref CacheEntry.HitCount);
                CacheEntry.LastAccessTimestamp = Now;

                Interlocked.Increment(ref CacheStatHitCount);
                CacheStatLastAccessTimestamp = Now;
            }

            if (CachedResult.Exception != null)
            {
                throw CachedResult.Exception; // rethrow
            }

            return(CachedResult.Result);
        }
예제 #15
0
        private static int DoIt(int[] n, out long time)
        {
            int result = -1;

            System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew();
            HashSet <string>             map       = new HashSet <string>();
            StringBuilder   sb = new StringBuilder();
            String          finalstate;
            List <FuncCall> bfs = new List <FuncCall>();
            String          s;

            for (int i = 0; i <= n.Length; i++)
            {
                sb.Append('3');
            }
            finalstate = sb.ToString();
            bfs.Add(new FuncCall(n, 0, 0));
            while (bfs.Count > 0)
            {
                FuncCall f = bfs[0];
                bfs.RemoveAt(0);
                if (f.e < 0 || f.e > 3)
                {
                    continue;                                     //elevator outside building
                }
                sortx(f.n);
                if (!ok(f.n))
                {
                    continue;                           //microship gets fried
                }
                s = getStr(f.n, f.e);
                if (map.Contains(s))
                {
                    continue;                                  //state we've already been to.
                }
                map.Add(s);
                if (s.Equals(finalstate))                   //found final state!
                {
                    result = f.k;
                    break;
                }


                for (int i = 0; i < f.n.Length; i++)
                {
                    if (f.n[i] != f.e)
                    {
                        continue;
                    }
                    f.n[i]--;
                    bfs.Add(new FuncCall(f.n, f.k + 1, f.e - 1));                     //move n[i]
                    bool mvnxt = i % 2 == 0 && f.n[i + 1] == f.e;
                    if (mvnxt)
                    {
                        f.n[i + 1]--;
                        bfs.Add(new FuncCall(f.n, f.k + 1, f.e - 1));                         //move n[i]
                        f.n[i + 1]++;
                    }
                    f.n[i] += 2;
                    bfs.Add(new FuncCall(f.n, f.k + 1, f.e + 1));                     //move n[i]
                    if (mvnxt)
                    {
                        f.n[i + 1]++;
                        bfs.Add(new FuncCall(f.n, f.k + 1, f.e + 1));                         //move n[i]
                        f.n[i + 1]--;
                    }
                    f.n[i]--;

                    for (int j = i + 2; j < f.n.Length; j += 2)
                    {
                        if (f.n[j] != f.e)
                        {
                            continue;
                        }
                        f.n[i]--; f.n[j]--;
                        bfs.Add(new FuncCall(f.n, f.k + 1, f.e - 1));                         //move n[i]&n[j]
                        f.n[i] += 2; f.n[j] += 2;
                        bfs.Add(new FuncCall(f.n, f.k + 1, f.e + 1));                         //move n[i]&n[j]
                        f.n[i]--; f.n[j]--;
                    }
                }
            }

            stopwatch.Stop();
            time = stopwatch.ElapsedMilliseconds;
            return(result);
        }
예제 #16
0
        public List <Step> ParseTokens() // Due to the size of this method I am not using IEnumerable 'yield return' as it is hard to track nested return statements.
        {
            List <Step> EvaluationSteps = new List <Step>();

            while (tokQueue.More())                  // While more tokens in queue (returns bool)
            {
                Token nextTok = tokQueue.MoveNext(); // pop next out of TokenQueue

                if (nextTok.Type().Equals("identifier"))
                // All statements in our language begin with identifiers.
                // We do not know what we have at this point, so let's check the identifier to see which tokens should follow after.
                {
                    if (Syntax.IsType(nextTok.Value()))
                    // If it is a var type, e.g "int", "string" - if it is, this is a variable declaration ("int x = 0;")
                    {
                        /*
                         * EXPECTED PATTERN: varType varName = expr;
                         * e.g int x = 2 + y*10;
                         * e.g string testing = "Hello World!";
                         */

                        VarDeclare varDeclare = CaptureVarDeclare(nextTok.Value()); // Call method with argument storing the type of var being declared, e.g 'string'

                        EvaluationSteps.Add(varDeclare);                            // Add Event object to the overall list of 'Steps' for the Evaluator module
                    }
                    else if (nextTok.Value().ToLower().Equals("if"))
                    // Start of an if statement
                    {
                        /*
                         * EXPECTED PATTERN: if(operands) { codeblock }
                         * e.g if (x > 0) {
                         *      output(x);
                         *      x = 0;
                         *     }
                         */

                        IfStatement ifState = CaptureIfStatement(); // Capture all useful information of the following if statements

                        // We COULD have an else statement, so let's check the next token
                        // First check there are still MORE tokens to check to avoid out of range errors
                        // Then check it's an IDENTIFIER ('else')
                        if (tokQueue.More() && tokQueue.Next().Type().Equals("identifier") && tokQueue.Next().Value().Equals("else"))
                        {
                            // If next token is 'else' and an identifier
                            ElseStatement elseState = CaptureElseStatement();
                            EvaluationSteps.Add(ifState);
                            EvaluationSteps.Add(elseState);
                            // Add if state then else directly after (ordered list!)
                        }
                        else
                        {
                            EvaluationSteps.Add(ifState);  // if no 'else' statement exists just add the if statement
                        }
                    }

                    else if (nextTok.Value().ToLower().Equals("while"))
                    {
                        IfStatement template  = CaptureIfStatement(); // Trick the program to think it's capturing an if statement
                        WhileLoop   whileLoop = new WhileLoop(template.GetCBContents(), template.GetOp1(), template.GetOp2(), template.GetComparator());
                        // Reuse code from the if statement because while & if follow the exact same structure:
                        // while (condition) { codeblock }
                        // if (condition) { codeblock }
                        // We just captured an if statement 'template' then used the information it collected to create a while loop instead

                        EvaluationSteps.Add(whileLoop);
                    }


                    else if (GrammarTokenCheck(tokQueue.Next(), "("))
                    // This condition will also return true if it finds an if/while statement, so it is AFTER the check for those.
                    // As we're using else if, if the program didn't recognise a 'while' or 'if' statement, we will reach this check
                    // We can GUARANTEE now that this must be a function call as 'if(){}' and 'while(){}' have been ruled out
                    {
                        /*
                         * EXPECTED PATTERN: funcName(expr); // Can take any expression!
                         * e.g output("Testing");
                         * e.g output(1 + 23);
                         * e.g output(x);
                         */

                        tokQueue.MoveNext(); // Skip the '(' token
                        // Remember, nextTok still holds the value of the token before '('
                        // This is the name of our function ('funcName')

                        FuncCall funcCall = CaptureFunctionCall(nextTok.Value()); // Pass the function name, e.g 'output'
                        EvaluationSteps.Add(funcCall);
                    }
                    else if (GrammarTokenCheck(tokQueue.Next(), "=")) // .Next() is PEEK not POP.
                    // Check if the token AFTER this one is "="
                    {
                        /*
                         * EXPECTED PATTERN: varName = expr;
                         * e.g x = 2 + y*10;
                         * e.g testing = "Hello World!";
                         */

                        tokQueue.MoveNext(); // Skip the '=' token
                        // Remember, nextTok still holds the value of the token before the '='
                        // This is the name of our variable to change ('varName')

                        VarChange varChan = CaptureVarChange(nextTok.Value());
                        EvaluationSteps.Add(varChan);
                    }
                    else
                    {
                        throw new SyntaxError();
                    }
                    // If there is a rogue 'else' statement it will be caught in this
                    // Else statements are not 'looked' for on there own, they are only recognised when an if statement is found
                }
                else
                {
                    throw new SyntaxError();    // Statement doesn't begin with identifier - throw error.
                }
            }

            return(EvaluationSteps);
        }
예제 #17
0
 private void GenStmt(Stmt stmt, ILGenerator il, Type[] argtypes)
 {
     if (stmt is VarDeclaration)
     {
         VarDeclaration var   = (VarDeclaration)stmt;
         string         tname = var.Type.GetTypeName();
         if (typeTable.ContainsKey(tname))
         {
             TypeBuilder        typeBuilder  = typeTable[tname];
             ConstructorBuilder ctorBuilder  = ctorTable[tname];
             LocalBuilder       localBuilder = il.DeclareLocal(typeBuilder);
             symbolTable[var.Name] = localBuilder;
             il.Emit(OpCodes.Newobj, ctorBuilder);
             il.Emit(OpCodes.Stloc, localBuilder);
         }
         else
         {
             Type vtype = var.Type.GetAType();
             symbolTable[var.Name] = il.DeclareLocal(vtype);
             GenExpr(var.Expr, TypeOfExpr(var.Expr, argtypes), il, argtypes);
             Store(var.Name, TypeOfExpr(var.Expr, argtypes), il);
         }
     }
     else if (stmt is Assign)
     {
         Assign assign = (Assign)stmt;
         GenExpr(assign.Expr, TypeOfExpr(assign.Expr, argtypes), il, argtypes);
         Store(assign.Name, TypeOfExpr(assign.Expr, argtypes), il);
     }
     else if (stmt is ExprStmt)
     {
         Expr expr = ((ExprStmt)stmt).Expr;
         if (expr is FuncCall)
         {
             FuncCall funcCall = (FuncCall)expr;
             if (funcCall.Name.Count > 1 && funcCall.Name[0] != "System")
             {
                 if (symbolTable.ContainsKey(funcCall.Name[0]))
                 {
                     LocalBuilder localBuilder = (LocalBuilder)symbolTable[funcCall.Name[0]];
                     il.Emit(OpCodes.Ldloc, localBuilder);
                 }
             }
             Type[] typeArgs = new Type[funcCall.Args.Count];
             for (int i = 0; i < funcCall.Args.Count; i++)
             {
                 typeArgs[i] = TypeOfExpr(funcCall.Args[i], argtypes);
                 GenExpr(funcCall.Args[i], typeArgs[i], il, argtypes);
             }
             string strFunc = funcCall.Name[funcCall.Name.Count - 1];    // "WriteLine"
             if (funcCall.Name[0] == "System")
             {
                 string strType = funcCall.Name[0];
                 for (int i = 1; i < funcCall.Name.Count - 1; i++)
                 {
                     strType += "." + funcCall.Name[i];
                 }
                 Type typeFunc = Type.GetType(strType);          // System.Console
                 il.Emit(OpCodes.Call, typeFunc.GetMethod(strFunc, typeArgs));
             }
             else if (funcCall.Name.Count > 1)
             {
                 MethodBuilder methodBuilder = funcTable[strFunc];
                 il.EmitCall(OpCodes.Call, methodBuilder, null);
             }
             else
             {
                 if (!funcTable.ContainsKey(strFunc))
                 {
                     throw new Exception("undeclared function '" + strFunc + "'");
                 }
                 MethodBuilder funcBuilder = funcTable[strFunc];
                 il.EmitCall(OpCodes.Call, funcBuilder, null);
             }
         }
     }
 }
예제 #18
0
 protected abstract void VisitFuncCall(FuncCall tree);
예제 #19
0
 public void Visit(FuncCall funcCall)
 {
     if (funcCall.Func is Function cf)
     {
         if (hierarchy.Contains(cf))
         {
             result.Push(cf.RetType as TypeObj);
         }
         else
         {
             funcCall.Func.Accept(this);
         }
     }
     else if (funcCall.Func is Overload overload)
     {
         var types = new List <TypeObj>();
         foreach (var arg in funcCall.Args)
         {
             arg.Accept(this);
             var type = result.Pop();
             if (type == null)
             {
                 if (ignoreErrors)
                 {
                     result.Push(null);
                     return;
                 }
                 else
                 {
                     throw new CompilationError(CantDetermineType);
                 }
             }
             types.Add(type);
         }
         var func = overload.Find(types);
         if (func == null)
         {
             throw new CompilationError(ObjectIsNotDefined);
         }
         if (func.TemplateParamsCount > 0)
         {
             var spec = specFuncs.Find(func, types);
             if (spec == null)
             {
                 new TemplateVisitor(func, out spec);
                 for (var i = 0; i < types.Count; i += 1)
                 {
                     spec.Parameters[i].Type = types[i];
                 }
                 specFuncs.Add(func, spec);
                 overload.Funcs.Add(spec);
                 func.Def.Specs.Add(spec);
                 spec.Accept(this);
                 result.Pop();
             }
             if (!ignoreErrors)
             {
                 funcCall.Func = spec;
             }
             result.Push((TypeObj)spec.RetType);
         }
         else
         {
             if (!ignoreErrors)
             {
                 funcCall.Func = func;
                 func.Accept(this);
             }
             else
             {
                 result.Push((TypeObj)func.RetType);
             }
         }
     }
     else
     {
         throw new CompilationError(ObjectIsNotCallable);
     }
 }
예제 #20
0
        public void Evaluate(List <Step> evaluationSteps)
        {
            for (int index = 0; index < evaluationSteps.Count; index++)
            {
                Step evalStep = evaluationSteps[index];
                // .Type() can only be "VAR_DECLARE", "VAR_CHANGE", "FUNC_CALL", "IF_STATEMENT", "WHILE_LOOP"
                // It could also be "ELSE_STATEMENT", but we should only check for that DIRECTLY after an IF_STATEMENT
                if (evalStep.Type().Equals("IF_STATEMENT"))
                {
                    // Evaluate if statement - contains OPERAND1, OPERAND2, COMPARISON, codeBlockContents
                    IfStatement ifState         = (IfStatement)evalStep;                                                                           // Cast as we know it is now an IfStatement obj
                    bool        conditionResult = CompareExpressions(ifState.GetOp1(), ifState.GetOp2(), ifState.GetComparator());
                    bool        hasElse         = index + 1 < evaluationSteps.Count && evaluationSteps[index + 1].Type().Equals("ELSE_STATEMENT"); // No chance of index out of range error as set to False before reaching it

                    if (conditionResult)
                    // If the 'IfStatement' condition is TRUE
                    {
                        Evaluate(ifState.GetCBContents()); // 'run' the contents of the if statement - this is RECURSIVE
                        if (hasElse)
                        {
                            evaluationSteps.RemoveAt(index + 1);
                        }
                        // If we have an ELSE_STATEMENT after this, we need to remove it as the IF_STATEMENT has triggered (therefore the ELSE will not be triggered).
                    }
                    else if (hasElse)
                    {
                        // If the CONDITION is FALSE and the next Step obj is an ELSE_STATEMENT type

                        ElseStatement elseState = (ElseStatement)evaluationSteps[index + 1];
                        // Cast to else
                        Evaluate(elseState.GetCBContents()); // 'run' the contents of the else (RECURSION)

                        evaluationSteps.RemoveAt(index + 1); // Remove ELSE_STATEMENT as we have used it and do not want to go over it again.
                    }
                }
                else if (evalStep.Type().Equals("WHILE_LOOP"))
                {
                    WhileLoop whileLoop = (WhileLoop)evalStep;
                    // Similar to if statement evaluation though no need to set a 'condition' variable because that condition may change
                    // Basically just reusing the C# while loop with the template of the Interpreted one
                    while (CompareExpressions(whileLoop.GetOp1(), whileLoop.GetOp2(), whileLoop.GetComparator()))
                    {
                        // While the condition is true, evaluate code inside
                        Evaluate(whileLoop.GetCBContents());
                    }
                }
                else if (evalStep.Type().Equals("VAR_DECLARE"))
                // Declare a variable in the variableScope
                {
                    VarDeclare varDecl = (VarDeclare)evalStep; // Cast as we know it's a VarDeclare obj
                    if (variableScope.ContainsKey(varDecl.GetName()))
                    {
                        throw new DeclareError();
                    }
                    // If scope already has a variable that name, you cannot redeclare it as it already exists.
                    // Potential endpoint if variable exists - entire program will stop (crash).
                    Token varExpr = ResolveExpression(varDecl.Value());

                    if (!varExpr.Type().Equals(varDecl.GetVarType()))
                    {
                        throw new TypeError();
                    }
                    // Value of variable does not match type with declared one. e.g 'int x = "Hello";'


                    variableScope.Add(varDecl.GetName(), varExpr);
                    // Type of variable can be found out by the .Type() of the key's Token.
                    // e.g 'int x = 1 + 2;'
                    // if we want to find variable 'x' type, we find variableScope[x].Type() which will return 'number', with variableScope[x].Value() being '3'
                }
                else if (evalStep.Type().Equals("VAR_CHANGE"))
                // Change a pre-existing variable
                {
                    VarChange varChan = (VarChange)evalStep; // Cast as we know it is a VarChange obj

                    if (!variableScope.ContainsKey(varChan.GetName()))
                    {
                        throw new ReferenceError();
                    }
                    // If variable is NOT in the variableScope then we cannot change it as it doesn't exist.
                    // Potential endpoint for program crash
                    string varType  = variableScope[varChan.GetName()].Type();
                    Token  newValue = ResolveExpression(varChan.Value());

                    if (!varType.Equals(newValue.Type()))
                    {
                        throw new TypeError();
                    }
                    // If the new value of the variable is not the right type, then crash.
                    // Potential endpoint
                    // e.g int x = 0; x = "hi"; will cause this error
                    variableScope[varChan.GetName()] = newValue; // Assign new value (Token)
                }
                else if (evalStep.Type().Equals("FUNC_CALL"))
                // Call a function
                {
                    FuncCall functionCall = (FuncCall)evalStep;                                                   // Cast as we know it is a FuncCall obj now
                    if (!functionCall.GetName().Equals("inputstr") && !functionCall.GetName().Equals("inputint")) // If NOT calling 'input' function
                    {
                        CallFunction(functionCall.GetName(), ResolveExpression(functionCall.GetArguments()));
                        // Call function with name and *resolved* list of arguments
                        // Resolve function always outputs a single token which is the result of an expression (list of tokens) being evaluated
                    }
                    else
                    // SPECIAL CASE: Calling inputStr or inputInt functions indicates that the 'argument' is NOT an expression to be resolved, but rather a variable name to store input value in.
                    // This means functionCall.Argumnets() will only have 1 token:
                    {
                        CallFunction(functionCall.GetName(), functionCall.GetArguments()[0]); // Pass in first value in Arguments as there only should be one - the variable to be input to
                    }
                }
                else
                {
                    throw new SyntaxError();  // Unrecognised Step, crash program.
                }
            }
        }
예제 #21
0
        internal static void QueueFC(TcpClient client, int func_id, string[] str_args) //выбор функции по ID, попытка парсинга аргументов и постановки в очередь
        {
            FuncCall call;

            if (Flags.market_closed) //проверка на приостановку торгов
            {
                if (Enum.IsDefined(typeof(MarketClosedForbiddenFuncIds), func_id))
                {
                    CoreResponse.RejectMarketClosed(client);
                    return;
                }
            }

            switch (func_id)
            {
            case (int)FuncIds.PlaceLimit:     //подать лимитную заявку
            {
                int     user_id;
                bool    side;
                decimal amount, rate, sl_rate, tp_rate, ts_offset;
                if (int.TryParse(str_args[0], out user_id) && !String.IsNullOrEmpty(str_args[1]) && str_args[2].TryParseToBool(out side) && decimal.TryParse(str_args[3], out amount) && decimal.TryParse(str_args[4], out rate) && decimal.TryParse(str_args[5], out sl_rate) && decimal.TryParse(str_args[6], out tp_rate) && decimal.TryParse(str_args[7], out ts_offset))
                {
                    call        = new FuncCall();
                    call.Action = () =>
                    {
                        StatusCodes status = App.core.PlaceLimit(user_id, str_args[1], side, amount, rate, sl_rate, tp_rate, ts_offset, call.FuncCallId, FCSources.Marketmaker);
                        CoreResponse.ReportExecRes(client, call.FuncCallId, (int)status);
                    };
                    Console.WriteLine(DateTime.Now + " To queue core.PlaceLimit(" + str_args[0] + ", " + str_args[1] + ", " + str_args[2] + ", " + str_args[3] + ", " + str_args[4] + ", " + str_args[5] + ", " + str_args[6] + ", " + str_args[7] + ")");
                    break;
                }
                else
                {
                    CoreResponse.RejectInvalidFuncArgs(client);
                    return;
                }
            }

            case (int)FuncIds.PlaceMarket:     //подать рыночную заявку
            {
                int     user_id;
                bool    side, base_amount;
                decimal amount, sl_rate, tp_rate, ts_offset;
                if (int.TryParse(str_args[0], out user_id) && !String.IsNullOrEmpty(str_args[1]) && str_args[2].TryParseToBool(out side) && str_args[3].TryParseToBool(out base_amount) && decimal.TryParse(str_args[4], out amount) && decimal.TryParse(str_args[5], out sl_rate) && decimal.TryParse(str_args[6], out tp_rate) && decimal.TryParse(str_args[7], out ts_offset))
                {
                    call        = new FuncCall();
                    call.Action = () =>
                    {
                        StatusCodes status = App.core.PlaceMarket(user_id, str_args[1], side, base_amount, amount, sl_rate, tp_rate, ts_offset, call.FuncCallId, FCSources.Marketmaker);
                        CoreResponse.ReportExecRes(client, call.FuncCallId, (int)status);
                    };
                    Console.WriteLine(DateTime.Now + " To queue core.PlaceMarket(" + str_args[0] + ", " + str_args[1] + ", " + str_args[2] + ", " + str_args[3] + ", " + str_args[4] + ", " + str_args[5] + ", " + str_args[6] + ", " + str_args[7] + ")");
                    break;
                }
                else
                {
                    CoreResponse.RejectInvalidFuncArgs(client);
                    return;
                }
            }

            case (int)FuncIds.CancelOrder:     //отменить заявку
            {
                int  user_id;
                long order_id;
                if (int.TryParse(str_args[0], out user_id) && long.TryParse(str_args[1], out order_id))
                {
                    call        = new FuncCall();
                    call.Action = () =>
                    {
                        StatusCodes status = App.core.CancelOrder(user_id, order_id, call.FuncCallId, FCSources.Marketmaker);
                        CoreResponse.ReportExecRes(client, call.FuncCallId, (int)status);
                    };
                    Console.WriteLine(DateTime.Now + " To queue core.CancelOrder(" + str_args[0] + ", " + str_args[1] + ")");
                    break;
                }
                else
                {
                    CoreResponse.RejectInvalidFuncArgs(client);
                    return;
                }
            }

            default:
            {
                CoreResponse.RejectFuncNotFound(client);
                return;
            }
            }

            //сообщаем об успешной регистрации FC
            CoreResponse.AcceptFC(client, call.FuncCallId);

            //ставим в очередь вызов функции
            Queues.stdf_queue.Enqueue(call);
        }