public Function(pBaseLangObject parent) : base(parent) { this.children.Add(null); varType = null; this.IsAsync = false; }
public bool IsKindOf(VarTypeObject vto) { if (this.varType != VarType.Object) { return(false); } HelperClasses.NamespaceResolver nsrL = this.ident.LastIdent; HelperClasses.NamespaceResolver nsrR = vto.ident.LastIdent; if (!(nsrL.Reference is Interfaces.iClass)) { return(false); } if (!(nsrR.Reference is Interfaces.iClass)) { return(false); } var list = new List <Ident>(); list.AddRange(((Interfaces.iClass)nsrL.Reference).ExtendedClasses); list.Add(((Interfaces.iClass)nsrL.Reference).Name); foreach (var it in list) { HelperClasses.NamespaceResolver nsrTmp = it.LastIdent; if (nsrTmp.isSame(nsrR)) { return(true); } } return(false); }
public Function(pBaseLangObject parent) : base(parent) { this.children.Add(null); varType = null; this.IsAsync = false; this.SqfSuffix = ""; }
public VirtualFunction(pBaseLangObject parent) : base(parent) { argTypes = new List<VarTypeObject>(); this.children.Add(null); varType = null; }
public Null(pBaseLangObject parent, int line, int pos, string file) : base(parent) { this.Line = line; this.Pos = pos; this.File = file; ReferencedType = new VarTypeObject(VarType.NullObject); }
public SupportInfoObject(string command, Ident type, bool hasR = false, bool hasL = false) { this.SqfCommand = command; this.outType = new VarTypeObject(type); this.hasL = hasL; this.hasR = hasR; }
public Variable(pBaseLangObject parent, int pos, int line) : base(parent) { this.addChild(null); varType = null; this.Line = line; this.Pos = pos; }
public Variable(pBaseLangObject parent, int line, int pos, string file) : base(parent) { this.addChild(null); varType = null; this.Line = line; this.Pos = pos; this.File = file; }
public override int doFinalize() { ReferencedType = new VarTypeObject(((Ident)this.children[0]).LastIdent.ReferencedType); if (this.TemplateObject != null) { this.ReferencedType.TemplateObject = this.TemplateObject; } return(0); }
public override int doFinalize() { ReferencedType = new VarTypeObject(((Ident)this.children[0]).LastIdent.ReferencedType); if(this.TemplateObject != null) { this.ReferencedType.TemplateObject = this.TemplateObject; } return 0; }
public Ident(pBaseLangObject parent, string origVal, int line, int pos) : base(parent) { this.originalValue = origVal; referencedObject = null; referencedType = new VarTypeObject(VarType.Void); this.Line = line; this.Pos = pos; this.Access = AccessType.NA; this.isGlobalIdentifier = false; }
public override int doFinalize() { int errCount = 0; var list = this.getAllChildrenOf <EnumEntry>(); VarTypeObject vto = null; int offset = 0; List <string> usedValues = new List <string>(); for (int i = 0; i < list.Count; i++) { var it = list[i]; if (it.Value == null) { Value val = new Value(it); val.value = (i + offset).ToString(); it.Value = val; it.Value.varType.varType = VarType.Scalar; } else { if (it.Value.varType.varType == VarType.Scalar) { offset = int.Parse(it.Value.value) - i; } } if (usedValues.Contains(it.Value.value)) { Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.LNK0048, it.Name.Line, it.Name.Pos, it.Name.File)); errCount++; } usedValues.Add(it.Value.value); if (vto == null) { vto = it.Value.varType; } else if (!vto.Equals(it.Value.varType)) { Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.LNK0047, it.Name.Line, it.Name.Pos, it.Name.File)); errCount++; } } this.ReferencedType.ident = vto.ident; this.ReferencedType.varType = vto.varType; this.ReferencedType.TemplateObject = vto.TemplateObject; if (list.Count == 1) { Logger.Instance.log(Logger.LogLevel.WARNING, "Enum '" + this.Name.OriginalValue + "' only has a single value assigned to it"); } return(errCount); }
public override int doFinalize() { int errCount = 0; foreach (var it in this.children) { if (it is Expression) { Expression exp = (Expression)it; if (this.ReferencedType == null) { this.ReferencedType = exp.ReferencedType; } if (!this.ReferencedType.Equals(exp.ReferencedType)) { Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.LNK0013, exp.Line, exp.Pos)); errCount++; } } else { Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.UNKNOWN)); errCount++; } } if (this.ReferencedType != null) { this.ReferencedType = new VarTypeObject(this.ReferencedType); switch (this.ReferencedType.varType) { case VarType.Bool: this.ReferencedType.varType = VarType.BoolArray; break; case VarType.Scalar: this.ReferencedType.varType = VarType.ScalarArray; break; } } return(errCount); }
public override int doFinalize() { int errCount = 0; foreach(var it in this.children) { if(it is Expression) { Expression exp = (Expression)it; if (this.ReferencedType == null) this.ReferencedType = exp.ReferencedType; if (!this.ReferencedType.Equals(exp.ReferencedType)) { Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.LNK0013, exp.Line, exp.Pos)); errCount++; } } else { Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.UNKNOWN)); errCount++; } } if (this.ReferencedType != null) { this.ReferencedType = new VarTypeObject(this.ReferencedType); switch(this.ReferencedType.varType) { case VarType.Bool: this.ReferencedType.varType = VarType.BoolArray; break; case VarType.Scalar: this.ReferencedType.varType = VarType.ScalarArray; break; case VarType.String: this.ReferencedType.varType = VarType.StringArray; break; } } return errCount; }
public Value(pBaseLangObject parent) : base(parent) { varType = new VarTypeObject(VarType.Void); value = ""; }
public override int doFinalize() { int errCount = 0; this.ReferencedType = new VarTypeObject(VarType.Void); VarTypeObject vto = this.ReferencedType; if (this.expressionObjects.Count == 1) { var obj = this.expressionObjects[0]; if (obj is Interfaces.iHasType) { if (obj is Ident) { vto.copyFrom(((Ident)obj).LastIdent.ReferencedType); } else { vto.copyFrom(((Interfaces.iHasType)obj).ReferencedType); } } else if (obj is Value) { vto.copyFrom(((Value)obj).varType); } else { Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.UNKNOWN, this.Line, this.Pos, this.File)); errCount++; } } else { int i = 0; foreach (var op in this.expressionOperators) { var lArg = this.expressionObjects[i]; var rArg = this.expressionObjects[++i]; VarTypeObject lType; VarTypeObject rType; if (lArg is Interfaces.iHasType) { lType = ((Interfaces.iHasType)lArg).ReferencedType; if (lArg is Ident) { lType = ((Ident)lArg).LastIdent.ReferencedType; } } else if (lArg is Value) { lType = ((Value)lArg).varType; } else { Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.UNKNOWN, this.Line, this.Pos, this.File)); errCount++; continue; } if (rArg is Interfaces.iHasType) { rType = ((Interfaces.iHasType)rArg).ReferencedType; if (rArg is Ident) { rType = ((Ident)rArg).LastIdent.ReferencedType; } } else if (rArg is Value) { rType = ((Value)rArg).varType; } else { Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.UNKNOWN, this.Line, this.Pos, this.File)); errCount++; continue; } switch (op) { case "&": case "&&": case "|": case "||": if (lType.varType != VarType.Bool || rType.varType != VarType.Bool) { Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.LNK0014, this.Line, this.Pos, this.File)); errCount++; break; } vto.copyFrom(new VarTypeObject(VarType.Bool)); break; case "==": vto.copyFrom(new VarTypeObject(VarType.Bool)); break; case "+": case "-": case "*": case "/": if (lType.varType != VarType.Scalar || rType.varType != VarType.Scalar) { Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.LNK0014, this.Line, this.Pos, this.File)); errCount++; break; } vto.copyFrom(new VarTypeObject(VarType.Scalar)); break; case ">": case ">=": case "<": case "<=": if (lType.varType != VarType.Scalar || rType.varType != VarType.Scalar) { Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.LNK0014, this.Line, this.Pos, this.File)); errCount++; break; } vto.copyFrom(new VarTypeObject(VarType.Bool)); break; default: throw new NotImplementedException(); } } } if (vto.IsObject) { errCount += vto.ident.finalize(); } return(errCount); }
public SqfCall(pBaseLangObject parent) : base(parent) { this.children.Add(null); this.referencedType = new VarTypeObject(VarType.Void); }
public void copyFrom(VarTypeObject vto) { this.ident = vto.ident; this.varType = vto.varType; template = vto.template; }
public VarTypeObject(VarTypeObject vto) { this.ident = vto.ident; this.varType = vto.varType; template = vto.template; }
public override int doFinalize() { int errCount = 0; Ident parentIdent = (this.Parent is Ident ? (Ident)this.Parent : default(Ident)); //Check what we have here (possible outcomes: variableacces, arrayaccess, functioncall, namespaceaccess) #region typeDetection type = IdenType.NamespaceAccess; var fncCalls = this.getAllChildrenOf<FunctionCall>(); var arrAccess = this.getAllChildrenOf<ArrayAccess>(); if (this.Parent is Template) { type = IdenType.TemplateVar; } else if (this.Parent is SqfCall && ((SqfCall)this.Parent).Name == this) { type = IdenType.SqfCommandName; } else if (this.IsSelfReference) { type = IdenType.ThisVar; } else if (fncCalls.Count > 0) { type = IdenType.FunctionCall; } else if (arrAccess.Count > 0) { type = IdenType.ArrayAccess; } else if (parentIdent == null && this.Access == AccessType.NA) { if (this.Parent is Interfaces.iClass || (this.Parent is Interfaces.iFunction && ((Interfaces.iFunction)this.Parent).ReturnType.ident == this)) type = IdenType.NamespaceAccess; else type = IdenType.VariableAccess; } else if (parentIdent != null && ( (parentIdent.Access == AccessType.Namespace && this.Access == AccessType.NA) || this.Access == AccessType.Instance || (parentIdent.Access == AccessType.Instance && this.Access == AccessType.NA) )) { var ntr = HelperClasses.NamespaceResolver.createNSR(this); if (ntr.Reference is Interfaces.iClass) type = IdenType.NamespaceAccess; else type = IdenType.VariableAccess; } else if (this.Access == AccessType.Namespace) { type = IdenType.NamespaceAccess; } else if (this.Access == AccessType.Instance && parentIdent == null) { type = IdenType.VariableAccess; } else { Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.UNKNOWN, this.Line, this.Pos)); errCount++; } #endregion //And process it then ((unless its a simple ident, then we do not want to process ... here any further)) if (this.IsSimpleIdentifier && ((this.Parent is Interfaces.iName && ((Interfaces.iName)this.Parent).Name == this) || (this.Parent is Interfaces.iHasType && !(this.Parent is Expression) && ((Interfaces.iHasType)this.Parent).ReferencedType.ident == this)) && !(this.Parent is AssignContainer)) { this.referencedObject = this.Parent; if (this.Parent is Interfaces.iHasType) this.referencedType = ((Interfaces.iHasType)this.Parent).ReferencedType; else //todo: try to replace with proper refObject type this.referencedType = new VarTypeObject(this, true, (this.Parent is Interfaces.iTemplate ? ((Interfaces.iTemplate)this.Parent).TemplateObject : null) ); } else { switch (type) { #region ThisVar case IdenType.ThisVar: { Interfaces.iClass curObject = this.getFirstOf<Interfaces.iClass>(); this.referencedObject = (pBaseLangObject)curObject; this.referencedType = curObject.VTO; } break; #endregion #region TemplateVar case IdenType.TemplateVar: { this.referencedObject = (pBaseLangObject)this.getFirstOf<Interfaces.iClass>(); this.referencedType = ((Interfaces.iClass)this.referencedObject).VTO; } break; #endregion #region SqfCommandName case IdenType.SqfCommandName: { this.referencedObject = this.Parent; this.referencedType = ((SqfCall)this.Parent).ReferencedType; } break; #endregion #region VariableAccess & ArrayAccess case IdenType.VariableAccess: case IdenType.ArrayAccess: { var variable = HelperClasses.NamespaceResolver.getVariableReferenceOfFQN(HelperClasses.NamespaceResolver.createNSR(this,true), true, this); if (variable == null) { variable = HelperClasses.NamespaceResolver.getVariableReferenceOfFQN(this, false, this); } if (variable == null) { Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.LNK0012, this.Line, this.Pos)); errCount++; } this.referencedObject = variable; //Set type to variable type this.referencedType = variable.varType; if (type == IdenType.ArrayAccess) { if (variable.ReferencedType.IsObject) { //Check if given object is implementing the ArrayAccess operator if (variable.ReferencedType.ident.LastIdent.referencedObject is Interfaces.iClass) { Interfaces.iClass classRef = (Interfaces.iClass)variable.ReferencedType.ident.LastIdent.referencedObject; Interfaces.iOperatorFunction opFnc = classRef.getOperatorFunction(OverridableOperator.ArrayAccess); if (opFnc == null) { Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.LNK0005, this.Line, this.Pos)); errCount++; } else { this.referencedType = opFnc.ReturnType; if (variable.TemplateObject != null) { var templateList = ((pBaseLangObject)opFnc).getAllParentsOf<Interfaces.iTemplate>(); foreach (var it in templateList) { var tmp = HelperClasses.ArgList.resolveVarTypeObject(opFnc.ReturnType, it.TemplateObject, variable.TemplateObject); if (tmp != opFnc.ReturnType) { this.referencedType = tmp; break; } } } } } else { Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.UNKNOWN, this.Line, this.Pos)); errCount++; } } else { //just check if this is an array type switch (this.referencedType.varType) { case VarType.BoolArray: this.referencedType = new VarTypeObject(this.referencedType); this.referencedType.varType = VarType.Bool; break; case VarType.ScalarArray: this.referencedType = new VarTypeObject(this.referencedType); this.referencedType.varType = VarType.Scalar; break; case VarType.StringArray: this.referencedType = new VarTypeObject(this.referencedType); this.referencedType.varType = VarType.String; break; default: Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.LNK0006, this.Line, this.Pos)); errCount++; break; } } } } break; #endregion #region FunctionCall case IdenType.FunctionCall: { List<Interfaces.iFunction> fncList; var fncCall = fncCalls[0]; var newInstance = this.getFirstOf<NewInstance>(); var fqn = this.FullyQualifiedName; if (parentIdent != null && parentIdent.ReferencedObject is Variable) { //if (((Variable)parentIdent.ReferencedObject).ReferencedType.IsObject) // fqn = ((Interfaces.iClass)((Variable)parentIdent.ReferencedObject).ReferencedType.ident.LastIdent.ReferencedObject).Name.LastIdent.FullyQualifiedName + "." + this.originalValue; //else fqn = parentIdent.ReferencedType.ident.LastIdent.referencedType.ident.LastIdent.FullyQualifiedName + "." + this.originalValue; } if (newInstance == null) { fncList = HelperClasses.NamespaceResolver.getFunctionReferenceOfFQN(HelperClasses.NamespaceResolver.createNSR(fqn)); } else { fncList = HelperClasses.NamespaceResolver.getFunctionReferenceOfFQN(HelperClasses.NamespaceResolver.createNSR(fqn + "::" + this.originalValue)); } if (fncList.Count == 0) { Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.UNKNOWN, this.Line, this.Pos)); errCount++; } else { //Search the correct function in the possible matches Interfaces.iFunction fnc = null; foreach (var it in fncList) { if (HelperClasses.ArgList.matchesArglist(it.ArgList, fncCall.ArgList, (parentIdent.ReferencedObject is Variable ? (Variable)parentIdent.ReferencedObject : null))) { fnc = it; break; } } //Raise new linker issue if we could not locate a matching function if (fnc == null) { Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.LNK0002, this.Line, this.Pos)); errCount++; } else { if(fnc is Function && ((Function)fnc).IsConstructor && this.getFirstOf<NewInstance>() == null) { Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.LNK0026, this.Line, this.Pos)); errCount++; } //Ref the object to the function this.referencedObject = (pBaseLangObject)fnc; //Ref the type to the return type this.referencedType = fnc.ReturnType; //As last step make sure we got the correct encapsulation here var enc = fnc.FunctionEncapsulation; if (enc != Encapsulation.Static && enc != Encapsulation.Public) { var parentClass = this.getFirstOf<Interfaces.iClass>(); HelperClasses.NamespaceResolver fncNsr = fnc.Name; if (enc == Encapsulation.Private) { //Private encapsulation just requires checking the current class we are operating in if (!fncNsr.isInNamespace(parentClass.Name)) { Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.LNK0003, this.Line, this.Pos)); errCount++; } } else { //Protected we need to check ALL extended classes ... var classes = parentClass.ExtendedClasses; bool flag = false; foreach (var it in classes) { if (fncNsr.isInNamespace(it)) { flag = true; break; } } if (!flag) { Logger.Instance.log(Logger.LogLevel.ERROR, ErrorStringResolver.resolve(ErrorStringResolver.LinkerErrorCode.LNK0004, this.Line, this.Pos)); errCount++; } } } } } } break; #endregion #region NamespaceAccess case IdenType.NamespaceAccess: { var nsr = HelperClasses.NamespaceResolver.createNSR(this, this.IsAnonymousIdent); var reference = nsr.Reference; this.referencedObject = reference; if (reference is Interfaces.iClass) this.referencedType = ((Interfaces.iClass)reference).VTO; else if (reference is Interfaces.iFunction) this.referencedType = ((Interfaces.iFunction)reference).ReturnType; else this.referencedType = null; } break; #endregion } } return errCount; }
public SqfCall(pBaseLangObject parent) : base(parent) { this.children.Add(null); this.ReferencedType = new VarTypeObject(VarType.Void); }
public VirtualFunction(pBaseLangObject parent) : base(parent) { argTypes = new List <VarTypeObject>(); this.children.Add(null); varType = null; }