Exemplo n.º 1
0
        public void CheckEvt(IScope currScope, LSLAst id)
        {
            EventSymbol evt = (EventSymbol)currScope.Resolve(id.Text + "()");

            Debug.Assert(evt != null);

            //try to find this event in our table
            if (!_supportedEvents.HasEventByName(id.Text))
            {
                _listener.Error("line " + id.Token.Line + ":" +
                                id.Token.CharPositionInLine + " No event evailable with name '" + id.Text + "'");

                return;
            }

            //also try to resolve the arguments
            List <VarType> passedEvtArgs = evt.ExtractArgumentTypes();

            if (!_supportedEvents.HasEventBySig(id.Text, VarType.Void, passedEvtArgs))
            {
                string paramList = this.FormatParamTypeList(_supportedEvents.GetArguments(id.Text));
                _listener.Error("line " + id.Token.Line + ":" +
                                id.Token.CharPositionInLine + " Incorrect parameters for event " + id.Text +
                                paramList);
            }
        }
Exemplo n.º 2
0
        public bool IsAssignable(LSLAst lhs)
        {
            //lhs will either be an id direct or an EXPR with an ID child
            if (lhs.Type == LSLParser.ID)
            {
                return(true);
            }

            if (lhs.Type == LSLParser.EXPR &&
                lhs.ChildCount == 1 &&
                lhs.Children[0].Type == LSLParser.ID)
            {
                return(true);
            }

            if (lhs.Type == LSLParser.SUBSCRIPT)
            {
                return(true);
            }


            _listener.Error(
                "line " + lhs.Line + ":" + lhs.CharPositionInLine + " '" +
                lhs.Text + "' is not assignable"
                );

            return(false);
        }
Exemplo n.º 3
0
        public bool CheckRotationLiteral(LSLAst e1, LSLAst e2, LSLAst e3, LSLAst e4)
        {
            if (!AllTypesAreResolved(new LSLAst[] { e1, e2, e3, e4 }))
            {
                _listener.Error(
                    "line " + e1.Token.Line + ":" + e1.Token.CharPositionInLine +
                    " Rotation contains expression(s) of unknown type"
                    );

                return(false);
            }

            //try type promotion first
            e1.promoteToType = promoteFromTo[e1.evalType.TypeIndex, FLOAT.TypeIndex];
            e2.promoteToType = promoteFromTo[e2.evalType.TypeIndex, FLOAT.TypeIndex];
            e3.promoteToType = promoteFromTo[e3.evalType.TypeIndex, FLOAT.TypeIndex];
            e4.promoteToType = promoteFromTo[e4.evalType.TypeIndex, FLOAT.TypeIndex];

            if (CanAssignTo(e1.evalType, FLOAT, e1.promoteToType) &&
                CanAssignTo(e2.evalType, FLOAT, e2.promoteToType) &&
                CanAssignTo(e3.evalType, FLOAT, e3.promoteToType) &&
                CanAssignTo(e4.evalType, FLOAT, e4.promoteToType))
            {
                return(true);
            }

            _listener.Error(
                "line " + e1.Token.Line + ":" + e1.Token.CharPositionInLine +
                " Rotation components must be float or implicitly convertable to float "
                );

            return(false);
        }
Exemplo n.º 4
0
        public ISymbolType Bop(LSLAst bop, LSLAst lhs, LSLAst rhs)
        {
            ISymbolType[,] symTable;
            string op = bop.Token.Text;

            symTable = FindOperationTable(lhs, op);
            if (symTable == null)
            {
                return(VOID);
            }

            if (HasUnknownTypes(lhs, rhs))
            {
                return(VOID);
            }

            ISymbolType symType = symTable[lhs.evalType.TypeIndex, rhs.evalType.TypeIndex];

            if (symType == VOID)
            {
                _listener.Error("line " + lhs.Token.Line + ":" +
                                lhs.Token.CharPositionInLine + " '" + op + "' is not a valid operation between " +
                                lhs.evalType.Name + " and " + rhs.evalType.Name);
                return(VOID);
            }

            return(symType);
        }
Exemplo n.º 5
0
        public ISymbolType RelOp(LSLAst lhs, LSLAst rhs)
        {
            if (HasUnknownTypes(lhs, rhs))
            {
                return(VOID);
            }

            //relational operations must be between the same types
            int tlhs = lhs.evalType.TypeIndex; // promote right to left type?
            int trhs = rhs.evalType.TypeIndex;

            rhs.promoteToType = promoteFromTo[trhs, tlhs];
            lhs.promoteToType = promoteFromTo[tlhs, trhs];

            if (!HaveSameTypes(lhs, rhs))
            {
                _listener.Error("line " + lhs.Token.Line + ":" +
                                lhs.Token.CharPositionInLine + " Type mismatch, relational operators require arguments of the same type");
            }

            //strings can not be LT/GT compared in LSL
            if (lhs.evalType == STRING || rhs.evalType == STRING)
            {
                _listener.Error("line " + lhs.Token.Line + ":" +
                                lhs.Token.CharPositionInLine + " Type mismatch, strings can not be compared with < or >");
            }

            return(INT);
        }
Exemplo n.º 6
0
        public ISymbolType PreDec(LSLAst a)
        {
            if (a.evalType == null)
            {
                _listener.Error(
                    "line " + a.Token.Line + ":" + a.Token.CharPositionInLine +
                    " (--) Unknown type in expression " + a.Text
                    );

                return(VOID);
            }

            if (!IsAssignable(a))
            {
                return(VOID);
            }

            if (!TypeIsIn(a.evalType, new ISymbolType[] { INT, FLOAT }))
            {
                _listener.Error(
                    "line " + a.Token.Line + ":" + a.Token.CharPositionInLine +
                    " -- not valid for type " + a.evalType.Name
                    );

                return(VOID);
            }

            return(a.evalType);
        }
Exemplo n.º 7
0
 public void CheckLogicalExpr(LSLAst expr)
 {
     if (expr.evalType != INT)
     {
         _listener.Error("line " + expr.Token.Line + ":" +
                         expr.Token.CharPositionInLine + " Logical expressions require integer type");
     }
 }
