Example #1
0
        private RuntimeResult VisitWhileNode(WhileNode node, Context context)
        {
            RuntimeResult condResult = Visit(node.Condition, context);

            if (condResult.HasError)
            {
                return(condResult);
            }
            Values.Value output = new Values.NullValue().SetPositionAndContext(node.Position, context);
            while (condResult.Value.GetAsBoolean())
            {
                RuntimeResult bodyResult = Visit(node.Body, context);
                if (bodyResult.HasError)
                {
                    return(bodyResult);
                }
                if (context.Return)
                {
                    return(bodyResult);
                }
                output = bodyResult.Value;
                if (context.Break)
                {
                    context.Break = false;
                    break;
                }
                condResult = Visit(node.Condition, context);
                if (condResult.HasError)
                {
                    return(condResult);
                }
            }
            return(new RuntimeResult(output));
        }
Example #2
0
        private RuntimeResult VisitForEachNode(ForEachNode node, Context context)
        {
            RuntimeResult iterResult = Visit(node.Iteratable, context);

            if (iterResult.HasError)
            {
                return(iterResult);
            }

            int    elementCount = iterResult.Value.GetElementCount();
            string varName      = node.Token.Value.ToString();

            for (int i = 0; i < elementCount; i++)
            {
                RuntimeResult runtimeResult = iterResult.Value.GetElementAt(i);
                if (runtimeResult.HasError)
                {
                    return(runtimeResult);
                }
                context.AddSymbol(varName, runtimeResult.Value);
                RuntimeResult bodyResult = Visit(node.Body, context);
                if (bodyResult.HasError)
                {
                    return(bodyResult);
                }
            }
            return(new RuntimeResult(iterResult.Value));
        }
Example #3
0
        private static void Execute(string code, string fname, Context context, bool inlineOutput)
        {
            Tokenizer       tokenizer       = new Tokenizer(fname, code);
            TokenizerResult tokenizerResult = tokenizer.GenerateTokens();

            if (!tokenizerResult.HasError)
            {
                Parser       parser       = new Parser(tokenizerResult.Tokens);
                ParserResult parserResult = parser.Parse();
                if (!parserResult.HasError)
                {
                    Interpreter   interpreter   = new Interpreter();
                    RuntimeResult runtimeResult = interpreter.Visit(parserResult.Node, context);
                    if (!runtimeResult.HasError)
                    {
                        if (inlineOutput)
                        {
                            Console.WriteLine(runtimeResult.Value);
                        }
                    }
                    else
                    {
                        Console.WriteLine(runtimeResult.Error);
                    }
                }
                else
                {
                    Console.WriteLine(parserResult.Error);
                }
            }
            else
            {
                Console.WriteLine(tokenizerResult.Error);
            }
        }
Example #4
0
        private RuntimeResult VisitVarAssignNode(VarAssignNode node, Context context, Context baseCtx = null)
        {
            string name = node.Token.Value.ToString();

            if (name == "null" || name == "true" || name == "false" || name == "this" || name == "base")
            {
                return(new RuntimeResult(new RuntimeError(node.Token.Position, "'" + name + "' is a reserved keyword", context)));
            }
            RuntimeResult runtimeResult = Visit(node.Node, baseCtx != null ? baseCtx : context);

            if (runtimeResult.HasError)
            {
                return(runtimeResult);
            }

            if (node.TypeToken == null)
            {
                if (context.ContainsSymbol(name) && context.GetSymbol(name).TypeDefined)
                {
                    Values.ValueType toType = context.GetSymbol(name).Type;
                    if (toType != runtimeResult.Value.Type)
                    {
                        Values.Value castedValue = runtimeResult.Value.Cast(toType);
                        if (castedValue == null)
                        {
                            return(new RuntimeResult(new RuntimeError(node.Token.Position, "Can't convert '" + runtimeResult.Value.Type.ToString().ToLower() + "' to '" + toType.ToString().ToLower() + "'", context)));
                        }
                        else
                        {
                            context.AddSymbol(name, castedValue);
                            return(runtimeResult);
                        }
                    }
                }
                context.AddSymbol(name, runtimeResult.Value);
                return(runtimeResult);
            }
            else
            {
                if (node.TypeToken.CheckKeyword("int"))
                {
                    return(TypeDefAssign(Values.ValueType.INTEGER, runtimeResult.Value, name, node.Token.Position, context));
                }
                if (node.TypeToken.CheckKeyword("complex"))
                {
                    return(TypeDefAssign(Values.ValueType.COMPLEX, runtimeResult.Value, name, node.Token.Position, context));
                }
                if (node.TypeToken.CheckKeyword("long"))
                {
                    return(TypeDefAssign(Values.ValueType.INT64, runtimeResult.Value, name, node.Token.Position, context));
                }
                if (node.TypeToken.CheckKeyword("big"))
                {
                    return(TypeDefAssign(Values.ValueType.BIGINTEGER, runtimeResult.Value, name, node.Token.Position, context));
                }
            }
            return(new RuntimeResult(new RuntimeError(node.Token.Position, "Type conversion error", context)));
        }
