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); } }
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); }
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); }
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); }
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); }
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); }
public void CheckLogicalExpr(LSLAst expr) { if (expr.evalType != INT) { _listener.Error("line " + expr.Token.Line + ":" + expr.Token.CharPositionInLine + " Logical expressions require integer type"); } }
public string text(LSLAst t) { string ts = ""; //if (t.evalType != null) ts = ":<" + t.evalType + ">"; return(_tokens.ToString(t.TokenStartIndex, t.TokenStopIndex) + ts); }
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); }
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); }
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); }
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); }
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 ); } }
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; } }
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); }
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); }
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); }
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) ); } }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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 ); } }
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); }
public ISymbolType Unot(LSLAst a) { return(INT); }
public ISymbolType PostDec(LSLAst a) { return(PreDec(a)); }
public ISymbolType PostInc(LSLAst a) { return(PreInc(a)); }