示例#1
0
    int Visit(AssignContext acontext)
    {
        COOL_TYPE vartype  = GetType(acontext.var_value);
        string    varname  = acontext.ID().GetText();
        var       varvalue = Visit(acontext.var_value);

        foreach (var item in variable_type)
        {
            if (item.Key == varname)
            {
                if (item.Value == vartype)
                {
                    variable_value[varname] = varvalue;
                    return(0);
                }
                else
                {
                    /// Manejar esto
                    throw new Exception("No puedes asignar a la variable algo de tipo distinto al que fue declarado.");
                }
            }
        }

        /// Manejar que la variable no este declarada
        return(1);
    }
示例#2
0
        public override Node VisitAssign([NotNull] AssignContext context)
        {
            var names = context.nestedName().Name().Select(x => x.GetText()).ToList();
            var expr  = VisitExpr(context.expr());

            return(new AssignNode(names, expr, GetLocation(context)));
        }
示例#3
0
 public override object VisitAssign([NotNull] AssignContext context)
 {
     if (context.op.Type == Assign)
     {
         return("=");
     }
     return(context.op.Text);
 }
        public override ASTN VisitAssign([NotNull] AssignContext context)
        {
            AssignNode node = new AssignNode(context)
            {
                Id       = new IdNode(context, context.var_name.Text),
                exprBody = VisitExpr(context.var_value) as ExprNode
            };

            return(node);
        }
示例#5
0
    public AssignContext assign()
    {
        AssignContext _localctx = new AssignContext(Context, State);

        EnterRule(_localctx, 4, RULE_assign);
        try {
            State = 28;
            ErrorHandler.Sync(this);
            switch (Interpreter.AdaptivePredict(TokenStream, 1, Context))
            {
            case 1:
                EnterOuterAlt(_localctx, 1);
                {
                    State = 20;
                    Match(ID);
                    State = 21;
                    Match(EQ);
                    State = 22;
                    Match(NUM);
                    State = 23;
                    Match(SEMI);
                }
                break;

            case 2:
                EnterOuterAlt(_localctx, 2);
                {
                    State = 24;
                    Match(ID);
                    State = 25;
                    Match(EQ);
                    State = 26;
                    Match(STRINGCONST);
                    State = 27;
                    Match(SEMI);
                }
                break;
            }
        }
        catch (RecognitionException re) {
            _localctx.exception = re;
            ErrorHandler.ReportError(this, re);
            ErrorHandler.Recover(this, re);
        }
        finally {
            ExitRule();
        }
        return(_localctx);
    }
        public StatContext stat()
        {
            StatContext _localctx = new StatContext(_ctx, State);

            EnterRule(_localctx, 2, RULE_stat);
            try {
                State = 20;
                switch (Interpreter.AdaptivePredict(_input, 1, _ctx))
                {
                case 1:
                    _localctx = new PrintExprContext(_localctx);
                    EnterOuterAlt(_localctx, 1);
                    {
                        State = 11; expr(0);
                        State = 12; Match(NEWLINE);
                    }
                    break;

                case 2:
                    _localctx = new AssignContext(_localctx);
                    EnterOuterAlt(_localctx, 2);
                    {
                        State = 14; Match(ID);
                        State = 15; Match(3);
                        State = 16; expr(0);
                        State = 17; Match(NEWLINE);
                    }
                    break;

                case 3:
                    _localctx = new BlankContext(_localctx);
                    EnterOuterAlt(_localctx, 3);
                    {
                        State = 19; Match(NEWLINE);
                    }
                    break;
                }
            }
            catch (RecognitionException re) {
                _localctx.exception = re;
                _errHandler.ReportError(this, re);
                _errHandler.Recover(this, re);
            }
            finally {
                ExitRule();
            }
            return(_localctx);
        }
示例#7
0
 public override object VisitAssign(AssignContext context)
 {
     return(context.op.Text);
 }