Example #5
0
        private RuntimeResult VisitListNode(ListNode node, Context context)
        {
            List <Values.Value> elements = new List <Values.Value>();

            for (int i = 0; i < node.ElementNodes.Count; i++)
            {
                RuntimeResult runtimeResult = Visit(node.ElementNodes[i], context);
                if (runtimeResult.HasError)
                {
                    return(runtimeResult);
                }
                elements.Add(runtimeResult.Value);
            }
            return(new RuntimeResult(new Values.ListValue(elements).SetPositionAndContext(node.Position, context)));
        }
Example #6
0
        private RuntimeResult VisitSubscriptNode(SubscriptNode node, Context context)
        {
            RuntimeResult baseResult = Visit(node.BaseNode, context);

            if (baseResult.HasError)
            {
                return(baseResult);
            }
            RuntimeResult indexResult = Visit(node.IndexNode, context);

            if (indexResult.HasError)
            {
                return(indexResult);
            }
            return(baseResult.Value.Subscript(indexResult.Value));
        }
Example #7
0
 private RuntimeResult VisitReturnNode(ReturnNode node, Context context)
 {
     if (node.Node == null)
     {
         Values.Value val = new Values.NullValue().SetPositionAndContext(node.Position, context);
         context.Return = true;
         return(new RuntimeResult(val));
     }
     else
     {
         RuntimeResult result = Visit(node.Node, context);
         if (result.HasError)
         {
             return(result);
         }
         context.Return = true;
         return(new RuntimeResult(result.Value));
     }
 }
Example #8
0
        private RuntimeResult VisitDictionaryNode(DictionaryNode node, Context context)
        {
            List <(Values.Value, Values.Value)> pairs = new List <(Values.Value, Values.Value)>();

            for (int i = 0; i < node.KeyValuePairs.Count; i++)
            {
                RuntimeResult keyResult = Visit(node.KeyValuePairs[i].Item1, context);
                if (keyResult.HasError)
                {
                    return(keyResult);
                }
                RuntimeResult valueResult = Visit(node.KeyValuePairs[i].Item2, context);
                if (valueResult.HasError)
                {
                    return(valueResult);
                }
                pairs.Add((keyResult.Value, valueResult.Value));
            }
            return(new RuntimeResult(new Values.DictionaryValue(pairs).SetPositionAndContext(node.Position, context)));
        }
Example #9
0
 private RuntimeResult VisitIfNode(IfNode node, Context context)
 {
     for (int i = 0; i < node.Cases.Count; i++)
     {
         RuntimeResult condResult = Visit(node.Cases[i].Item1, context);
         if (condResult.HasError)
         {
             return(condResult);
         }
         if (condResult.Value.GetAsBoolean())
         {
             return(Visit(node.Cases[i].Item2, context));
         }
     }
     if (node.ElseCase != null)
     {
         return(Visit(node.ElseCase, context));
     }
     return(new RuntimeResult(new Values.NullValue().SetPositionAndContext(node.Position, context)));
 }
