Ejemplo n.º 1
0
    protected void ResolveVarExpr(AstVarExpr expr)
    {
        var scope = Scope();

        if (scope == null)
        {
            return;                 // TODO: Better global handling
        }
        if (expr.m_instance != null)
        {
            // Can't resolve properties (i.e., right-hand side of .), but we still want to resolve the instance (i.e., left-hand-side of .)

            ResolveExpr(expr.m_instance);
        }
        else
        {
            if (scope.ContainsKey(expr.m_identifier.m_identifier) && !scope[expr.m_identifier.m_identifier])
            {
                m_error = true;
                Lox.Error(expr.m_startLine, "Cannot use identifier \"" + expr.m_identifier.m_identifier + "\" in it's own initialization.");
                return;
            }

            ResolveLocal(expr.m_identifier, expr.m_startLine);
        }
    }
Ejemplo n.º 2
0
    protected object EvaluateVarExpr(AstVarExpr expr)
    {
        if (HadErrorOrReturn())
        {
            return(null);
        }

        if (expr.m_instance == null)
        {
            object result  = null;
            bool   success = m_environment.Get(expr.m_identifier, out result);

            if (!success)
            {
                m_runtimeError = true;
                Lox.Error(expr.m_startLine, "Undeclared identifier \"" + expr.m_identifier.m_identifier + "\"");
                return(null);
            }

            return(result);
        }
        else
        {
            object   instanceObj = EvaluateExpr(expr.m_instance);
            Instance instance    = instanceObj as Instance;

            if (instance != null)
            {
                object value;
                bool   success = instance.TryGetMember(expr.m_identifier.m_identifier, out value);

                if (success)
                {
                    return(value);
                }

                m_runtimeError = true;
                Lox.Error(expr.m_startLine, "Undefined member \"" + expr.m_identifier + "\"");
                return(null);
            }
            else
            {
                m_runtimeError = true;
                Lox.Error(expr.m_startLine, "Only class instances can access properties with '.'");
                return(null);
            }
        }
    }
Ejemplo n.º 3
0
    protected AstExpr ParseFunCallExpr()
    {
        AstExpr expr = ParsePrimaryExpr();

        if (expr == null)
        {
            return(EmptyErrorExpr());
        }

        Token token;

        // NOTE (andrews) While loop handles chained function calls and member access like this:
        //  some.member.functionThatReturnsFunction()();

        while (true)
        {
            if ((token = TryMatch(TOKENK.OpenParen)) != null)
            {
                bool           isFirstArg = true;
                List <AstExpr> args       = new List <AstExpr>();
                while ((token = TryMatch(TOKENK.CloseParen)) == null)
                {
                    if (!isFirstArg)
                    {
                        AstExpr prevArg = args[args.Count - 1];

                        if ((token = TryMatch(TOKENK.Comma)) == null)
                        {
                            return(ErrorExpr(prevArg.m_startLine, "Expected ',' in argument list"));
                        }

                        if (args.Count == AstFunCallExpr.s_maxArgCount)
                        {
                            // NOTE (andrews) This isn't a parse error so we don't return ErrorExpr like we do for other parse errors.
                            //  This lets us report it while continuing the parse in case we find other errors.

                            Lox.Error(prevArg.m_startLine, "Cannot exceed " + AstFunCallExpr.s_maxArgCount + " arguments");
                        }
                    }

                    AstExpr arg = ParseExpr();
                    if (arg == null)
                    {
                        return(EmptyErrorExpr());
                    }

                    args.Add(arg);
                    isFirstArg = false;
                }

                expr = new AstFunCallExpr(expr, args);
            }
            else if ((token = TryMatch(TOKENK.Dot)) != null)
            {
                if ((token = TryMatch(TOKENK.Identifier)) != null)
                {
                    expr = new AstVarExpr(expr, token);
                }
            }
            else
            {
                return(expr);
            }
        }
    }
Ejemplo n.º 4
0
 public AstAssignmentExpr(AstVarExpr lhs, AstExpr rhs)
     : base(EXPRK.Assignment, lhs.m_startLine)
 {
     m_lhs = lhs;
     m_rhs = rhs;
 }