示例#8
0
        private TypedContext GetContext(IScopeOwner context, int opDepth, int callDepth, int flags)
        {
            tokenizer.advance(0);
            var          s0  = tokenizer.peekNext().value;
            TypedContext ret = null;

            //number
            if (int.TryParse(s0, out int unused) &&
                tokenizer.peekNext().value == "." &&
                float.TryParse(tokenizer.peekNext().value, out float num))
            {
                tokenizer.advance(2);
                s0 += "." + num;
            }
            else
            {
                tokenizer.advance(0);
                tokenizer.peekNext();
            }

            //parenthesis
            if (s0 == "")
            {
                tokenizer.advance(0);
                return(null);
            }
            else if (s0 == "(")
            {
                if (tokenizer.peekNext().value == ")")
                {
                    ret = new ParenContext()
                    {
                        parent = context
                    };
                    tokenizer.advance(1);
                }
                else
                {
                    tokenizer.advance(1);
                    var t1  = GetContext(context, 0, 0, NoBlocks);
                    var sn1 = tokenizer.peekNext().value;
                    if (sn1 == ")" && t1 is TypedContext)
                    {
                        ret = new ParenContext()
                        {
                            parent = context, interior = t1 as TypedContext
                        }
                    }
                    ;
                    else
                    {
                        throw new Exception("yeet");
                    }
                }
            }

            //blocks and array declaration
            else if (blockMode == BlockMode.brackets && s0 == "{")
            {
                tokenizer.advance(1);
                var cret = new BlockContext();
                while (tokenizer.peekNext().value != "}")
                {
                    var next = GetContext(context, opDepth, 0, flags);
                    if (next != null)
                    {
                        cret.body.Add(next);
                    }
                    else
                    {
                        throw new Exception("hmm");
                    }
                }
                if (cret.body.Count == 1 && cret.body[0] is SeperatedContext)
                {
                    tokenizer.advance(0);
                    var aret = new ArrayContext()
                    {
                        parent = context
                    };
                    aret.content = (cret.body[0] as SeperatedContext)?.children ?? new List <TypedContext>()
                    {
                        cret.body[0]
                    };
                    aret.type = $"{SysLib.ArrayType.name}<{aret.content[0].type}>";
                    ret       = aret;
                }
                else
                {
                    tokenizer.advance(0);
                    ret = cret;
                }
            }

            //list declaration
            else if (s0 == "[")
            {
                tokenizer.advance(1);
                var t2 = GetContext(context, opDepth, callDepth + 1, flags);
                if (tokenizer.peekNext().value != "]")
                {
                    throw new Exception("Expected one of these: ]");
                }
                var cret = new ListContext();
                cret.parent  = context;
                cret.content = (t2 as SeperatedContext)?.children ?? new List <TypedContext>()
                {
                    t2
                };
                cret.type = $"{SysLib.ListType.name}<{cret.content[0].type}>";
                ret       = cret;
            }

            //for, while, foreach
            else if (s0 == "for")
            {
                tokenizer.advance(1);
                var cret = new LoopContext()
                {
                    parent = context
                };
                var t2 = GetContext(cret, 0, 0, NoBlocks) as ParenContext;
                if (t2 == null)
                {
                    throw new Exception("expected a condition for the for loop");
                }
                cret.condition = t2.interior;
                var t3 = GetContext(cret, 0, 0, 0);
                cret.body = t3;
                tokenizer.advance(-1);
                ret = cret;
            }
            else if (s0 == "if")
            {
                tokenizer.advance(1);
                var cret = new IfContext()
                {
                    parent = context
                };
                var t2 = GetContext(cret, 0, 0, 0) as ParenContext;
                if (t2 == null || t2.type != SysLib.BoolType.name)
                {
                    throw new Exception("expected a boolean condition for the if statement");
                }
                cret.condition = t2.interior;
                var t3 = GetContext(cret, 0, 0, 0);
                cret.body = t3;

                // while(tokenizer.peekNext().value == "elif") {

                // }
                if (tokenizer.peekNext().value == "else")
                {
                    tokenizer.advance(1);
                    var eret = new ElseContext()
                    {
                        parent = context, chainParent = cret
                    };
                    eret.chainParent = cret;
                    var t4 = GetContext(eret, 0, 0, 0);
                    eret.body = t4;
                    ret       = eret;
                }
                else
                {
                    ret = cret;
                }
                tokenizer.advance(-1);
            }
            else if (s0 == "break")
            {
                var cret = new BreakContext();
                cret.parent = context;
                cret.type   = SysLib.VoidType.name;
                ret         = cret;
            }

            //constants
            else if (int.TryParse(s0, out int i0))
            {
                ret = new ConstContext()
                {
                    value = i0, type = SysLib.IntType.name
                }
            }
            ;
            else if (double.TryParse(s0, out double d0))
            {
                ret = new ConstContext()
                {
                    value = d0, type = SysLib.DoubleType.name
                }
            }
            ;
            else if (float.TryParse(s0, out float f0))
            {
                ret = new ConstContext()
                {
                    value = f0, type = SysLib.FloatType.name
                }
            }
            ;
            else if (long.TryParse(s0, out long l0))
            {
                ret = new ConstContext()
                {
                    value = l0, type = SysLib.LongType.name
                }
            }
            ;
            else if (bool.TryParse(s0, out bool b0))
            {
                ret = new ConstContext()
                {
                    value = b0, type = SysLib.BoolType.name
                }
            }
            ;
            else if (s0[0] == '"' && s0[s0.Length - 1] == '"')
            {
                ret = new ConstContext()
                {
                    value = s0.Substring(1, s0.Length - 2), type = SysLib.StringType.name
                }
            }
            ;
            else if (s0.Length == 3 && s0[0] == '\'' && s0[2] == '\'')
            {
                ret = new ConstContext()
                {
                    value = s0[1], type = SysLib.CharType.name
                }
            }
            ;

            //prefix operators
            else if (prefixOperators.Contains(s0))
            {
                tokenizer.advance(1);
                var t2 = GetContext(context, opDepth, callDepth + 1, NoOps);
                ret = new SimpleOpContext()
                {
                    a = t2, op = s0
                };
                tokenizer.advance(-1);
            }

            //variables, functions, etc.
            else
            {
                if (ResolveVariable(context, s0, out var match))
                {
                    ret = new VarContext()
                    {
                        variable = match
                    }
                }
                ;
                else
                {
                    if (tokenizer.peekNext().value == ".")
                    {
                        //check imported types


                        //namespace prefixed types
                        string typeName = s0;

                        //reset tokenizer for while loop
                        tokenizer.advance(0);
                        tokenizer.peekNext();

                        int      steps = 0;
                        TypeData td    = null;
                        while (!compiler.ValidateType(typeName, out td))
                        {
                            if (tokenizer.peekNext().value != ".")
                            {
                                break;
                            }
                            typeName += '.' + tokenizer.peekNext().value;
                            steps    += 2;
                        }
                        if (td != null)
                        {
                            ret = new StaticTypeContext()
                            {
                                parent = context, type = typeName
                            };
                            tokenizer.advance(steps);
                        }
                        else
                        {
                            tokenizer.advance(0);
                        }
                    }
                    else
                    {
                        var vc = new VarDecContext()
                        {
                            name = s0
                        };
                        context.variables.Add(vc);
                        ret = vc;
                    }
                }
            }
            tokenizer.advance(1);

            ret.parent = context;
            //all operators
            var s1 = tokenizer.peekNext().value;

            if (flags == NoRecursion)
            {
                tokenizer.advance(0);
                return(ret);
            }

            //indexers
            if ((ret is VarContext || ret is MemberContext) && s1 == "[")
            {
                tokenizer.advance(1);
                var t2 = GetContext(context, 0, callDepth + 1, 0);

                //get arguments
                var arguments = t2 is SeperatedContext ? (t2 as SeperatedContext).children : new List <TypedContext>()
                {
                    t2
                };
                if (tokenizer.peekNext().value != "]")
                {
                    throw new Exception("expected one of these: ]");
                }

                if (tokenizer.peekNext().value == "=")
                {
                    tokenizer.advance(2);
                    var t3 = GetContext(context, 0, callDepth + 1, 0);
                    arguments.Add(t3);
                    var cret = new CallContext()
                    {
                        owner      = ret,
                        methodName = "_setIndex",
                        parent     = context,
                        arguments  = arguments
                    };
                    if (compiler.ValidateCall(cret, out MethodData md))
                    {
                        cret.type = md.returnType;
                        ret       = cret;
                    }
                    else
                    {
                        throw new Exception("no indexer for this boi");
                    }
                }
                else
                {
                    var cret = new CallContext()
                    {
                        owner      = ret,
                        methodName = "_getIndex",
                        parent     = context,
                        arguments  = arguments
                    };
                    if (compiler.ValidateCall(cret, out MethodData md))
                    {
                        cret.type = md.returnType;
                        ret       = cret;
                    }
                    else
                    {
                        throw new Exception("no indexer for this boi");
                    }
                    tokenizer.advance(1);
                    s1 = tokenizer.peekNext().value;
                }
            }

            //array declaration
            else if (ret is StaticTypeContext && s1 == "[")
            {
                tokenizer.advance(1);
                if (tokenizer.peekNext().value == "]")
                {
                    ret = new ListContext()
                    {
                        type   = $"{SysLib.ListType.name}<{ret.type}>",
                        parent = context
                    };
                }
                else
                {
                    var t2 = GetContext(context, 0, callDepth + 1, 0);
                    if (t2.type != SysLib.IntType.name)
                    {
                        throw new Exception("array initializer must have an integer length");
                    }
                    if (tokenizer.peekNext().value != "]")
                    {
                        throw new Exception("expected one of these: ]");
                    }

                    ret = new ArrayInitContext()
                    {
                        type   = $"{SysLib.ArrayType.name}<{ret.type}>",
                        length = t2,
                        parent = context
                    };
                }
                tokenizer.advance(1);
            }


            //calls and member accessing,
            if (s1 == ".")
            {
                while (s1 == ".")
                {
                    var type           = ret.type;
                    var memberOrMethod = tokenizer.peekNext().value;
                    if (tokenizer.peekNext().value == "(")
                    {
                        //method
                        tokenizer.advance(2);
                        var t2 = GetContext(context, 0, callDepth + 1, NoRecursion) as ParenContext;
                        if (t2 == null)
                        {
                            throw new Exception("expected arguments");
                        }

                        //resolve arguments
                        List <TypedContext> arguments = new List <TypedContext>();
                        if (t2.interior != null)
                        {
                            if (t2.interior is SeperatedContext)
                            {
                                arguments = ((SeperatedContext)t2.interior).children;
                            }
                            else
                            {
                                arguments.Add(t2);
                            }
                        }
                        var cret = new CallContext()
                        {
                            parent     = context,
                            owner      = ret,
                            methodName = memberOrMethod,
                            arguments  = arguments
                        };
                        if (compiler.ValidateCall(cret, out MethodData md))
                        {
                            cret.type = md.returnType;
                            ret       = cret;
                        }
                        else
                        {
                            throw new Exception("could not find method");
                        }
                        tokenizer.advance(0);
                        //if(tokenizer.peekNext().value != ")") throw new Exception("Expected one of these: )");
                    }
                    else
                    {
                        //member
                        var cret = new MemberContext()
                        {
                            parent     = context,
                            owner      = ret,
                            memberName = memberOrMethod,
                        };
                        if (compiler.ValidateMember(cret, out MemberData md))
                        {
                            tokenizer.advance(2);
                            cret.type = md.returnType;
                            ret       = cret;
                        }
                        else
                        {
                            throw new Exception("could not find member");
                        }
                    }
                    s1 = tokenizer.peekNext().value;
                }
                //tokenizer.advance(0);
            }

            //Parameter lists
            else if (s1 == "," && ret is VarDecContext)
            {
                var cret = new ParamContext();
                var prev = ret as VarDecContext;
                cret.children.Add(ret);
                cret.parent = context;
                while (s1 == ",")
                {
                    tokenizer.advance(1);
                    var t2 = GetContext(context, 0, callDepth + 1, NoRecursion) as VarDecContext;
                    if (t2 == null)
                    {
                        throw new Exception("excepted parameter");
                    }
                    if (t2.type == null)
                    {
                        t2.type = prev.type;
                    }
                    prev = t2;
                    cret.children.Add(t2);
                    s1 = tokenizer.peekNext().value;
                }
                ret = cret;
            }

            //list definition
            else if (s1 == "," && flags != 4)
            {
                var cret = new SeperatedContext();
                cret.children.Add(ret);
                cret.parent = context;
                while (s1 == ",")
                {
                    tokenizer.advance(1);
                    var t2 = GetContext(context, 0, callDepth + 1, NoRecursion);
                    cret.children.Add(t2);
                    s1 = tokenizer.peekNext().value;

                    //find common type
                    cret.type = t2.type;
                }
                ret = cret;
            }

            //assignments
            if (s1 == "=" && flags != NoOps)
            {
                TypedContext variable = ret as VarDecContext ?? (ret as VarContext)?.variable;
                if (variable == null)
                {
                    if (ret is MemberContext)
                    {
                        variable = ret;
                    }
                    else
                    {
                        throw new Exception("you can only assign variables");
                    }
                }

                tokenizer.advance(1);
                var t2 = GetContext(context, opDepth, callDepth + 1, flags);
                variable.type = t2.type;
                ret           = new AssignContext()
                {
                    parent = context, variable = ret, value = t2
                };
            }

            //from
            else if (s1 == ":")
            {
                var variable = ret as VarDecContext ?? (ret as VarContext).variable;
                if (variable == null)
                {
                    throw new Exception("you must get a variable from the following expression");
                }
                tokenizer.advance(1);
                var t2   = GetContext(context, opDepth, callDepth + 1, flags);
                var call = new CallContext()
                {
                    owner      = t2,
                    methodName = "_getIter",
                    parent     = context
                };
                if (compiler.ValidateCall(call, out MethodData md))
                {
                    if (variable.type == null)
                    {
                        variable.type = md.returnType.Between("<", ">");
                    }
                }
                else
                {
                    throw new Exception("Cannot iterate a type without a _getIter method");
                }
                ret = new FromContext()
                {
                    parent = context, reference = variable, body = t2
                };
            }

            //operators
            else if (operators.ContainsKey(s1) && flags != NoOps)
            {
                tokenizer.advance(1);
                var t2 = GetContext(context, opDepth + 1, callDepth + 1, flags);

                var cret = new OpContext()
                {
                    a = ret, op = s1, b = t2
                };
                if (t2 is OpContext)
                {
                    int p0 = operators[s1];
                    int p1 = operators[((OpContext)t2).op];
                    if (p0 >= p1)
                    {
                        OpContext deepA = (OpContext)t2;
                        for (; deepA.a is OpContext; deepA = (OpContext)(deepA.a))
                        {
                            ;
                        }
                        cret.b  = deepA.a;
                        deepA.a = cret;
                        cret    = (OpContext)t2;
                    }
                }
                if (opDepth == 0)
                {
                    //resolve type
                    ResolveType(cret);
                }
                ret = cret;
            }
            else
            {
                tokenizer.advance(0);
            }

            ret.parent = context;

            return(ret);
        }