Example #10
0
        private RuntimeResult VisitUnaryNode(UnaryNode node, Context context)
        {
            RuntimeResult runtimeResult = Visit(node.Node, context);

            if (runtimeResult.HasError)
            {
                return(runtimeResult);
            }
            if (node.Token.Type == TokenType.MINUS)
            {
                return(runtimeResult.Value.Multiply(new Values.IntegerValue(-1).SetPositionAndContext(node.Token.Position, context)));
            }
            else if (node.Token.Type == TokenType.BOOLEAN_NOT)
            {
                return(runtimeResult.Value.BooleanNot());
            }
            else if (node.Token.Type == TokenType.COMPLEMENT)
            {
                return(runtimeResult.Value.BitwiseComplement());
            }
            return(null); // todo: error handling
        }
Example #11
0
 private RuntimeResult VisitWhenNode(WhenNode node, Context context)
 {
     Values.Value variable = context.GetSymbol(node.Token.Value.ToString());
     if (variable == null)
     {
         return(new RuntimeResult(new RuntimeError(node.Token.Position, "Variable '" + node.Token.Value + "' not defined", context)));
     }
     for (int i = 0; i < node.Cases.Count; i++)
     {
         RuntimeResult condResult = Visit(node.Cases[i].Item1, context);
         if (condResult.HasError)
         {
             return(condResult);
         }
         if (condResult.Value.Equals(variable).Value.GetAsBoolean())
         {
             return(Visit(node.Cases[i].Item2, context));
         }
     }
     //if (node.ElseCase != null)
     //    return Visit(node.ElseCase, context);
     return(new RuntimeResult(new Values.NullValue().SetPositionAndContext(node.Token.Position, context)));
 }
Example #12
0
        private RuntimeResult VisitSubscriptAssignNode(SubscriptAssignNode node, Context context)
        {
            SubscriptNode subscript    = (SubscriptNode)node.Target;
            RuntimeResult targetResult = Visit(subscript.BaseNode, context);

            if (targetResult.HasError)
            {
                return(targetResult);
            }
            RuntimeResult indexResult = Visit(subscript.IndexNode, context);

            if (indexResult.HasError)
            {
                return(indexResult);
            }
            RuntimeResult exprResult = Visit(node.Node, context);

            if (exprResult.HasError)
            {
                return(exprResult);
            }
            return(targetResult.Value.SubscriptAssign(indexResult.Value, exprResult.Value));
        }
Example #13
0
 private RuntimeResult VisitDoNode(DoNode node, Context context)
 {
     Values.Value output = new Values.NullValue().SetPositionAndContext(node.Position, context);
     while (true)
     {
         RuntimeResult bodyResult = Visit(node.Body, context);
         if (bodyResult.HasError)
         {
             return(bodyResult);
         }
         output = bodyResult.Value;
         RuntimeResult condResult = Visit(node.Condition, context);
         if (condResult.HasError)
         {
             return(condResult);
         }
         if (!condResult.Value.GetAsBoolean())
         {
             break;
         }
     }
     return(new RuntimeResult(output));
 }
Example #14
0
 private RuntimeResult VisitBlockNode(BlockNode node, Context context)
 {
     Values.Value output = new Values.NullValue().SetPositionAndContext(node.Position, context);
     for (int i = 0; i < node.Statements.Count; i++)
     {
         RuntimeResult runtimeResult = Visit(node.Statements[i], context);
         if (runtimeResult.HasError)
         {
             return(runtimeResult);
         }
         if (context.Return)
         {
             return(runtimeResult);
         }
         if (context.Continue)
         {
             context.Continue = false;
             return(runtimeResult);
         }
         output = runtimeResult.Value;
     }
     return(new RuntimeResult(output));
 }
