Beispiel #1
0
        private AST Convert(AST candidate)
        {
            switch (candidate.Type)
            {
            case TreeType.IDENTIFIER:
                return(candidate.Evaluate(this.env));

            case TreeType.FUNCTION_CALL:
                return(candidate.Evaluate(this.env));

            default:
                return(candidate);
            }
        }
Beispiel #2
0
        private AST ApplyPLUS(Token oparata, AST op1, AST op2)
        {
            AST firstType  = op1.Evaluate(this.env);
            AST secondType = op2.Evaluate(this.env);

            if (checkType(firstType, TreeType.NUMBER) && checkType(secondType, TreeType.NUMBER))
            {
                //Both are numbers
                Number first  = firstType as Number;
                Number second = secondType as Number;
                return(new Tree.Number((first.Value + second.Value).ToString()));
            }
            else if (checkType(firstType, TreeType.STRING) && checkType(secondType, TreeType.STRING))
            {
                //Concat strings
                Tree.String first  = firstType as Tree.String;
                Tree.String second = secondType as Tree.String;
                return(new Tree.String(first.Value + second.Value));
            }
            else
            {
                this.Error("Operator + cannot be applied to operands of type " + op1.Type + " and " + op2.Type, oparata.Row, oparata.Column);
                return(new Null());
            }
        }
Beispiel #3
0
        public override dynamic Solve(Env.Environment env)
        {
            Env.Environment environ = Env.Environment.Scope(env);
            AST             value   = environ.Get(this.Parameters[0]);
            dynamic         print   = "";

            if (value.Type == TreeType.LIST)
            {
                print = value.Evaluate(environ).ToString();
            }
            else if (value.Type == TreeType.LIST_ACCESS)
            {
                print = value.Evaluate(env).ToString();
            }
            else
            {
                print = value.Evaluate(environ).Value;
            }
            using (StreamWriter writer = new StreamWriter(Console.OpenStandardOutput())) {
                writer.Write(print.ToString() + "\n");
            }
            return(value);
        }
Beispiel #4
0
        public override dynamic Evaluate(Env.Environment env)
        {
            if (this.right.Type == TreeType.LIST)
            {
                Tree.List  right = this.right as List;
                List <AST> items = new List <AST>();
                foreach (AST item in right.Items)
                {
                    items.Add(item.Evaluate(env));
                }
                this.right = new Tree.List(items);
            }
            AST final = this.right.Evaluate(env);

            if (final.Type == TreeType.LIST_ACCESS)
            {
                final = final.Evaluate(env);
            }
            env.Set(this.left, final);
            return(this.right);
        }
Beispiel #5
0
        public AST Apply(Token operata, AST op1, AST op2)
        {
            op1 = this.Convert(op1);
            if (!operata.Is(TokenType.FULL_STOP))
            {
                op2 = this.Convert(op2);
            }

            switch (operata.Type)
            {
            case TokenType.TIMES:
                return(new Tree.Number((op1.Evaluate(this.env).Value *op2.Evaluate(this.env).Value).ToString()));

            case TokenType.DIVIDE:
                return(new Tree.Number((op1.Evaluate(this.env).Value / op2.Evaluate(this.env).Value).ToString()));

            case TokenType.PLUS:
                return(this.ApplyPLUS(operata, op1, op2));

            case TokenType.MINUS:
                return(new Tree.Number((op1.Evaluate(this.env).Value - op2.Evaluate(this.env).Value).ToString()));

            case TokenType.MODULUS:
                return(new Tree.Number((op1.Evaluate(this.env).Value % op2.Evaluate(this.env).Value).ToString()));

            case TokenType.EQUAL_TO:
                return(new Tree.Boolean((op1.Evaluate(this.env).Value == op2.Evaluate(this.env).Value).ToString()));

            case TokenType.NOT_EQUAL_TO:
                return(new Tree.Boolean((op1.Evaluate(this.env).Value != op2.Evaluate(this.env).Value).ToString()));

            case TokenType.LESS_THAN:
                return(new Tree.Boolean((op1.Evaluate(this.env).Value < op2.Evaluate(this.env).Value).ToString()));

            case TokenType.LESS_THAN_OR_EQUAL_TO:
                return(new Tree.Boolean((op1.Evaluate(this.env).Value <= op2.Evaluate(this.env).Value).ToString()));

            case TokenType.GREATER_THAN:
                return(new Tree.Boolean((op1.Evaluate(this.env).Value > op2.Evaluate(this.env).Value).ToString()));

            case TokenType.GREATER_THAN_OR_EQUAL_TO:
                return(new Tree.Boolean((op1.Evaluate(env).Value >= op2.Evaluate(env).Value).ToString()));

            case TokenType.LOGICAL_AND:
                var op1Res = op1.Evaluate(this.env).Value;
                var op2Res = op2.Evaluate(this.env).Value;
                return(new Tree.Boolean((op1Res && op2Res).ToString()));

            case TokenType.LOGICAL_OR:
                var operationOneRes = op1.Evaluate(this.env).Value;
                var operationTwoRes = op2.Evaluate(this.env).Value;
                return(new Tree.Boolean((operationOneRes || operationTwoRes).ToString()));

            case TokenType.FULL_STOP:
                return(this.AccessModifier(op1, op2));

            default:
                this.Error(operata.Type + " cannot be used as an expression operator", operata.Row, operata.Column);
                return(null);
            }
        }