示例#9
0
    public StatContext stat()
    {
        StatContext _localctx = new StatContext(Context, State);

        EnterRule(_localctx, 2, RULE_stat);
        int _la;

        try {
            int _alt;
            _localctx = new AssignContext(_localctx);
            EnterOuterAlt(_localctx, 1);
            {
                State = 18;
                ErrorHandler.Sync(this);
                _alt = Interpreter.AdaptivePredict(TokenStream, 1, Context);
                while (_alt != 2 && _alt != global::Antlr4.Runtime.Atn.ATN.INVALID_ALT_NUMBER)
                {
                    if (_alt == 1)
                    {
                        {
                            {
                                State = 15; stat1();
                            }
                        }
                    }
                    State = 20;
                    ErrorHandler.Sync(this);
                    _alt = Interpreter.AdaptivePredict(TokenStream, 1, Context);
                }
                State = 22;
                ErrorHandler.Sync(this);
                _la = TokenStream.LA(1);
                if (_la == ASSIGN)
                {
                    {
                        State = 21; ((AssignContext)_localctx).op = Match(ASSIGN);
                    }
                }

                State = 27;
                ErrorHandler.Sync(this);
                _la = TokenStream.LA(1);
                while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__1) | (1L << SIN) | (1L << COS) | (1L << TAN) | (1L << LN) | (1L << LOG) | (1L << SQRT) | (1L << LL) | (1L << ID) | (1L << NUM))) != 0))
                {
                    {
                        {
                            State = 24; stat1();
                        }
                    }
                    State = 29;
                    ErrorHandler.Sync(this);
                    _la = TokenStream.LA(1);
                }
                State = 30; Match(NL);
            }
        }
        catch (RecognitionException re) {
            _localctx.exception = re;
            ErrorHandler.ReportError(this, re);
            ErrorHandler.Recover(this, re);
        }
        finally {
            ExitRule();
        }
        return(_localctx);
    }