Example #15
0
        private RuntimeResult VisitAttributeNode(AttributeNode node, Context context)
        {
            RuntimeResult runtimeResult = Visit(node.BaseNode, context);

            if (runtimeResult.HasError)
            {
                return(runtimeResult);
            }

            if (node.Node.Type == NodeType.VAR_ASSIGN)
            {
                return(VisitVarAssignNode((VarAssignNode)node.Node, runtimeResult.Value.Context, context));
            }
            else if (node.Node.Type == NodeType.CALL)
            {
                if (runtimeResult.Value.Type == Values.ValueType.ASSEMBLY)
                {
                    CallNode             callNode = (CallNode)node.Node;
                    Values.AssemblyValue asmVal   = (Values.AssemblyValue)runtimeResult.Value;
                    string        name            = ((VarAccessNode)callNode.Node).Token.Value.ToString();
                    List <object> args            = new List <object>();
                    for (int i = 0; i < callNode.Arguments.Count; i++)
                    {
                        RuntimeResult result = Visit(callNode.Arguments[i].Item2, context);
                        if (result.HasError)
                        {
                            return(result);
                        }
                        if (result.Value.Type == Values.ValueType.LIST)
                        {
                            object[] array = Util.ListToArray(result.Value);
                            if (array == null)
                            {
                                return(new RuntimeResult(new RuntimeError(callNode.Position, "Error while converting list to an array", context)));
                            }
                            args.Add(array);
                        }
                        else if (result.Value.Type == Values.ValueType.BYTE_ARRAY)
                        {
                            byte[] array = ((Values.ByteArrayValue)result.Value).Bytes.ToArray();
                            args.Add(array);
                        }
                        else if (result.Value.IsBoolean)
                        {
                            args.Add(result.Value.GetAsBoolean());
                        }
                        else
                        {
                            args.Add(result.Value.Data);
                        }
                    }
                    return(asmVal.Invoke(name, args.ToArray()));
                }
                else if (Util.isPremitiveType(runtimeResult.Value.Type) || runtimeResult.Value.Type == Values.ValueType.C_SHARP)
                {
                    CallNode callNode = (CallNode)node.Node;
                    List <(string, Values.Value)> args = new List <(string, Values.Value)>();
                    for (int i = 0; i < callNode.Arguments.Count; i++)
                    {
                        RuntimeResult result = Visit(callNode.Arguments[i].Item2, context);
                        if (result.HasError)
                        {
                            return(result);
                        }
                        args.Add((callNode.Arguments[i].Item1, result.Value));
                    }
                    string name = ((VarAccessNode)callNode.Node).Token.Value.ToString();
                    return(runtimeResult.Value.CallMethod(name, args));
                }
                return(VisitCallNode((CallNode)node.Node, runtimeResult.Value.Context, context));
            }
            else if (node.Node.Type == NodeType.VAR_ACCESS)
            {
                if (runtimeResult.Value.Type == Values.ValueType.ASSEMBLY || runtimeResult.Value.Type == Values.ValueType.C_SHARP)
                {
                    VarAccessNode vaccess = (VarAccessNode)node.Node;
                    return(runtimeResult.Value.GetAttribute(vaccess.Token.Value.ToString()));
                }
            }
            return(Visit(node.Node, runtimeResult.Value.Context));
        }
