private IRStatement ASTActionToIR(IRRule rule, ASTAction astAction) { if (astAction is ASTGoalCompletedAction) { var astGoal = astAction as ASTGoalCompletedAction; return(new IRStatement { Func = null, Goal = rule.Goal, Not = false, Params = new List <IRValue>(), Location = astAction.Location }); } else if (astAction is ASTStatement) { var astStmt = astAction as ASTStatement; var stmt = new IRStatement { Func = new IRSymbolRef(new FunctionNameAndArity(astStmt.Name, astStmt.Params.Count)), Goal = null, Not = astStmt.Not, Params = new List <IRValue>(astStmt.Params.Count), Location = astAction.Location }; foreach (var param in astStmt.Params) { stmt.Params.Add(ASTValueToIR(rule, param)); } return(stmt); } else { throw new InvalidOperationException("Cannot convert unknown AST condition type to IR"); } }
private void VerifyIRStatement(IRRule rule, IRStatement statement) { if (statement.Func == null) return; var func = Context.LookupSignature(statement.Func.Name); if (func == null) { Context.Log.Error(statement.Location, DiagnosticCode.UnresolvedSymbol, "Symbol \"{0}\" could not be resolved", statement.Func.Name); return; } if (!func.FullyTyped) { Context.Log.Error(statement.Location, DiagnosticCode.UnresolvedSignature, "Signature of \"{0}\" could not be determined", statement.Func.Name); return; } if (func.Type != FunctionType.Database && func.Type != FunctionType.Call && func.Type != FunctionType.SysCall && func.Type != FunctionType.Proc) { Context.Log.Error(statement.Location, DiagnosticCode.InvalidSymbolInStatement, "KB rule actions can only reference databases, calls and PROCs; \"{0}\" is a {1}", statement.Func.Name, func.Type); return; } if (statement.Not && func.Type != FunctionType.Database) { Context.Log.Error(statement.Location, DiagnosticCode.CanOnlyDeleteFromDatabase, "KB rule NOT actions can only reference databases; \"{0}\" is a {1}", statement.Func.Name, func.Type); return; } if (statement.Not) { func.Deleted = true; } else { func.Inserted = true; } int index = 0; foreach (var param in func.Params) { var ele = statement.Params[index]; ValueType type = ele.Type; if (type == null) { Context.Log.Error(ele.Location, DiagnosticCode.InternalError, "No type information available for statement argument"); continue; } VerifyIRValue(rule, ele); VerifyIRValueCall(rule, ele, func, index, -1, statement.Not); VerifyParamCompatibility(func, index, param, ele); index++; } }