Exemplo n.º 8
0
        public string text(LSLAst t)
        {
            string ts = "";

            //if (t.evalType != null) ts = ":<" + t.evalType + ">";
            return(_tokens.ToString(t.TokenStartIndex,
                                    t.TokenStopIndex) + ts);
        }
Exemplo n.º 9
0
        public ISymbolType SubScript(LSLAst id, LSLAst subScript)
        {
            //the lhs must be an ID and it must be of vector type or rotation type
            //and it must be the letters x, y, z, or s for rotation
            if (id.Type != LSLParser.ID)
            {
                _listener.Error(
                    "line " + id.Token.Line + ":" + id.Token.CharPositionInLine +
                    " Use of subscript ." + subScript.Text + " requires a vector or rotation variable "
                    );

                return(VOID);
            }

            if (!TypeIsIn(id.evalType, new ISymbolType[] { VECTOR, ROTATION }))
            {
                _listener.Error(
                    "line " + id.Token.Line + ":" + id.Token.CharPositionInLine +
                    " Use of subscript ." + subScript.Text + " requires a vector or rotation variable"
                    );

                return(VOID);
            }

            if (id.evalType == VECTOR)
            {
                if (subScript.Text != "x" &&
                    subScript.Text != "y" &&
                    subScript.Text != "z")
                {
                    _listener.Error(
                        "line " + id.Token.Line + ":" + id.Token.CharPositionInLine +
                        " Invalid subscript ." + subScript.Text
                        );

                    return(VOID);
                }
            }

            if (id.evalType == ROTATION)
            {
                if (subScript.Text != "x" &&
                    subScript.Text != "y" &&
                    subScript.Text != "z" &&
                    subScript.Text != "s")
                {
                    _listener.Error(
                        "line " + id.Token.Line + ":" + id.Token.CharPositionInLine +
                        " Invalid subscript ." + subScript.Text
                        );

                    return(VOID);
                }
            }

            return(FLOAT);
        }
Exemplo n.º 10
0
        public ISymbolType LogBop(LSLAst lhs, LSLAst rhs)
        {
            if (lhs.evalType != INT || rhs.evalType != INT)
            {
                _listener.Error("line " + lhs.Token.Line + ":" +
                                lhs.Token.CharPositionInLine + " Type mismatch, logical operators || and && require integer arguments");
            }

            return(INT);
        }
Exemplo n.º 11
0
        public bool HasUnknownType(LSLAst lhs)
        {
            if (lhs.evalType == null)
            {
                _listener.Error("line " + lhs.Token.Line + ":" +
                                lhs.Token.CharPositionInLine + " Invalid operation. At least one type is unknown");
                return(true);
            }

            return(false);
        }
Exemplo n.º 12
0
        public ISymbolType CheckListLiteral(LSLAst start, IList <LSLAst> args)
        {
            foreach (LSLAst node in args)
            {
                if (node.evalType == LIST)
                {
                    _listener.Error("line " + start.Token.Line + ":" +
                                    start.Token.CharPositionInLine + " A list can not contain another list");
                }
            }

            return(LIST);
        }
Exemplo n.º 13
0
        public void CheckStateChange(LSLAst chgNode, LSLAst destID)
        {
            string      stateName = destID != null ? destID.Text + "(*)" : "default(*)";
            StateSymbol state     = _globals.Resolve(stateName) as StateSymbol;

            if (state == null)
            {
                _listener.Error(
                    "line " + chgNode.Token.Line + ":" + chgNode.Token.CharPositionInLine +
                    " Undefined state " + stateName
                    );
            }
        }
Exemplo n.º 14
0
        public void CheckJump(LSLAst jumpStmt, LSLAst id)
        {
            LabelSymbol label = jumpStmt.scope.Resolve("@" + id.Text) as LabelSymbol;

            if (label == null)
            {
                _listener.Error("line " + id.Token.Line + ":" +
                                id.Token.CharPositionInLine + " Undefined label " + id.Text);
            }
            else
            {
                id.symbol = label;
            }
        }
Exemplo n.º 15
0
        public ISymbolType BitOp(LSLAst lhs, LSLAst rhs)
        {
            if (HasUnknownTypes(lhs, rhs))
            {
                return(INT);
            }

            if (lhs.evalType != INT || rhs.evalType != INT)
            {
                _listener.Error("line " + lhs.Token.Line + ":" +
                                lhs.Token.CharPositionInLine + " Type mismatch, bitwise operators require arguments of integral type");
            }

            return(INT);
        }
Exemplo n.º 16
0
        private ISymbolType StdAssign(LSLAst lhs, LSLAst rhs, int tlhs, int trhs)
        {
            rhs.promoteToType = promoteFromTo[trhs, tlhs];
            if (!CanAssignTo(rhs.evalType, lhs.evalType, rhs.promoteToType))
            {
                _listener.Error(
                    "line " + lhs.Line + ":" + lhs.CharPositionInLine + " " + text(lhs) + " and " +
                    text(rhs) + " have incompatible types in " +
                    text((LSLAst)lhs.Parent)
                    );

                return(VOID);
            }

            return(lhs.evalType);
        }
Exemplo n.º 17
0
        public void DeclInit(LSLAst varName, LSLAst initExpr)
        {
            int tlhs = varName.symbol.Type.TypeIndex; // promote right to left type?

            varName.evalType = varName.symbol.Type;
            int trhs = initExpr.evalType.TypeIndex;

            initExpr.promoteToType = promoteFromTo[trhs, tlhs];
            if (!CanAssignTo(initExpr.evalType, varName.evalType, initExpr.promoteToType))
            {
                _listener.Error(
                    "line " + varName.Line + ":" + varName.CharPositionInLine + " " + text(varName) + " and " +
                    text(initExpr) + " have incompatible types in " +
                    text((LSLAst)initExpr.Parent)
                    );
            }
        }