Example #16
0
        private RuntimeResult VisitBinaryNode(BinaryNode node, Context context, Context other = null)
        {
            RuntimeResult leftResult = Visit(node.LeftNode, context);

            if (leftResult.HasError)
            {
                return(leftResult);
            }
            RuntimeResult rightResult = Visit(node.RightNode, other != null ? other : context);

            if (rightResult.HasError)
            {
                return(rightResult);
            }

            if (node.OpToken.Type == TokenType.PLUS)
            {
                return(leftResult.Value.Add(rightResult.Value));
            }
            else if (node.OpToken.Type == TokenType.MINUS)
            {
                return(leftResult.Value.Substract(rightResult.Value));
            }
            else if (node.OpToken.Type == TokenType.MULTIPLY)
            {
                return(leftResult.Value.Multiply(rightResult.Value));
            }
            else if (node.OpToken.Type == TokenType.DIVIDE)
            {
                return(leftResult.Value.Divide(rightResult.Value));
            }
            else if (node.OpToken.Type == TokenType.MODULUS)
            {
                return(leftResult.Value.Modulus(rightResult.Value));
            }
            else if (node.OpToken.Type == TokenType.EXPONENT)
            {
                return(leftResult.Value.Exponent(rightResult.Value));
            }

            else if (node.OpToken.Type == TokenType.BITWISE_AND)
            {
                return(leftResult.Value.BitwiseAnd(rightResult.Value));
            }
            else if (node.OpToken.Type == TokenType.BITWISE_OR)
            {
                return(leftResult.Value.BitwiseOr(rightResult.Value));
            }
            else if (node.OpToken.Type == TokenType.BITWISE_XOR)
            {
                return(leftResult.Value.BitwiseXor(rightResult.Value));
            }
            else if (node.OpToken.Type == TokenType.BITWISE_OR)
            {
                return(leftResult.Value.BitwiseOr(rightResult.Value));
            }
            else if (node.OpToken.Type == TokenType.BITWISE_XOR)
            {
                return(leftResult.Value.BitwiseXor(rightResult.Value));
            }
            else if (node.OpToken.Type == TokenType.LEFT_SHIFT)
            {
                return(leftResult.Value.LeftShift(rightResult.Value));
            }
            else if (node.OpToken.Type == TokenType.RIGHT_SHIFT)
            {
                return(leftResult.Value.RightShift(rightResult.Value));
            }

            else if (node.OpToken.Type == TokenType.EQUALS_EQUALS)
            {
                return(leftResult.Value.Equals(rightResult.Value));
            }
            else if (node.OpToken.Type == TokenType.NOT_EQUALS)
            {
                return(leftResult.Value.NotEquals(rightResult.Value));
            }
            else if (node.OpToken.Type == TokenType.GREATER_THAN)
            {
                return(leftResult.Value.GreaterThan(rightResult.Value));
            }
            else if (node.OpToken.Type == TokenType.LESS_THAN)
            {
                return(leftResult.Value.LessThan(rightResult.Value));
            }
            else if (node.OpToken.Type == TokenType.GREATER_TOE)
            {
                return(leftResult.Value.GreaterOrEqual(rightResult.Value));
            }
            else if (node.OpToken.Type == TokenType.LESS_TOE)
            {
                return(leftResult.Value.LessOrEqual(rightResult.Value));
            }

            else if (node.OpToken.Type == TokenType.BOOLEAN_AND)
            {
                return(leftResult.Value.BooleanAnd(rightResult.Value));
            }
            else if (node.OpToken.Type == TokenType.BOOLEAN_OR)
            {
                return(leftResult.Value.BooleanOr(rightResult.Value));
            }
            else if (node.OpToken.Type == TokenType.IN)
            {
                return(leftResult.Value.In(rightResult.Value));
            }

            return(null); // todo: error handling
        }
Example #17
0
        private RuntimeResult VisitCallNode(CallNode node, Context context, Context fromCtx = null)
        {
            List <(string, Values.Value)> args = new List <(string, Values.Value)>();

            for (int i = 0; i < node.Arguments.Count; i++)
            {
                RuntimeResult result = Visit(node.Arguments[i].Item2, fromCtx == null ? context : fromCtx);
                if (result.HasError)
                {
                    return(result);
                }
                args.Add((node.Arguments[i].Item1, result.Value));
            }
            if (node.Node.Type == NodeType.VAR_ACCESS)
            {
                VarAccessNode accessNode = (VarAccessNode)node.Node;
                string        name       = accessNode.Token.Value.ToString();
                if (BuiltinMethods.BuiltinMethodList.ContainsKey(name))
                {
                    return(BuiltinMethods.Execute(name, args, node.Position, context));
                }
                else
                {
                    Values.Value method = context.GetSymbol(name);
                    if (method == null)
                    {
                        return(new RuntimeResult(new RuntimeError(node.Position, "Method '" + name + "' is not defined", context)));
                    }
                    if (method.Type == Values.ValueType.METHOD)
                    {
                        return(((Values.MethodValue)method).Execute(args, this));
                    }
                    else if (method.Type == Values.ValueType.CLASS)
                    {
                        Values.ClassValue classValue = ((Values.ClassValue)method).Clone();
                        //classValue.Type = Values.ValueType.OBJECT;
                        if (classValue.BaseClass != null)
                        {
                            RuntimeResult baseResult = classValue.InitializeBaseClass(context, this);
                            if (baseResult.HasError)
                            {
                                return(baseResult);
                            }

                            Context newContext = new Context(name, baseResult.Value.Context);
                            classValue.SetPositionAndContext(accessNode.Token.Position, newContext);
                            newContext.AddSymbol("this", classValue);
                            newContext.AddSymbol("base", baseResult.Value);
                            RuntimeResult runtimeResult = Visit(classValue.Body, newContext);
                            if (runtimeResult.HasError)
                            {
                                return(runtimeResult);
                            }

                            //Constructor
                            Values.Value ctorValue = newContext.GetSymbol("init");
                            if (ctorValue != null && ctorValue.Type == Values.ValueType.METHOD)
                            {
                                Values.MethodValue initMethod = (Values.MethodValue)ctorValue;
                                RuntimeResult      res        = initMethod.Execute(args, this);
                                if (res.HasError)
                                {
                                    return(res);
                                }
                            }
                            return(new RuntimeResult(classValue));
                        }
                        else
                        {
                            Context newContext = new Context(name, context);
                            classValue.SetPositionAndContext(accessNode.Token.Position, newContext);
                            newContext.AddSymbol("this", classValue);
                            RuntimeResult runtimeResult = Visit(classValue.Body, newContext);
                            if (runtimeResult.HasError)
                            {
                                return(runtimeResult);
                            }

                            //Constructor
                            Values.Value ctorValue = newContext.GetSymbol("init");
                            if (ctorValue != null && ctorValue.Type == Values.ValueType.METHOD)
                            {
                                Values.MethodValue initMethod = (Values.MethodValue)ctorValue;
                                initMethod.Execute(args, this);
                            }
                            return(new RuntimeResult(classValue));
                        }
                    }
                    return(new RuntimeResult(new RuntimeError(node.Position, "'" + name + "' is not a method", context)));
                }
            }
            return(new RuntimeResult(new RuntimeError(node.Position, "Can't call as a method", context)));
        }