示例#10
0
	private ExprContext expr(int _p) {
		ParserRuleContext _parentctx = Context;
		int _parentState = State;
		ExprContext _localctx = new ExprContext(Context, _parentState);
		ExprContext _prevctx = _localctx;
		int _startState = 12;
		EnterRecursionRule(_localctx, 12, RULE_expr, _p);
		int _la;
		try {
			int _alt;
			EnterOuterAlt(_localctx, 1);
			{
			State = 120;
			ErrorHandler.Sync(this);
			switch ( Interpreter.AdaptivePredict(TokenStream,6,Context) ) {
			case 1:
				{
				_localctx = new Call_methodContext(_localctx);
				Context = _localctx;
				_prevctx = _localctx;

				State = 68; Match(ID);
				State = 69; Match(T__3);
				State = 70; args_call();
				State = 71; Match(T__4);
				}
				break;
			case 2:
				{
				_localctx = new IfContext(_localctx);
				Context = _localctx;
				_prevctx = _localctx;
				State = 73; Match(IF);
				State = 74; expr(0);
				State = 75; Match(THEN);
				State = 76; expr(0);
				State = 77; Match(ELSE);
				State = 78; expr(0);
				State = 79; Match(FI);
				}
				break;
			case 3:
				{
				_localctx = new WhileContext(_localctx);
				Context = _localctx;
				_prevctx = _localctx;
				State = 81; Match(WHILE);
				State = 82; expr(0);
				State = 83; Match(LOOP);
				State = 84; expr(0);
				State = 85; Match(POOL);
				}
				break;
			case 4:
				{
				_localctx = new BodyContext(_localctx);
				Context = _localctx;
				_prevctx = _localctx;
				State = 87; Match(T__1);
				State = 88; expr_list();
				State = 89; Match(T__2);
				}
				break;
			case 5:
				{
				_localctx = new New_typeContext(_localctx);
				Context = _localctx;
				_prevctx = _localctx;
				State = 91; Match(NEW);
				State = 92; Match(TYPE);
				}
				break;
			case 6:
				{
				_localctx = new IsvoidContext(_localctx);
				Context = _localctx;
				_prevctx = _localctx;
				State = 93; Match(ISVOID);
				State = 94; expr(12);
				}
				break;
			case 7:
				{
				_localctx = new Unary_expContext(_localctx);
				Context = _localctx;
				_prevctx = _localctx;
				State = 95;
				((Unary_expContext)_localctx).op = TokenStream.LT(1);
				_la = TokenStream.LA(1);
				if ( !(_la==T__16 || _la==NOT) ) {
					((Unary_expContext)_localctx).op = ErrorHandler.RecoverInline(this);
				}
				else {
					ErrorHandler.ReportMatch(this);
				    Consume();
				}
				State = 96; expr(8);
				}
				break;
			case 8:
				{
				_localctx = new ParentesisContext(_localctx);
				Context = _localctx;
				_prevctx = _localctx;
				State = 97; Match(T__3);
				State = 98; expr(0);
				State = 99; Match(T__4);
				}
				break;
			case 9:
				{
				_localctx = new IntContext(_localctx);
				Context = _localctx;
				_prevctx = _localctx;
				State = 101; Match(INTEGER);
				}
				break;
			case 10:
				{
				_localctx = new BoolContext(_localctx);
				Context = _localctx;
				_prevctx = _localctx;
				State = 102;
				((BoolContext)_localctx).cons = TokenStream.LT(1);
				_la = TokenStream.LA(1);
				if ( !(_la==TRUE || _la==FALSE) ) {
					((BoolContext)_localctx).cons = ErrorHandler.RecoverInline(this);
				}
				else {
					ErrorHandler.ReportMatch(this);
				    Consume();
				}
				}
				break;
			case 11:
				{
				_localctx = new StringContext(_localctx);
				Context = _localctx;
				_prevctx = _localctx;
				State = 103; Match(STR);
				}
				break;
			case 12:
				{
				_localctx = new AssignContext(_localctx);
				Context = _localctx;
				_prevctx = _localctx;
				State = 104; Match(ID);
				State = 105; Match(T__6);
				State = 106; expr(3);
				}
				break;
			case 13:
				{
				_localctx = new LetContext(_localctx);
				Context = _localctx;
				_prevctx = _localctx;
				State = 107; Match(LET);
				State = 108; attr();
				State = 113;
				ErrorHandler.Sync(this);
				_la = TokenStream.LA(1);
				while (_la==T__17) {
					{
					{
					State = 109; Match(T__17);
					State = 110; attr();
					}
					}
					State = 115;
					ErrorHandler.Sync(this);
					_la = TokenStream.LA(1);
				}
				State = 116; Match(IN);
				State = 117; expr(2);
				}
				break;
			case 14:
				{
				_localctx = new IdContext(_localctx);
				Context = _localctx;
				_prevctx = _localctx;
				State = 119; Match(ID);
				}
				break;
			}
			Context.Stop = TokenStream.LT(-1);
			State = 144;
			ErrorHandler.Sync(this);
			_alt = Interpreter.AdaptivePredict(TokenStream,9,Context);
			while ( _alt!=2 && _alt!=global::Antlr4.Runtime.Atn.ATN.INVALID_ALT_NUMBER ) {
				if ( _alt==1 ) {
					if ( ParseListeners!=null )
						TriggerExitRuleEvent();
					_prevctx = _localctx;
					{
					State = 142;
					ErrorHandler.Sync(this);
					switch ( Interpreter.AdaptivePredict(TokenStream,8,Context) ) {
					case 1:
						{
						_localctx = new MultdivContext(new ExprContext(_parentctx, _parentState));
						PushNewRecursionContext(_localctx, _startState, RULE_expr);
						State = 122;
						if (!(Precpred(Context, 11))) throw new FailedPredicateException(this, "Precpred(Context, 11)");
						State = 123;
						((MultdivContext)_localctx).op = TokenStream.LT(1);
						_la = TokenStream.LA(1);
						if ( !(_la==T__9 || _la==T__10) ) {
							((MultdivContext)_localctx).op = ErrorHandler.RecoverInline(this);
						}
						else {
							ErrorHandler.ReportMatch(this);
						    Consume();
						}
						State = 124; expr(12);
						}
						break;
					case 2:
						{
						_localctx = new SumarestaContext(new ExprContext(_parentctx, _parentState));
						PushNewRecursionContext(_localctx, _startState, RULE_expr);
						State = 125;
						if (!(Precpred(Context, 10))) throw new FailedPredicateException(this, "Precpred(Context, 10)");
						State = 126;
						((SumarestaContext)_localctx).op = TokenStream.LT(1);
						_la = TokenStream.LA(1);
						if ( !(_la==T__11 || _la==T__12) ) {
							((SumarestaContext)_localctx).op = ErrorHandler.RecoverInline(this);
						}
						else {
							ErrorHandler.ReportMatch(this);
						    Consume();
						}
						State = 127; expr(11);
						}
						break;
					case 3:
						{
						_localctx = new CompContext(new ExprContext(_parentctx, _parentState));
						PushNewRecursionContext(_localctx, _startState, RULE_expr);
						State = 128;
						if (!(Precpred(Context, 9))) throw new FailedPredicateException(this, "Precpred(Context, 9)");
						State = 129;
						((CompContext)_localctx).op = TokenStream.LT(1);
						_la = TokenStream.LA(1);
						if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__13) | (1L << T__14) | (1L << T__15))) != 0)) ) {
							((CompContext)_localctx).op = ErrorHandler.RecoverInline(this);
						}
						else {
							ErrorHandler.ReportMatch(this);
						    Consume();
						}
						State = 130; expr(10);
						}
						break;
					case 4:
						{
						_localctx = new DispatchContext(new ExprContext(_parentctx, _parentState));
						PushNewRecursionContext(_localctx, _startState, RULE_expr);
						State = 131;
						if (!(Precpred(Context, 18))) throw new FailedPredicateException(this, "Precpred(Context, 18)");
						State = 134;
						ErrorHandler.Sync(this);
						_la = TokenStream.LA(1);
						if (_la==T__7) {
							{
							State = 132; Match(T__7);
							State = 133; Match(TYPE);
							}
						}

						State = 136; Match(T__8);
						State = 137; Match(ID);
						State = 138; Match(T__3);
						State = 139; args_call();
						State = 140; Match(T__4);
						}
						break;
					}
					} 
				}
				State = 146;
				ErrorHandler.Sync(this);
				_alt = Interpreter.AdaptivePredict(TokenStream,9,Context);
			}
			}
		}
		catch (RecognitionException re) {
			_localctx.exception = re;
			ErrorHandler.ReportError(this, re);
			ErrorHandler.Recover(this, re);
		}
		finally {
			UnrollRecursionContexts(_parentctx);
		}
		return _localctx;
	}