Exemplo n.º 18
0
        private ISymbolType[,] FindOperationTable(LSLAst lhs, string op)
        {
            ISymbolType[,] symTable;
            switch (op)
            {
            case "+":
            case "+=":
                symTable = additionResultType;
                break;

            case "-":
            case "-=":
                symTable = subtractionResultType;
                break;

            case "*":
            case "*=":
                symTable = multiplicationResultType;
                break;

            case "/":
            case "/=":
                symTable = divisionResultType;
                break;

            case "%":
            case "%=":
                symTable = modResultType;
                break;

            case "<<":
            case ">>":
            case ">>=":
            case "<<=":
                symTable = shiftResultType;
                break;

            default:
                _listener.Error("line " + lhs.Token.Line + ":" +
                                lhs.Token.CharPositionInLine + " Internal error. No such operation '" + op + "'");
                symTable = null;
                break;
            }

            return(symTable);
        }
Exemplo n.º 19
0
        public ISymbolType Assign(string type, LSLAst lhs, LSLAst rhs)
        {
            if (HasUnknownTypes(lhs, rhs))
            {
                return(VOID);
            }

            //the left hand side needs to be assignable
            if (!IsAssignable(lhs))
            {
                return(VOID);
            }

            int tlhs = lhs.evalType.TypeIndex; // promote right to left type?
            int trhs = rhs.evalType.TypeIndex;

            if (type == "=")
            {
                return(StdAssign(lhs, rhs, tlhs, trhs));
            }

            ISymbolType[,] opTable = FindOperationTable(lhs, type);
            if (opTable == null)
            {
                return(VOID);
            }

            ISymbolType symType = opTable[lhs.evalType.TypeIndex, rhs.evalType.TypeIndex];

            if (symType == VOID)
            {
                if (lhs.Type == LSLParser.EXPR)
                {
                    lhs = (LSLAst)lhs.Children[0];
                }

                _listener.Error("line " + lhs.Token.Line + ":" +
                                lhs.Token.CharPositionInLine + " '" + type + "' is not a valid operation between " +
                                lhs.evalType.Name + " and " + rhs.evalType.Name);
                return(VOID);
            }

            return(symType);
        }
Exemplo n.º 20
0
        public bool HaveSameTypes(LSLAst lhs, LSLAst rhs)
        {
            if (lhs.evalType == null || rhs.evalType == null)
            {
                _listener.Error("line " + lhs.Token.Line + ":" +
                                lhs.Token.CharPositionInLine + "Can not compare types, at least one type is unknown " + lhs.Text + ", " + rhs.Text);

                return(false);
            }

            if (lhs.evalType == rhs.evalType ||
                (lhs.promoteToType == rhs.promoteToType && lhs.promoteToType != null && rhs.promoteToType != null) ||
                lhs.evalType == rhs.promoteToType ||
                rhs.evalType == lhs.promoteToType)
            {
                return(true);
            }

            return(false);
        }
Exemplo n.º 21
0
        private bool IsChildNodeOf(LSLAst sym, LSLAst node)
        {
            if (sym == null || sym.Children == null)
            {
                return(false);
            }

            foreach (Antlr.Runtime.Tree.ITree childNode in sym.Children)
            {
                if (childNode == node)
                {
                    return(true);
                }

                if (IsChildNodeOf((LSLAst)childNode, node))
                {
                    return(true);
                }
            }

            return(false);
        }
Exemplo n.º 22
0
        public ISymbolType EqOp(LSLAst lhs, LSLAst rhs)
        {
            if (HasUnknownTypes(lhs, rhs))
            {
                return(VOID);
            }

            //equality operations must be between the same types
            int tlhs = lhs.evalType.TypeIndex; // promote right to left type?
            int trhs = rhs.evalType.TypeIndex;

            rhs.promoteToType = promoteFromTo[trhs, tlhs];
            lhs.promoteToType = promoteFromTo[tlhs, trhs];

            if (!HaveSameTypes(lhs, rhs))
            {
                _listener.Error("line " + lhs.Token.Line + ":" +
                                lhs.Token.CharPositionInLine + " Type mismatch, equality operators == and != require arguments of the same type");
            }

            return(INT);
        }
Exemplo n.º 23
0
        public ISymbolType Uminus(LSLAst a)
        {
            if (a.evalType == null)
            {
                _listener.Error(
                    "line " + a.Token.Line + ":" + a.Token.CharPositionInLine +
                    " Unknown type in expression -" + a.Text
                    );

                return(VOID);
            }

            //only integer, float, vector and rotations can be negated
            if (!TypeIsIn(a.evalType, new ISymbolType[] { INT, FLOAT, VECTOR, ROTATION }))
            {
                _listener.Error(
                    "line " + a.Token.Line + ":" + a.Token.CharPositionInLine +
                    " Unary minus (-N) not valid for type " + a.evalType.Name
                    );
            }

            return(a.evalType);
        }
Exemplo n.º 24
0
        public ISymbolType TypeCast(LSLAst expr, LSLAst type)
        {
            if (HasUnknownType(expr))
            {
                return(VOID);
            }

            int texpr = expr.evalType.TypeIndex;

            //type must be a builtin type
            ISymbolType toType = (ISymbolType)_globals.Resolve(type.Text);
            int         ttype  = toType.TypeIndex;

            if (!CanCast(texpr, ttype))
            {
                _listener.Error(
                    "line " + type.Line + ":" + type.CharPositionInLine + " Can not cast from "
                    + expr.evalType.Name + " to " + type.Text
                    );
            }

            return(toType);
        }
Exemplo n.º 25
0
        public ISymbolType UBitNot(LSLAst a)
        {
            if (a.evalType == null)
            {
                _listener.Error(
                    "line " + a.Token.Line + ":" + a.Token.CharPositionInLine +
                    " Unknown type in expression !" + a.Text
                    );

                return(VOID);
            }

            if (a.evalType != INT)
            {
                _listener.Error(
                    "line " + a.Token.Line + ":" + a.Token.CharPositionInLine +
                    " Bitwise not (~) not valid for type " + a.evalType.Name
                    );

                return(VOID);
            }

            return(INT);
        }