Example #18
0
        private RuntimeResult VisitForNode(ForNode node, Context context)
        {
            RuntimeResult startResult = Visit(node.Start, context);

            if (startResult.HasError)
            {
                return(startResult);
            }
            if (startResult.Value.Type != Values.ValueType.INTEGER)
            {
                return(new RuntimeResult(new RuntimeError(node.Token.Position, "Start value must be an integer", context)));
            }
            int           start     = (int)startResult.Value.Data;
            RuntimeResult endResult = Visit(node.End, context);

            if (endResult.HasError)
            {
                return(endResult);
            }
            if (endResult.Value.Type != Values.ValueType.INTEGER)
            {
                return(new RuntimeResult(new RuntimeError(node.Token.Position, "Stop value must be an integer", context)));
            }
            int end  = (int)endResult.Value.Data;
            int step = 1;

            if (node.Step != null)
            {
                RuntimeResult stepResult = Visit(node.Step, context);
                if (stepResult.HasError)
                {
                    return(stepResult);
                }
                if (endResult.Value.Type != Values.ValueType.INTEGER)
                {
                    return(new RuntimeResult(new RuntimeError(node.Token.Position, "Step value must be an integer", context)));
                }
                step = (int)stepResult.Value.Data;
            }
            string id = node.Token.Value.ToString();

            context.AddSymbol(id, startResult.Value);
            Values.Value output = new Values.NullValue().SetPositionAndContext(node.Token.Position, context);
            if (step > 0)
            {
                while (start < end)
                {
                    RuntimeResult bodyResult = Visit(node.Body, context);
                    if (bodyResult.HasError)
                    {
                        return(bodyResult);
                    }
                    if (context.Return)
                    {
                        return(bodyResult);
                    }
                    output = bodyResult.Value;
                    if (context.Break)
                    {
                        context.Break = false;
                        break;
                    }
                    start += step;
                    startResult.Value.Data = start;
                }
            }
            else
            {
                while (start > end)
                {
                    RuntimeResult bodyResult = Visit(node.Body, context);
                    if (bodyResult.HasError)
                    {
                        return(bodyResult);
                    }
                    if (context.Return)
                    {
                        return(bodyResult);
                    }
                    output = bodyResult.Value;
                    if (context.Break)
                    {
                        context.Break = false;
                        break;
                    }
                    start += step;
                    startResult.Value.Data = start;
                }
            }
            return(new RuntimeResult(output));
        }