private UInt32 ComputeTupleSize(IRRule rule, IRFuncCondition condition, UInt32 lastTupleSize) { UInt32 tupleSize = lastTupleSize; foreach (var param in condition.Params) { if (param is IRVariable) { var variable = param as IRVariable; if (variable.Index >= tupleSize) { tupleSize = (UInt32)variable.Index + 1; } } } return tupleSize; }
private IRCondition ASTConditionToIR(IRRule rule, ASTCondition astCondition) { if (astCondition is ASTFuncCondition) { var astFunc = astCondition as ASTFuncCondition; var func = new IRFuncCondition { Func = new IRSymbolRef(new FunctionNameAndArity(astFunc.Name, astFunc.Params.Count)), Not = astFunc.Not, Params = new List <IRValue>(astFunc.Params.Count), TupleSize = -1, Location = astCondition.Location }; foreach (var param in astFunc.Params) { func.Params.Add(ASTValueToIR(rule, param)); } return(func); } else if (astCondition is ASTBinaryCondition) { var astBin = astCondition as ASTBinaryCondition; return(new IRBinaryCondition { LValue = ASTValueToIR(rule, astBin.LValue), Op = astBin.Op, RValue = ASTValueToIR(rule, astBin.RValue), TupleSize = -1, Location = astCondition.Location }); } else { throw new InvalidOperationException("Cannot convert unknown AST condition type to IR"); } }
private void VerifyIRFuncCondition(IRRule rule, IRFuncCondition condition, int conditionIndex) { // TODO - Merge FuncCondition and IRStatement base? // Base --> IRParameterizedCall --> FuncCond: has (NOT) field var func = Context.LookupSignature(condition.Func.Name); if (func == null) { Context.Log.Error(condition.Location, DiagnosticCode.UnresolvedSymbol, "Symbol \"{0}\" could not be resolved", condition.Func.Name); return; } if (!func.FullyTyped) { Context.Log.Error(condition.Location, DiagnosticCode.UnresolvedSignature, "Signature of \"{0}\" could not be determined", condition.Func.Name); return; } func.Read = true; if (conditionIndex == 0) { switch (rule.Type) { case RuleType.Proc: if (func.Type != FunctionType.Proc) { Context.Log.Error(condition.Location, DiagnosticCode.InvalidSymbolInInitialCondition, "Initial proc condition can only be a PROC name; \"{0}\" is a {1}", condition.Func.Name, func.Type); return; } break; case RuleType.Query: if (func.Type != FunctionType.UserQuery) { Context.Log.Error(condition.Location, DiagnosticCode.InvalidSymbolInInitialCondition, "Initial query condition can only be a user-defined QRY name; \"{0}\" is a {1}", condition.Func.Name, func.Type); return; } break; case RuleType.Rule: if (func.Type != FunctionType.Event && func.Type != FunctionType.Database) { Context.Log.Error(condition.Location, DiagnosticCode.InvalidSymbolInInitialCondition, "Initial rule condition can only be an event or a DB; \"{0}\" is a {1}", condition.Func.Name, func.Type); return; } break; default: throw new Exception("Unknown rule type"); } } else { if (func.Type != FunctionType.SysQuery && func.Type != FunctionType.Query && func.Type != FunctionType.Database && func.Type != FunctionType.UserQuery) { Context.Log.Error(condition.Location, DiagnosticCode.InvalidFunctionTypeInCondition, "Subsequent rule conditions can only be queries or DBs; \"{0}\" is a {1}", condition.Func.Name, func.Type); return; } } int index = 0; foreach (var param in func.Params) { var condParam = condition.Params[index]; ValueType type = condParam.Type; if (type == null) { Context.Log.Error(condParam.Location, DiagnosticCode.InternalError, "No type information available for func condition arg"); continue; } VerifyIRValue(rule, condParam); VerifyIRValueCall(rule, condParam, func, index, conditionIndex, condition.Not); VerifyParamCompatibility(func, index, param, condParam); index++; } }