Exemplo n.º 26
0
        public void CheckReturn(LSLAst retStmt, LSLAst retExpr)
        {
            //return must match function type
            if (retExpr == null)
            {
                if (retStmt.symbol.Type == VOID)
                {
                    //void return type with void result
                    return;
                }
                else
                {
                    _listener.Error(
                        "line " + retStmt.Token.Line + ":" + retStmt.Token.CharPositionInLine +
                        " Function must return a value"
                        );

                    return;
                }
            }

            if (HasUnknownType(retExpr))
            {
                return;
            }

            //check promotions and return
            retExpr.promoteToType = promoteFromTo[retExpr.evalType.TypeIndex, retStmt.symbol.Type.TypeIndex];
            if (!CanAssignTo(retExpr.evalType, retStmt.symbol.Type, retExpr.promoteToType))
            {
                _listener.Error(
                    "line " + retStmt.Token.Line + ":" + retStmt.Token.CharPositionInLine +
                    " Invalid return type " + retExpr.evalType.Name + ", expecting " + retStmt.symbol.Type.Name
                    );
            }
        }
Exemplo n.º 27
0
        public Symbol EnsureResolve(LSLAst node, IScope scope, string symName)
        {
            Symbol sym = scope.Resolve(symName);

            if (sym == null)
            {
                _listener.Error("line " + node.Token.Line + ":" +
                    node.Token.CharPositionInLine + " Undefined symbol '" + symName + "'");

                return null;
            }

            //globals are always ok to ref, so skip the rest of the checks if this is a global
            if (sym.Scope == Globals)
            {
                return sym;
            }

            //consts are always ok to ref
            if (sym is ConstantSymbol)
            {
                return sym;
            }

            if (sym.Def == null)
            {
                _listener.Error(String.Format("INTERNAL COMPILER ERROR: Symbol definition not set: {0}", sym));
                return sym;
            }

            //if the symbol is local, it cant be used before it's defined
            if (sym.Def.TokenStartIndex > node.TokenStartIndex)
            {
                //if we are in a local scope, check if there is a version of this symbol in the function (parameter) scope
                //then check if there is a version of this symbol on the global scope
                Symbol methodSymbol = FindSymbolInMethodScope(sym, scope);
                Symbol globalSymbol = Globals.Resolve(symName);

                if (methodSymbol == null && globalSymbol == null)
                {
                    //there is no global by this name, it's only defined locally and it's defined after
                    //its use
                    _listener.Error("line " + node.Token.Line + ":" +
                        node.Token.CharPositionInLine + " Symbol '" + symName + "' can not be used before it is defined");
                }

                if (methodSymbol != null) sym = methodSymbol;
                else sym = globalSymbol;
            }
            //also if this symbol is local, it can not be defined in the root of the expression from which it is being used
            else if (IsChildNodeOf((LSLAst)sym.Def.GetAncestor(LSLParser.VAR_DECL), node))
            {
                //the symbol we found is a parent of the declaration and is therefore not valid for use
                //check parent scopes for a valid symbol
                Symbol methodSymbol = FindSymbolInMethodScope(sym, scope);
                Symbol globalSymbol = Globals.Resolve(symName);

                if (methodSymbol == null && globalSymbol == null)
                {
                    //there is no global by this name, it's only defined locally and it's defined after
                    //its use
                    _listener.Error("line " + node.Token.Line + ":" +
                        node.Token.CharPositionInLine + " Symbol '" + symName + "' can not be used before it is defined");
                }

                if (methodSymbol != null) sym = methodSymbol;
                else sym = globalSymbol;
            }

            return sym;
        }
Exemplo n.º 28
0
 public void CheckJump(LSLAst jumpStmt, LSLAst id)
 {
     LabelSymbol label = jumpStmt.scope.Resolve("@" + id.Text) as LabelSymbol;
     if (label == null)
     {
         _listener.Error("line " + id.Token.Line + ":" +
             id.Token.CharPositionInLine + " Undefined label " + id.Text);
     }
     else
     {
         id.symbol = label;
     }
 }
Exemplo n.º 29
0
        public ISymbolType CheckListLiteral(LSLAst start, IList<LSLAst> args)
        {
            foreach (LSLAst node in args)
            {
                if (node.evalType == LIST)
                {
                    _listener.Error("line " + start.Token.Line + ":" +
                        start.Token.CharPositionInLine + " A list can not contain another list");
                }
            }

            return LIST;
        }
Exemplo n.º 30
0
 public void CheckStateChange(LSLAst chgNode, LSLAst destID)
 {
     string stateName = destID != null ? destID.Text + "(*)" : "default(*)";
     StateSymbol state = _globals.Resolve(stateName) as StateSymbol;
     if (state == null)
     {
         _listener.Error(
             "line " + chgNode.Token.Line + ":" + chgNode.Token.CharPositionInLine +
             " Undefined state " + stateName
         );
     }
 }
Exemplo n.º 31
0
 public void CheckLogicalExpr(LSLAst expr)
 {
     if (expr.evalType != INT)
     {
         _listener.Error("line " + expr.Token.Line + ":" +
             expr.Token.CharPositionInLine + " Logical expressions require integer type");
     }
 }
Exemplo n.º 32
0
 public ISymbolType Unot(LSLAst a)
 {
     return(INT);
 }
Exemplo n.º 33
0
        public void CheckReturn(LSLAst retStmt, LSLAst retExpr)
        {
            //return must match function type
            if (retExpr == null)
            {
                if (retStmt.symbol.Type == VOID)
                {
                    //void return type with void result
                    return;
                }
                else
                {
                    _listener.Error(
                        "line " + retStmt.Token.Line + ":" + retStmt.Token.CharPositionInLine +
                        " Function must return a value"
                    );

                    return;
                }
                
            }

            if (HasUnknownType(retExpr))
            {
                return;
            }

            //check promotions and return
            retExpr.promoteToType = promoteFromTo[retExpr.evalType.TypeIndex, retStmt.symbol.Type.TypeIndex];
            if (! CanAssignTo(retExpr.evalType, retStmt.symbol.Type, retExpr.promoteToType))
            {
                _listener.Error(
                    "line " + retStmt.Token.Line + ":" + retStmt.Token.CharPositionInLine +
                    " Invalid return type " + retExpr.evalType.Name + ", expecting " + retStmt.symbol.Type.Name
                );
            }

        }
Exemplo n.º 34
0
 public ISymbolType PostDec(LSLAst a)
 {
     return(PreDec(a));
 }
