public static NodeBinder BindNotInList(NodeBinder left, IEnumerable <NodeBinder> rest) { return(new NodeBinder(ctx => { var equalExprs = rest.Select( n => Expression.NotEqual(left(ctx), n(ctx))); return equalExprs.ToOrElseExpression(); })); }
public override void VisitMvApplyOperator(MvApplyOperator node) { base.VisitMvApplyOperator(node); if (_position >= node.OnKeyword.TextStart) { var info = new NodeBinder(_binder).VisitMvApplyOperator(node); _binder._rowScope = info?.ResultType as TableSymbol; } }
public static NodeBinder Bind(ModelBuilder builder, GeoModel node) { if (null != (object)builder) { var nb = new NodeBinder { builder = builder, Restore = System.Threading.Interlocked.Exchange(ref builder.geoModel, node), Replace = node, }; nb.NeedDispose = nb.Restore != nb.Replace; if (nb.NeedDispose) { return(nb); } } return(default(NodeBinder)); }
public static NodeBinder BindUserOperator(string opr, NodeBinder left, NodeBinder right) { return(new NodeBinder(ctx => { if (!ctx.UserFunctions.ContainsKey(opr)) { throw new BindingException($"Undefined user function: '{opr}'"); } var func = ctx.UserFunctions[opr]; var leftExpr = left(ctx); var rightExpr = right(ctx); if (func.GetMethodInfo().IsStatic) { return Expression.Call(func.GetMethodInfo(), leftExpr, rightExpr); } else { return Expression.Call(Expression.Constant(func.Target), func.GetMethodInfo(), leftExpr, rightExpr); } })); }
private ArrayType GetArrayType(PapyrusType elementType) { var objectIdentifier = elementType.Name; lock (_arrayTypes) { if (!_arrayTypes.ContainsKey(objectIdentifier)) { var source = CreateArrayTypeSource(objectIdentifier); var stream = new CaseInsensitiveStringStream(source); var lexer = new PapyrusLexer(stream); var parser = new PapyrusParser(new CommonTokenStream(lexer)); parser.AsDynamic().KnownUserFlags = _program.FlagsFile.NativeFlagsDict; parser.script(); var compilerType = parser.ParsedObject; var nodeBinder = new NodeBinder(); var node = nodeBinder.Bind(null, _program, new ScriptText(null, source, "0"), compilerType.GetTokenStream(), compilerType.GetAst()); var scopeBinder = new ScopeBinder(); var scopeResult = scopeBinder.Bind(compilerType, node.Value); node.Diagnostics.AddRange(scopeResult.Diagnostics); var symbolBinder = new SymbolBinder(); var symbolResult = symbolBinder.Bind(node.Value); var type = new ArrayType(_program, symbolResult.Value, compilerType, elementType.Name); _arrayTypes.Add(objectIdentifier, type); } return(_arrayTypes[objectIdentifier]); } }
public TreeBinder(Binder binder) { _binder = binder; _nodeBinder = new NodeBinder(binder); }
public ScriptFile(ObjectIdentifier id, string filePath, PapyrusProgram program, IScriptTextProvider textProvider, ILogger <ScriptFile> logger) { _id = id; _filePath = filePath; _program = program; _textProvider = textProvider; _logger = logger; var initialVersion = _textProvider.GetTextVersion(_filePath).WaitForResult(); _scriptText = new TokenEqualityCachedValue <ScriptText, string>( () => _textProvider.GetText(_filePath).WaitForResult(), (_) => { var currentVersion = _scriptText.CurrentToken; var version = _textProvider.GetTextVersion(_filePath).WaitForResult(); if (currentVersion != version) { _logger.LogTrace($"{_id} file version changed from '{currentVersion}' to '{version}'. (Thread: {Thread.CurrentThread.ManagedThreadId})"); } return(version); }, initialVersion); _textProvider.OnScriptTextChanged += HandleScriptTextChanged; _compiler = new TokenEqualityCachedValue <ScriptCompiler, string>(() => { var compiler = new ScriptCompiler(this, _logger); compiler.CompilerNotifyHandler += (s, e) => { _logger.LogTrace($"Compiler: {e.sMessage}"); }; return(compiler); }, (_) => _scriptText.Value.Version, initialVersion); _compilationResult = new TokenEqualityCachedValue <DiagnosticResult <CompilationResult>, ScriptCompiler>(() => { DiagnosticResult <CompilationResult> compileFunc() { return(DiagnosticResult <CompilationResult> .TryWithDiagnostics((diagnostics) => { return UseCompiler((compiler, types) => { var compilationResult = new CompilationResult(); _logger.LogTrace($"Compiling {_id}... (Thread: {Thread.CurrentThread.ManagedThreadId})"); var type = compiler.Load(types); compilationResult.CompilerType = type; compilationResult.CompilerNode = type?.GetAst(); _logger.LogTrace($"Type checking {_id}... (Thread: {Thread.CurrentThread.ManagedThreadId})"); var typeWalker = new TypeWalker(this, type, _logger); typeWalker.OnError((s, e) => { if (!e.ErrorText.StartsWith("mismatched tree node")) { diagnostics.Add(e.ToDiagnostic()); } }); try { #if FALLOUT4 typeWalker.script(type, compiler, types); #elif SKYRIM lock (types) { if (types.ContainsKey("int")) { types.Remove("int"); types.Remove("float"); types.Remove("string"); types.Remove("bool"); } } typeWalker.script(type, compiler, types, new Stack <string>()); #endif } catch (Exception e) { _logger.LogWarning(e, $"Thrown during type checking of {_id}"); } return compilationResult; }, (s, e) => { diagnostics.Add(e.ToDiagnostic()); }); })); } // If there are diagnostic errors, we re-run the compile once in case anything was missing, // but couldn't be resolved at the time. var result = compileFunc(); if (result.Diagnostics.Count > 0) { return(compileFunc()); } return(result); }, (_) => _compiler.Value); _node = new TokenEqualityCachedValue <DiagnosticResult <ScriptNode>, CompilationResult>(() => { if (CompilerType == null) { return(null); } _logger.LogTrace($"Transforming {_id} syntax tree... (Thread: {Thread.CurrentThread.ManagedThreadId})"); var nodeBinder = new NodeBinder(); var node = nodeBinder.Bind(this, _program, Text, CompilerType.GetTokenStream(), CompilerNode); _logger.LogTrace($"Binding script scopes to {_id} syntax tree... (Thread: {Thread.CurrentThread.ManagedThreadId})"); var scopeBinder = new ScopeBinder(); var scopeResult = scopeBinder.Bind(CompilerType, node.Value); node.Diagnostics.AddRange(scopeResult.Diagnostics); _logger.LogTrace($"Binding {_id} symbols... (Thread: {Thread.CurrentThread.ManagedThreadId})"); var symbolBinder = new SymbolBinder(); var symbolResult = symbolBinder.Bind(node.Value); node.Diagnostics.AddRange(symbolResult.Diagnostics); return(node); }, (_) => _compilationResult.Value?.Value); _type = new TokenEqualityCachedValue <ScriptType, ScriptSymbol>(() => { if (Symbol == null) { return(null); } _logger.LogTrace($"Creating {_id} type... (Thread: {Thread.CurrentThread.ManagedThreadId})"); return(new ScriptType(Program, Symbol, CompilerType)); }, (_) => Symbol); }