private static Expression Load(SymbolTable symbols, Object obj, String name) { if (name.StartsWithInvariant(CtsPrefix)) { return(Expression.Constant(((IEnumerable <IGrouping <String, Type> >)obj) .Select(g => g.Key.Apply(k => symbols[k] = YacqExpression.TypeCandidate(symbols, g))) .ToArray() )); } else { var stream = (Stream)obj; switch (Path.GetExtension(name).ToLowerInvariant()) { case ".dll": #if SILVERLIGHT throw new NotImplementedException("Loading DLL is not implemented in Sliverlight environment."); #else return(Expression.Constant(new Byte[stream.Length].Apply(b => stream.Read(b, 0, b.Length)) .Let(Assembly.Load) .Apply(a => a.GetTypes() .Where(t => t.IsPublic) .ForEach(symbols.Import) ) )); #endif case ".yacb": throw new NotImplementedException("YACQ Binary code is not implemented."); default: return(new StreamReader(stream, true) .Dispose(r => YacqServices.Parse(symbols, r.ReadToEnd()))); } } }
public ReplWindow() { this.Width = 450; this.Height = 350; this.Title = "YACQ Console"; this.Content = this.textBox; this.textBox.AcceptsReturn = true; this.textBox.BorderThickness = new Thickness(0); this.textBox.FontFamily = new FontFamily("Consolas"); this.textBox.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled; this.textBox.VerticalScrollBarVisibility = ScrollBarVisibility.Visible; this.textBox.TextWrapping = TextWrapping.Wrap; this.textBox.Text = string.Format("YACQ {0} on Krile {1}\r\n", YacqServices.Version, typeof(App).Assembly.GetName().Version); this.textBox.Select(this.textBox.Text.Length, 0); this.textBox.PreviewKeyDown += this.textBox_PreviewKeyDown; this.symbolTable = new SymbolTable(YacqFilter.FilterSymbols, typeof(Symbols)) { { "*textbox*", YacqExpression.Constant(textBox) }, }; var rcPath = Path.Combine( Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "yacq_lib\\rc.yacq" ); if (File.Exists(rcPath)) { YacqServices.ParseAll(this.symbolTable, File.ReadAllText(rcPath)) .ForEach(e => YacqExpression.Lambda(e).Compile().DynamicInvoke()); this.textBox.AppendText("rc.yacq was loaded.\r\n"); } this.textBox.AppendText(">>> "); }
/// <summary> /// Reduces this node to a simpler expression with additional symbol tables. /// </summary> /// <param name="symbols">The additional symbol table for reducing.</param> /// <param name="expectedType">The type which is expected as the type of reduced expression.</param> /// <returns>The reduced expression.</returns> protected override Expression ReduceImpl(SymbolTable symbols, Type expectedType) { return(this._codes.Any() ? (Expression)TypeCandidate(typeof(String)).Method(symbols, "Format", this._codes .Select(c => YacqServices.Parse(symbols, c)) .StartWith(Constant(this.Value)) ) : Constant(this.Value)); }
public void Run() { this.AddReplInterface("console", new ConsoleReplInterface()); new FileInfo("replrc.yacq").If(f => f.Exists, f => YacqServices.Parse(File.ReadLines(f.FullName).SelectMany(l => l)) .Evaluate() ); this._replInterfaces.Values.ForEach(i => i.Initialize(this)); this._replInterfaces.Values.ForEach(i => i.Run()); }
public static void Main(string[] args) { var scriptFile = "EntryPoint.yacq"; if (args.Any()) { scriptFile = args[0]; } foreach (var exp in YacqServices.ParseAll(new SymbolTable(), File.ReadAllText(scriptFile))) { Expression.Lambda(exp).Compile().DynamicInvoke(); } }
private static Expression Parse(SymbolTable symbols, String code) { try { return(YacqServices.ParseAll(symbols, code) .Let(es => es.Length == 1 ? es.Single() : Expression.Block(es) )); } catch (Exception ex) { Fail(ex, Phase.Parse); return(null); } }
public void Run() { this.Output = ""; Observable.Start(() => { try { this.WriteOutput("Started."); var expr = YacqServices.Parse( new SymbolTable() { { DispatchTypes.Method, typeof(Object), "print", (e, s, t) => YacqExpression.Dispatch( s, DispatchTypes.Method, Expression.Constant(this), "Print", e.Left ) }, }, this.Body ); this.WriteOutput("Parsed.\nGenerated Expression:\n" + expr); var func = Expression.Lambda(expr).Compile(); this.WriteOutput("Compiled."); var ret = func.DynamicInvoke(); this.WriteOutput("Finished.\nReturned Type: " + (ret != null ? ret.GetType().Name : "null")); if (ret != null) { this.Output += "Returned Value:\n" + (ret is IEnumerable && !(ret is String) ? String.Join(", ", ((IEnumerable)ret).OfType <Object>().Select(e => e.ToString())) : ret ); } } catch (Exception ex) { this.WriteOutput(ex.ToString()); } }).Subscribe(_ => { }); }
private void RunCode(string file) { try { YacqServices.ParseAll(new SymbolTable(), File.ReadAllText(file)) .Select(exp => Expression.Lambda(exp).Compile()) .ToArray() //全部コンパイルしてから .ForEach(dlg => dlg.DynamicInvoke()); } catch (Exception ex) { ExceptionStorage.Register( ex, ExceptionCategory.PluginError, string.Format("{0} の実行に失敗しました: {1}", Path.GetFileName(file), ex.Message), () => this.RunCode(file) ); } }
public void Start() { this._stopwatch.Start(); var expressions = Arrays.Empty <Expression>(); try { expressions = YacqServices.ParseAll(this._symbols, this._code); expressions .Select(e => Tuple.Create(Node.Serialize(e), TypeRef.Serialize(e.Type))) .ForEach(_ => this.NotifyParsed(_.Item1, _.Item2)); this._parsedExpressions.OnCompleted(); this.Log(LogEntry.Info, "Parsing completed."); } catch (Exception ex) { // BUG: causes cross-AppDomain problem // this._parsedExpressions.OnError(ex); this.Log(LogEntry.Error, "Failed to parse: " + ex); } try { expressions .Select(e => e.Evaluate(this._symbols) .If( o => o is IEnumerable && !o.GetType().Let(t => t.IsMarshalByRef || t.IsSerializable), o => ((IEnumerable)o).Cast <Object>().Remotable() ) ) .ForEach(this.NotifyReturned); this._returnValues.OnCompleted(); this.Log(LogEntry.Info, "Evaluation completed."); } catch (Exception ex) { this._returnValues.OnError(ex); this.Log(LogEntry.Error, "Failed to evaluate: " + ex); } }
public Object EvaluateWithoutContext(IEnumerable <Char> code, params Object[] args) { return(YacqServices.Parse(this.Symbols, code).Evaluate(null, args)); }
private static Int32 Main() { if (_args.Contains("debug")) { Debugger.Launch(); } if (_args.Contains("help")) { Console.WriteLine("Usage: {0} [switches] [--] [inputs]", Path.GetFileNameWithoutExtension(Environment.GetCommandLineArgs()[0])); Console.WriteLine( String.Join(Environment.NewLine, _options .SelectMany(o => new [] { " " + String.Join(", ", o.ShortNames .Select(n => "-" + n) .Concat(o.LongNames.Select(n => "--" + n)) ), " " + o.Description, } )) ); return(0); } if (_args.Contains("version")) { Console.WriteLine( #region String @"YACQ <http://yacq.net/> Yet Another Compilable Query Language, based on Expression Trees API Language service is provided by Yacq.dll, the assembly name is: {0} YACQ Runner (YACQRun) is part of YACQ Runner and Compiler of YACQ Copyright © 2011-2013 Takeshi KIRIYA (aka takeshik) <*****@*****.**> All rights reserved. YACQ and YACQ Runner are Free Software; licensed under the MIT License." #endregion , typeof(YacqServices).Assembly.FullName ); return(0); } var input = Read(); if (_args.Contains("compile")) { Compile( input, _args["_param"] .FirstOrDefault(p => p != "-") .Null(p => Path.GetFileNameWithoutExtension(p)) ?? "a.out", _args.Contains("winexe") ? PEFileKinds.WindowApplication : _args.Contains("library") ? PEFileKinds.Dll : PEFileKinds.ConsoleApplication ); } else { var ret = 0; var expression = Parse(null, input); if (!_args.Contains("parse")) { try { Expression.Lambda(expression) .Evaluate() .If(o => o is Int32, o => ret = (Int32)o); } catch (Exception ex) { Fail(ex, Phase.Evaluate); } } if (_args.Contains("dump-tree")) { Console.Error.WriteLine(YacqServices.SaveText(expression)); } return(ret); } return(0); }
/// <summary> /// Converts the string representation of a symbol entry to an equivalent <see cref="SymbolEntry"/> object. /// </summary> /// <param name="expression">An expression string that contains a symbol entry to convert.</param> /// <param name="symbols">The symbol table for the expression.</param> /// <param name="isLiteral"><c>true</c> if the symbol entry indicates a literal; otherwise, <c>false</c>.</param> /// <returns>An object that is equivalent to the symbol entry specified in the <paramref name="expression"/> parameter.</returns> public static SymbolEntry Parse(String expression, SymbolTable symbols, Boolean isLiteral) { return(Parse(YacqServices.Read(expression), symbols, isLiteral)); }
private void textBox_PreviewKeyDown(object sender, KeyEventArgs e) { switch (e.Key) { case Key.Up: var previous = this.historyPos != null ? this.historyPos.Previous : this.history.Last; if (previous != null) { var lines = this.textBox.Text.Split('\n'); lines[lines.Length - 1] = ">>> " + previous.Value; this.textBox.Text = string.Join("\n", lines); this.textBox.Select(this.textBox.Text.Length, 0); this.historyPos = previous; } e.Handled = true; break; case Key.Down: if (this.historyPos != null && this.historyPos.Next != null) { this.historyPos = this.historyPos.Next; var lines = this.textBox.Text.Split('\n'); lines[lines.Length - 1] = ">>> " + this.historyPos.Value; this.textBox.Text = string.Join("\n", lines); this.textBox.Select(this.textBox.Text.Length, 0); } e.Handled = true; break; case Key.Left: case Key.Back: e.Handled = this.textBox.SelectionStart <= (this.textBox.Text .Split('\n') .Select(s => s.Length + 1) .Reverse() .Skip(1) .Sum() + ">>> ".Length); break; case Key.Enter: var code = this.textBox.Text.Split('\n').Last().Substring(">>> ".Length); if (!string.IsNullOrWhiteSpace(code)) { this.history.AddLast(code); if (this.historyPos != null && this.historyPos.Value != code) { this.historyPos = null; } this.textBox.AppendText("\r\n"); try { var exp = YacqExpression.Lambda( YacqServices.Parse(this.symbolTable, code) ); var ret = exp.Compile().DynamicInvoke(); if (ret == null) { this.textBox.AppendText("null"); } else if (ret is IEnumerable && !(ret is String)) { var sb = new StringBuilder("[ "); var data = ((IEnumerable)ret) .Cast <Object>() .Select(_ => (_ ?? "(null)").ToString()) .Take(Symbols.ReplDumpLimit + 1) .ToArray(); if (data.Any(s => s.Length > 40)) { sb.Append("\n"); sb.Append(String.Join( "\n", data.Take(Symbols.ReplDumpLimit) .Select(s => " " + s) )); sb.Append(data.Length > Symbols.ReplDumpLimit ? " (more...)\n]" : "\n]" ); } else { sb.Append(String.Join(" ", data.Take(Symbols.ReplDumpLimit))); sb.Append(data.Length > Symbols.ReplDumpLimit ? " (more...) ]" : " ]" ); } this.textBox.AppendText(sb.ToString()); } else { this.textBox.AppendText(ret.ToString()); } } catch (Exception ex) { this.textBox.AppendText(ex.GetType().Name + ":" + ex); } } this.textBox.AppendText("\r\n>>> "); this.textBox.Select(this.textBox.Text.Length, 0); e.Handled = true; break; default: if ( e.KeyboardDevice.Modifiers == ModifierKeys.None || e.KeyboardDevice.Modifiers == ModifierKeys.Shift || e.KeyboardDevice.Modifiers == ModifierKeys.Control && (e.Key == Key.V || e.Key == Key.X || e.Key == Key.Back || e.Key == Key.Delete) ) { var inputStartPos = this.textBox.Text .Split('\n') .Select(s => s.Length + 1) .Reverse() .Skip(1) .Sum() + ">>> ".Length; if (this.textBox.SelectionStart < inputStartPos) { this.textBox.Select(this.textBox.Text.Length, 0); } } break; } }