Exemplo n.º 35
0
        public ISymbolType BitOp(LSLAst lhs, LSLAst rhs)
        {
            if (HasUnknownTypes(lhs, rhs))
            {
                return INT;
            }

            if (lhs.evalType != INT || rhs.evalType != INT)
            {
                _listener.Error("line " + lhs.Token.Line + ":" +
                    lhs.Token.CharPositionInLine + " Type mismatch, bitwise operators require arguments of integral type");
            }

            return INT;
        }
Exemplo n.º 36
0
        public ISymbolType Bop(LSLAst bop, LSLAst lhs, LSLAst rhs)
        {
            ISymbolType[,] symTable;
            string op = bop.Token.Text;

            symTable = FindOperationTable(lhs, op);
            if (symTable == null)
            {
                return VOID;
            }

            if (HasUnknownTypes(lhs, rhs))
            {
                return VOID;
            }

            ISymbolType symType = symTable[lhs.evalType.TypeIndex, rhs.evalType.TypeIndex];
            if (symType == VOID)
            {
                _listener.Error("line " + lhs.Token.Line + ":" +
                    lhs.Token.CharPositionInLine + " '" + op + "' is not a valid operation between " +
                    lhs.evalType.Name + " and " + rhs.evalType.Name);
                return VOID;
            }

            return symType;
        }
Exemplo n.º 37
0
        private bool IsChildNodeOf(LSLAst sym, LSLAst node)
        {
            if (sym == null || sym.Children == null)
            {
                return false;
            }

            foreach (Antlr.Runtime.Tree.ITree childNode in sym.Children)
            {
                if (childNode == node)
                {
                    return true;
                }

                if (IsChildNodeOf((LSLAst)childNode, node))
                {
                    return true;
                }
            }

            return false;
        }
Exemplo n.º 38
0
 public ISymbolType Unot(LSLAst a)
 {
     return INT;
 }
Exemplo n.º 39
0
 public ISymbolType PostDec(LSLAst a)
 {
     return PreDec(a);
 }
Exemplo n.º 40
0
        public ISymbolType PreDec(LSLAst a)
        {
            if (a.evalType == null)
            {
                _listener.Error(
                    "line " + a.Token.Line + ":" + a.Token.CharPositionInLine +
                    " (--) Unknown type in expression " + a.Text
                );

                return VOID;
            }

            if (!IsAssignable(a))
            {
                return VOID;
            }

            if (!TypeIsIn(a.evalType, new ISymbolType[] { INT, FLOAT }))
            {
                _listener.Error(
                    "line " + a.Token.Line + ":" + a.Token.CharPositionInLine +
                    " -- not valid for type " + a.evalType.Name
                );

                return VOID;
            }

            return a.evalType;
        }
Exemplo n.º 41
0
        public bool HasUnknownType(LSLAst lhs)
        {
            if (lhs.evalType == null)
            {
                _listener.Error("line " + lhs.Token.Line + ":" +
                    lhs.Token.CharPositionInLine + " Invalid operation. At least one type is unknown");
                return true;
            }

            return false;
        }
Exemplo n.º 42
0
        public ISymbolType LogBop(LSLAst lhs, LSLAst rhs)
        {
            if (lhs.evalType != INT || rhs.evalType != INT)
            {
                _listener.Error("line " + lhs.Token.Line + ":" +
                    lhs.Token.CharPositionInLine + " Type mismatch, logical operators || and && require integer arguments");
            }

            return INT;
        }
Exemplo n.º 43
0
        private ISymbolType[,] FindOperationTable(LSLAst lhs, string op)
        {
            ISymbolType[,] symTable;
            switch (op)
            {
                case "+":
                case "+=":
                    symTable = additionResultType;
                    break;

                case "-":
                case "-=":
                    symTable = subtractionResultType;
                    break;

                case "*":
                case "*=":
                    symTable = multiplicationResultType;
                    break;

                case "/":
                case "/=":
                    symTable = divisionResultType;
                    break;

                case "%":
                case "%=":
                    symTable = modResultType;
                    break;

                case "<<":
                case ">>":
                case ">>=":
                case "<<=":
                    symTable = shiftResultType;
                    break;

                default:
                    _listener.Error("line " + lhs.Token.Line + ":" +
                        lhs.Token.CharPositionInLine + " Internal error. No such operation '" + op + "'");
                    symTable = null;
                    break;
            }

            return symTable;
        }
Exemplo n.º 44
0
        public ISymbolType RelOp(LSLAst lhs, LSLAst rhs)
        {
            if (HasUnknownTypes(lhs, rhs))
            {
                return VOID;
            }

            //relational operations must be between the same types
            int tlhs = lhs.evalType.TypeIndex; // promote right to left type?
            int trhs = rhs.evalType.TypeIndex;

            rhs.promoteToType = promoteFromTo[trhs, tlhs];
            lhs.promoteToType = promoteFromTo[tlhs, trhs];

            if (!HaveSameTypes(lhs, rhs))
            {
                _listener.Error("line " + lhs.Token.Line + ":" +
                    lhs.Token.CharPositionInLine + " Type mismatch, relational operators require arguments of the same type");
            }

            //strings can not be LT/GT compared in LSL
            if (lhs.evalType == STRING || rhs.evalType == STRING)
            {
                _listener.Error("line " + lhs.Token.Line + ":" +
                    lhs.Token.CharPositionInLine + " Type mismatch, strings can not be compared with < or >");
            }

            return INT;
        }
Exemplo n.º 45
0
        public bool HaveSameTypes(LSLAst lhs, LSLAst rhs)
        {
            if (lhs.evalType == null || rhs.evalType == null)
            {
                _listener.Error("line " + lhs.Token.Line + ":" +
                    lhs.Token.CharPositionInLine + "Can not compare types, at least one type is unknown " + lhs.Text + ", " + rhs.Text);

                return false;
            }

            if (lhs.evalType == rhs.evalType ||
                (lhs.promoteToType == rhs.promoteToType && lhs.promoteToType != null && rhs.promoteToType != null) ||
                lhs.evalType == rhs.promoteToType ||
                rhs.evalType == lhs.promoteToType)
            {
                return true;
            }

            return false;
        }
