Example #1
0
        private RuntimeResult VisitVarAccessNode(VarAccessNode node, Context context)
        {
            string name = node.Token.Value.ToString();

            if (name == "null")
            {
                return(new RuntimeResult(new Values.NullValue().SetPositionAndContext(node.Token.Position, context)));
            }
            else if (name == "true")
            {
                return(new RuntimeResult(new Values.IntegerValue(1, true).SetPositionAndContext(node.Token.Position, context)));
            }
            else if (name == "false")
            {
                return(new RuntimeResult(new Values.IntegerValue(0, true).SetPositionAndContext(node.Token.Position, context)));
            }
            Values.Value value = context.GetSymbol(name);
            if (value != null)
            {
                return(new RuntimeResult(value));
            }
            return(new RuntimeResult(new RuntimeError(node.Token.Position, "Variable '" + name + "' not defined----", context)));
        }
Example #2
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 #3
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)));
        }