Exemple #1
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)));
        }
Exemple #2
0
        private RuntimeResult VisitMethodNode(MethodNode node, Context context)
        {
            string name = "anonymous";

            if (node.Token != null)
            {
                switch (node.Token.Type)
                {
                case TokenType.IDENTIFIER:
                    name = node.Token.Value.ToString();
                    break;

                case TokenType.PLUS:
                    name = "-add-";
                    break;

                case TokenType.MINUS:
                    name = "-sub-";
                    break;

                case TokenType.MULTIPLY:
                    name = "-mul-";
                    break;

                case TokenType.DIVIDE:
                    name = "-div-";
                    break;

                case TokenType.MODULUS:
                    name = "-mod-";
                    break;

                case TokenType.EXPONENT:
                    name = "-exp-";
                    break;

                case TokenType.STRING:
                    name = "-str-";
                    break;

                case TokenType.LEFT_SQB:
                    name = "-sst-";
                    break;

                case TokenType.LESS_THAN:
                    name = "-les-";
                    break;

                case TokenType.LESS_TOE:
                    name = "-lte-";
                    break;

                case TokenType.GREATER_THAN:
                    name = "-gre-";
                    break;

                case TokenType.GREATER_TOE:
                    name = "-gte-";
                    break;

                case TokenType.EQUALS_EQUALS:
                    name = "-eeq-";
                    break;

                case TokenType.NOT_EQUALS:
                    name = "-neq-";
                    break;

                case TokenType.BITWISE_AND:
                    name = "-ban-";
                    break;

                case TokenType.BITWISE_OR:
                    name = "-bor-";
                    break;

                case TokenType.BITWISE_XOR:
                    name = "-xor-";
                    break;

                case TokenType.COMPLEMENT:
                    name = "-com-";
                    break;

                case TokenType.EQUALS:
                    name = "-sse-";
                    break;

                case TokenType.LEFT_SHIFT:
                    name = "-lsh-";
                    break;

                case TokenType.RIGHT_SHIFT:
                    name = "-rsh-";
                    break;

                case TokenType.BOOLEAN_AND:
                    name = "-and-";
                    break;

                case TokenType.BOOLEAN_OR:
                    name = "-orr-";
                    break;

                case TokenType.BOOLEAN_NOT:
                    name = "-not-";
                    break;

                case TokenType.IN:
                    name = "-inn-";
                    break;
                }
            }
            Values.Value method = new Values.MethodValue(name, node.Parameters, node.Body, node.DefaultValues).SetPositionAndContext(node.Position, context);
            if (node.Token != null)
            {
                context.AddSymbol(name, method);
            }
            return(new RuntimeResult(method));
        }