Exemplo n.º 46
0
        public ISymbolType TypeCast(LSLAst expr, LSLAst type)
        {
            if (HasUnknownType(expr))
            {
                return VOID;
            }

            int texpr = expr.evalType.TypeIndex;
            
            //type must be a builtin type
            ISymbolType toType = (ISymbolType)_globals.Resolve(type.Text);
            int ttype = toType.TypeIndex;

            if (!CanCast(texpr, ttype))
            {
                _listener.Error(
                    "line " + type.Line + ":" + type.CharPositionInLine + " Can not cast from " 
                    + expr.evalType.Name + " to " + type.Text
                );
            }

            return toType;
        }
Exemplo n.º 47
0
        public ISymbolType EqOp(LSLAst lhs, LSLAst rhs)
        {
            if (HasUnknownTypes(lhs, rhs))
            {
                return VOID;
            }

            //equality operations must be between the same types
            int tlhs = lhs.evalType.TypeIndex; // promote right to left type?
            int trhs = rhs.evalType.TypeIndex;

            rhs.promoteToType = promoteFromTo[trhs, tlhs];
            lhs.promoteToType = promoteFromTo[tlhs, trhs];

            if (!HaveSameTypes(lhs, rhs))
            {
                _listener.Error("line " + lhs.Token.Line + ":" +
                    lhs.Token.CharPositionInLine + " Type mismatch, equality operators == and != require arguments of the same type");
            }

            return INT;
        }
Exemplo n.º 48
0
 public string text(LSLAst t)
 {
     string ts = "";
     //if (t.evalType != null) ts = ":<" + t.evalType + ">";
     return _tokens.ToString(t.TokenStartIndex,
                            t.TokenStopIndex) + ts;
 }
Exemplo n.º 49
0
        public ISymbolType Uminus(LSLAst a)
        {
            if (a.evalType == null)
            {
                _listener.Error(
                    "line " + a.Token.Line + ":" + a.Token.CharPositionInLine +
                    " Unknown type in expression -" + a.Text
                );

                return VOID;
            }

            //only integer, float, vector and rotations can be negated
            if (! TypeIsIn(a.evalType, new ISymbolType[] { INT, FLOAT, VECTOR, ROTATION }))
            {
                _listener.Error(
                    "line " + a.Token.Line + ":" + a.Token.CharPositionInLine +
                    " Unary minus (-N) not valid for type " + a.evalType.Name
                );
            }

            return a.evalType;
        }
Exemplo n.º 50
0
        public bool CheckRotationLiteral(LSLAst e1, LSLAst e2, LSLAst e3, LSLAst e4)
        {
            if (! AllTypesAreResolved(new LSLAst[] {e1, e2, e3, e4}))
            {
                _listener.Error(
                    "line " + e1.Token.Line + ":" + e1.Token.CharPositionInLine +
                    " Rotation contains expression(s) of unknown type"
                );

                return false;
            }

            //try type promotion first
            e1.promoteToType = promoteFromTo[e1.evalType.TypeIndex, FLOAT.TypeIndex];
            e2.promoteToType = promoteFromTo[e2.evalType.TypeIndex, FLOAT.TypeIndex];
            e3.promoteToType = promoteFromTo[e3.evalType.TypeIndex, FLOAT.TypeIndex];
            e4.promoteToType = promoteFromTo[e4.evalType.TypeIndex, FLOAT.TypeIndex];

            if (CanAssignTo(e1.evalType, FLOAT, e1.promoteToType) &&
                CanAssignTo(e2.evalType, FLOAT, e2.promoteToType) &&
                CanAssignTo(e3.evalType, FLOAT, e3.promoteToType) &&
                CanAssignTo(e4.evalType, FLOAT, e4.promoteToType))
            {
                return true;
            }

            _listener.Error(
                    "line " + e1.Token.Line + ":" + e1.Token.CharPositionInLine +
                    " Rotation components must be float or implicitly convertable to float "
                );

            return false;
        }
Exemplo n.º 51
0
 public ISymbolType PostInc(LSLAst a)
 {
     return PreInc(a);
 }
Exemplo n.º 52
0
        public ISymbolType MethodCall(LSLAst id, IList <LSLAst> args)
        {
            Symbol s = id.scope.Resolve(id.Text + "()");

            if (s == null)
            {
                _listener.Error(
                    "line " + id.Token.Line + ":" + id.Token.CharPositionInLine +
                    " Call to undefined function " + id.Text + "()"
                    );

                return(VOID);
            }

            MethodSymbol ms = (MethodSymbol)s;

            id.symbol = ms;

            //check the call parameters
            if (!AllTypesAreResolved(args))
            {
                _listener.Error(
                    "line " + id.Token.Line + ":" + id.Token.CharPositionInLine +
                    " Method call contains expression(s) of unknown type"
                    );

                return(ms.Type);
            }

            //check param count and type
            if (args.Count != ms.Members.Count)
            {
                _listener.Error(
                    "line " + id.Token.Line + ":" + id.Token.CharPositionInLine +
                    " Function " + id.Text + "() takes " + Convert.ToString(ms.Members.Count) +
                    " parameters, " + args.Count + " given"
                    );

                return(ms.Type);
            }


            List <ParmAndExpected> erroredParms = new List <ParmAndExpected>();
            IEnumerator <Symbol>   correctParms = ms.Members.GetEnumerator();

            foreach (LSLAst parm in args)
            {
                correctParms.MoveNext();

                //promote if necessary
                parm.promoteToType = promoteFromTo[parm.evalType.TypeIndex, correctParms.Current.Type.TypeIndex];

                if (!CanAssignTo(parm.evalType, correctParms.Current.Type, parm.promoteToType))
                {
                    erroredParms.Add(new ParmAndExpected {
                        Parm = parm, Expected = correctParms.Current
                    });
                }
            }

            //one of the parameter types is incompatible
            if (erroredParms.Count > 0)
            {
                _listener.Error("line " + id.Token.Line + ":" + id.Token.CharPositionInLine +
                                " In call of function " + id.Text + "(): ");

                foreach (ParmAndExpected error in erroredParms)
                {
                    _listener.Error(
                        "line " + error.Parm.Token.Line + ":" + error.Parm.Token.CharPositionInLine +
                        " Parameter " + error.Expected.Name + ", expected " + error.Expected.Type.Name +
                        " got " + error.Parm.evalType.Name
                        );
                }
            }

            return(ms.Type);
        }
Exemplo n.º 53
0
        public ISymbolType UBitNot(LSLAst a)
        {
            if (a.evalType == null)
            {
                _listener.Error(
                    "line " + a.Token.Line + ":" + a.Token.CharPositionInLine +
                    " Unknown type in expression !" + a.Text
                );

                return VOID;
            }

            if (a.evalType != INT)
            {
                _listener.Error(
                    "line " + a.Token.Line + ":" + a.Token.CharPositionInLine +
                    " Bitwise not (~) not valid for type " + a.evalType.Name
                );

                return VOID;
            }

            return INT;
        }
Exemplo n.º 54
0
        public ISymbolType MethodCall(LSLAst id, IList<LSLAst> args)
        {
            Symbol s = id.scope.Resolve(id.Text + "()");

            if (s == null)
            {
                _listener.Error(
                    "line " + id.Token.Line + ":" + id.Token.CharPositionInLine +
                    " Call to undefined function " + id.Text + "()"
                );

                return VOID;
            }

            MethodSymbol ms = (MethodSymbol)s;
            id.symbol = ms;

            //check the call parameters
            if (!AllTypesAreResolved(args))
            {
                _listener.Error(
                    "line " + id.Token.Line + ":" + id.Token.CharPositionInLine +
                    " Method call contains expression(s) of unknown type"
                );

                return ms.Type;
            }

            //check param count and type
            if (args.Count != ms.Members.Count)
            {
                _listener.Error(
                    "line " + id.Token.Line + ":" + id.Token.CharPositionInLine +
                    " Function " + id.Text + "() takes " + Convert.ToString(ms.Members.Count) +
                    " parameters, " + args.Count + " given"
                );

                return ms.Type;
            }


            List<ParmAndExpected> erroredParms = new List<ParmAndExpected>();
            IEnumerator<Symbol> correctParms = ms.Members.GetEnumerator();
            foreach (LSLAst parm in args)
            {
                correctParms.MoveNext();

                //promote if necessary
                parm.promoteToType = promoteFromTo[parm.evalType.TypeIndex, correctParms.Current.Type.TypeIndex];

                if (! CanAssignTo(parm.evalType, correctParms.Current.Type, parm.promoteToType))
                {
                    erroredParms.Add(new ParmAndExpected { Parm = parm, Expected = correctParms.Current });
                }
            }

            //one of the parameter types is incompatible
            if (erroredParms.Count > 0)
            {
                _listener.Error("line " + id.Token.Line + ":" + id.Token.CharPositionInLine +
                    " In call of function " + id.Text + "(): ");

                foreach (ParmAndExpected error in erroredParms)
                {
                    _listener.Error(
                        "line " + error.Parm.Token.Line + ":" + error.Parm.Token.CharPositionInLine +
                        " Parameter " + error.Expected.Name + ", expected " + error.Expected.Type.Name +
                        " got " + error.Parm.evalType.Name
                    );
                }
            }

            return ms.Type;
        }
Exemplo n.º 55
0
        public ISymbolType SubScript(LSLAst id, LSLAst subScript)
        {
            //the lhs must be an ID and it must be of vector type or rotation type
            //and it must be the letters x, y, z, or s for rotation
            if (id.Type != LSLParser.ID)
            {
                _listener.Error(
                    "line " + id.Token.Line + ":" + id.Token.CharPositionInLine +
                    " Use of subscript ." + subScript.Text + " requires a vector or rotation variable "
                );

                return VOID;
            }

            if (!TypeIsIn(id.evalType, new ISymbolType[] { VECTOR, ROTATION }))
            {
                _listener.Error(
                    "line " + id.Token.Line + ":" + id.Token.CharPositionInLine +
                    " Use of subscript ." + subScript.Text + " requires a vector or rotation variable"
                );

                return VOID;
            }

            if (id.evalType == VECTOR)
            {
                if (subScript.Text != "x" &&
                    subScript.Text != "y" &&
                    subScript.Text != "z")
                {
                    _listener.Error(
                        "line " + id.Token.Line + ":" + id.Token.CharPositionInLine +
                        " Invalid subscript ." + subScript.Text
                    );

                    return VOID;
                }
            }

            if (id.evalType == ROTATION)
            {
                if (subScript.Text != "x" &&
                    subScript.Text != "y" &&
                    subScript.Text != "z" &&
                    subScript.Text != "s")
                {
                    _listener.Error(
                        "line " + id.Token.Line + ":" + id.Token.CharPositionInLine +
                        " Invalid subscript ." + subScript.Text
                    );

                    return VOID;
                }
            }

            return FLOAT;
        }
Exemplo n.º 56
0
        public bool IsAssignable(LSLAst lhs)
        {
            //lhs will either be an id direct or an EXPR with an ID child
            if (lhs.Type == LSLParser.ID)
            {
                return true;
            }

            if (lhs.Type == LSLParser.EXPR &&
                lhs.ChildCount == 1 &&
                lhs.Children[0].Type == LSLParser.ID)
            {
                return true;
            }

            if (lhs.Type == LSLParser.SUBSCRIPT)
            {
                return true;
            }

            
            _listener.Error(
                "line " + lhs.Line + ":" + lhs.CharPositionInLine + " '" + 
                lhs.Text + "' is not assignable"
            );

            return false;
        }
Exemplo n.º 57
0
        public void CheckEvt(IScope currScope, LSLAst id)
        {   
            EventSymbol evt = (EventSymbol)currScope.Resolve(id.Text + "()");

            Debug.Assert(evt != null);

            //try to find this event in our table
            if (!_supportedEvents.HasEventByName(id.Text))
            {
                _listener.Error("line " + id.Token.Line + ":" +
                    id.Token.CharPositionInLine + " No event evailable with name '" + id.Text + "'");

                return;
            }

            //also try to resolve the arguments
            List<VarType> passedEvtArgs = evt.ExtractArgumentTypes();
            if (!_supportedEvents.HasEventBySig(id.Text, VarType.Void, passedEvtArgs))
            {
                string paramList = this.FormatParamTypeList(_supportedEvents.GetArguments(id.Text));
                _listener.Error("line " + id.Token.Line + ":" +
                    id.Token.CharPositionInLine + " Incorrect parameters for event " + id.Text +
                    paramList);
            }
        }
Exemplo n.º 58
0
        private void methodDef()
        {
            EnterRule_methodDef();
            EnterRule("methodDef", 10);
            TraceIn("methodDef", 10);
            LSLAst ID1   = default(LSLAst);
            LSLAst TYPE2 = default(LSLAst);

            try { DebugEnterRule(GrammarFileName, "methodDef");
                  DebugLocation(122, 1);
                  try
                  {
                      // Analyze.g:123:2: ( ^( METHOD_DEF ( TYPE )? ID ( . )* ) )
                      DebugEnterAlt(1);
                      // Analyze.g:123:4: ^( METHOD_DEF ( TYPE )? ID ( . )* )
                      {
                          DebugLocation(123, 4);
                          DebugLocation(123, 6);
                          Match(input, METHOD_DEF, Follow._METHOD_DEF_in_methodDef264); if (state.failed)
                          {
                              return;
                          }

                          Match(input, TokenTypes.Down, null); if (state.failed)
                          {
                              return;
                          }
                          DebugLocation(123, 17);
                          // Analyze.g:123:17: ( TYPE )?
                          int alt3 = 2;
                          try { DebugEnterSubRule(3);
                                try { DebugEnterDecision(3, false);
                                      int LA3_0 = input.LA(1);

                                      if ((LA3_0 == TYPE))
                                      {
                                          alt3 = 1;
                                      }
                                } finally { DebugExitDecision(3); }
                                switch (alt3)
                                {
                                case 1:
                                    DebugEnterAlt(1);
                                    // Analyze.g:123:17: TYPE
                                    {
                                        DebugLocation(123, 17);
                                        TYPE2 = (LSLAst)Match(input, TYPE, Follow._TYPE_in_methodDef266); if (state.failed)
                                        {
                                            return;
                                        }
                                    }
                                    break;
                                }
                          } finally { DebugExitSubRule(3); }

                          DebugLocation(123, 23);
                          ID1 = (LSLAst)Match(input, ID, Follow._ID_in_methodDef269); if (state.failed)
                          {
                              return;
                          }
                          DebugLocation(123, 26);
                          // Analyze.g:123:26: ( . )*
                          try { DebugEnterSubRule(4);
                                while (true)
                                {
                                    int alt4 = 2;
                                    try { DebugEnterDecision(4, false);
                                          int LA4_0 = input.LA(1);

                                          if (((LA4_0 >= ASSIGN_EQ && LA4_0 <= 95)))
                                          {
                                              alt4 = 1;
                                          }
                                          else if ((LA4_0 == UP))
                                          {
                                              alt4 = 2;
                                          }
                                    } finally { DebugExitDecision(4); }
                                    switch (alt4)
                                    {
                                    case 1:
                                        DebugEnterAlt(1);
                                        // Analyze.g:123:26: .
                                        {
                                            DebugLocation(123, 26);
                                            MatchAny(input); if (state.failed)
                                            {
                                                return;
                                            }
                                        }
                                        break;

                                    default:
                                        goto loop4;
                                    }
                                }

loop4:
                                ; } finally { DebugExitSubRule(4); }


                          Match(input, TokenTypes.Up, null); if (state.failed)
                          {
                              return;
                          }
                          DebugLocation(124, 3);
                          if (state.backtracking == 1)
                          {
                              currentBranch = new FunctionBranch(ID1, (TYPE2 != null?TYPE2.Text:null));
                          }
                      }
                  }
                  catch (RecognitionException re)
                  {
                      ReportError(re);
                      Recover(input, re);
                  }
                  finally
                  {
                      TraceOut("methodDef", 10);
                      LeaveRule("methodDef", 10);
                      LeaveRule_methodDef();
                  }
                  DebugLocation(127, 1); } finally { DebugExitRule(GrammarFileName, "methodDef"); }
            return;
        }
Exemplo n.º 59
0
        public ISymbolType Assign(string type, LSLAst lhs, LSLAst rhs)
        {
            if (HasUnknownTypes(lhs, rhs))
            {
                return VOID;
            }

            //the left hand side needs to be assignable
            if (!IsAssignable(lhs))
            {
                return VOID;
            }

            int tlhs = lhs.evalType.TypeIndex; // promote right to left type?
            int trhs = rhs.evalType.TypeIndex;

            if (type == "=")
            {
                return StdAssign(lhs, rhs, tlhs, trhs);
            }

            ISymbolType[,] opTable = FindOperationTable(lhs, type);
            if (opTable == null)
            {
                return VOID;
            }

            ISymbolType symType = opTable[lhs.evalType.TypeIndex, rhs.evalType.TypeIndex];
            if (symType == VOID)
            {
                if (lhs.Type == LSLParser.EXPR)
                {
                    lhs = (LSLAst)lhs.Children[0];
                }

                _listener.Error("line " + lhs.Token.Line + ":" +
                    lhs.Token.CharPositionInLine + " '" + type + "' is not a valid operation between " +
                    lhs.evalType.Name + " and " + rhs.evalType.Name);
                return VOID;
            }

            return symType;
        }
Exemplo n.º 60
0
        public void DeclInit(LSLAst varName, LSLAst initExpr)
        {
            int tlhs = varName.symbol.Type.TypeIndex; // promote right to left type?
            varName.evalType = varName.symbol.Type; 
            int trhs = initExpr.evalType.TypeIndex;

            initExpr.promoteToType = promoteFromTo[trhs, tlhs];
            if (!CanAssignTo(initExpr.evalType, varName.evalType, initExpr.promoteToType))
            {
                _listener.Error(
                    "line " + varName.Line + ":" + varName.CharPositionInLine + " " + text(varName) + " and " +
                    text(initExpr) + " have incompatible types in " +
                    text((LSLAst)initExpr.Parent)
                );
            }
        }