public override DLR.Expression Generate(AplusScope scope) { DLR.Expression result; if (this.indexExpression != null) { // Generate each indexer expression in reverse order // the reverse order is to mimic the A+ evaulation order IEnumerable <DLR.Expression> indexerValues = this.indexExpression.Items.Reverse().Select( item => { return(item.Generate(scope)); } ); DLR.ParameterExpression indexerParam = DLR.Expression.Parameter(typeof(List <AType>), "__INDEX__"); result = DLR.Expression.Block( new DLR.ParameterExpression[] { indexerParam }, DLR.Expression.Assign( indexerParam, DLR.Expression.Call( typeof(Helpers).GetMethod("BuildIndexerArray"), DLR.Expression.NewArrayInit(typeof(AType), indexerValues) ) ), DLR.Expression.Dynamic( scope.GetRuntime().GetIndexBinder(new DYN.CallInfo(indexerValues.Count())), typeof(object), this.item.Generate(scope), indexerParam ) ); } else { // in case of: a[]; result = DLR.Expression.Dynamic( scope.GetRuntime().GetIndexBinder(new DYN.CallInfo(0)), typeof(object), this.item.Generate(scope), DLR.Expression.Constant(null) ); } return(result.To <AType>()); }
public DLR.Expression <System.Func <Runtime.Aplus, AType> > ParseToLambda(string code) { AplusScope scope = new AplusScope(null, "__top__", this.aplus, DLR.Expression.Parameter(typeof(Aplus), "__aplusRuntime__"), DLR.Expression.Parameter(typeof(DYN.IDynamicMetaObjectProvider), "__module__") ); FunctionInformation funcionInfo = new FunctionInformation(this.aplus.CurrentContext); if (this.aplus.Context != null) { funcionInfo.LoadInfo((this.aplus.Context as Scope).Storage as ScopeStorage); } DLR.Expression codebody = null; AST.Node tree = Compiler.Parse.String(code, this.aplus.LexerMode, funcionInfo); if (tree == null) { codebody = DLR.Expression.Constant(null); } else { codebody = DLR.Expression.Block( new DLR.ParameterExpression[] { scope.ModuleExpression }, DLR.Expression.Assign( scope.ModuleExpression, DLR.Expression.PropertyOrField(scope.RuntimeExpression, "Context") ), tree.Generate(scope) ); } DLR.Expression <System.Func <Aplus, AType> > method = DLR.Expression.Lambda <Func <Aplus, AType> >( codebody, scope.RuntimeExpression ); return(method); }
public override DLR.Expression Generate(AplusScope scope) { Aplus runtime = scope.GetRuntime(); // Default result LinkedList <DLR.Expression> codeBlock = new LinkedList <DLR.Expression>(); codeBlock.AddLast(DLR.Expression.Constant(Utils.ANull())); switch (this.command) { case "$off": Environment.Exit(0); break; case "$laod": // Compatibility with original A+ interpreter case "$load": IDictionary <string, AType> items = runtime.ContextLoader.FindContextElements(this.argument); if (items.Count > 0) { foreach (KeyValuePair <string, AType> item in items) { codeBlock.AddFirst( VariableHelper.SetVariable( runtime, scope.GetModuleExpression(), new string[] { this.argument, item.Key }, DLR.Expression.Constant(item.Value) ) ); } } else { string path = Util.GetPath(runtime, ASymbol.Create(this.argument), ".a+"); if (File.Exists(path)) { // TODO: Save working directory and restore. // Save the previous context. string previousContext = runtime.CurrentContext; // Create the AST from file // TODO: fix the third function info argument Node fileAST = Parse.LoadFile(path, runtime.LexerMode, null); // And generate the DLR tree codeBlock.AddFirst(fileAST.Generate(scope)); // Restore the previous context runtime.CurrentContext = previousContext; } else { codeBlock.Clear(); codeBlock.AddFirst( DLR.Expression.Constant(Helpers.BuildString(String.Format("Invalid file: {0}", this.argument))) ); } } break; case "$mode": if (this.argument != null) { codeBlock.AddFirst( DLR.Expression.Call( scope.RuntimeExpression, typeof(Aplus).GetMethod("SwitchLexerMode"), DLR.Expression.Constant(this.argument) ) ); } else { codeBlock.Clear(); codeBlock.AddFirst(DLR.Expression.Constant(Runtime.Helpers.BuildString(runtime.LexerMode.ToString()))); } break; case "$cx": if (this.argument != null) { runtime.CurrentContext = this.argument; } else { codeBlock.Clear(); codeBlock.AddFirst( DLR.Expression.Call( typeof(Runtime.Helpers).GetMethod("BuildString"), DLR.Expression.Property(scope.RuntimeExpression, "CurrentContext") ) ); } break; case "$cxs": codeBlock.Clear(); codeBlock.AddFirst( DLR.Expression.Call( typeof(Runtime.SystemCommands).GetMethod("PrintContexts"), scope.GetModuleExpression() ) ); break; case "$pp": int precision = -1; if (this.argument != null && int.TryParse(this.argument, out precision) && precision >= 0) { runtime.SystemVariables["pp"] = AInteger.Create(precision); } else { codeBlock.Clear(); codeBlock.AddFirst(DLR.Expression.Constant(runtime.SystemVariables["pp"])); } break; case "$stop": if (this.argument != null) { int stopNumber; if (!int.TryParse(this.argument, out stopNumber) || stopNumber > 2 || stopNumber < 0) { stopNumber = 0; } runtime.SystemVariables["stop"] = AInteger.Create(stopNumber); } else { string resultText; switch (runtime.SystemVariables["stop"].asInteger) { default: case 0: resultText = "0 off"; break; case 1: resultText = "1 on [warning]"; break; case 2: resultText = "2 trace"; break; } codeBlock.Clear(); codeBlock.AddFirst(DLR.Expression.Constant(Helpers.BuildString(resultText))); } break; default: if (this.command.StartsWith("$>")) { string variable = this.command.Substring(2); if (this.argument == null || this.argument.Length == 0 || variable.Length == 0) { Console.WriteLine("incorrect"); } else { codeBlock.AddFirst( DLR.Expression.Call( typeof(SystemCommands).GetMethod("WriteToFile"), DLR.Expression.Constant(runtime), DLR.Expression.Constant(variable), DLR.Expression.Constant(this.argument) ) ); } } else { Console.WriteLine("Unknown system command: {0} {1}", this.command, this.argument); } break; } DLR.Expression result = DLR.Expression.Block(codeBlock); return(result); }
public override DLR.Expression Generate(AplusScope scope) { Aplus runtime = scope.GetRuntime(); // arguments for the dynamic method call LinkedList <DLR.Expression> callArguments = new LinkedList <DLR.Expression>(); if (scope.IsAssignment) { // Generate the paramters differently for assignment // f{...;x} := value <=> i := f{...; iota rho x}; (,x)[i] := value List <Node> items = new List <Node>(this.arguments.Items); // 2. Add the parameters in !reverse! order except the last one for (int i = 0; i < items.Count - 1; i++) { callArguments.AddFirst(items[i].Generate(scope)); } Node lastItem = items[items.Count - 1]; bool isPick = Node.TestDyadicToken(lastItem, Grammar.Tokens.PICK); bool isRavel = Node.TestMonadicToken(lastItem, Grammar.Tokens.RAVEL); if (!(lastItem is Identifier || isPick || isRavel)) { throw new ParseException("user-def invoke assign", false); } DLR.Expression indexList = AST.Assign.BuildIndicesList(scope, lastItem.Generate(scope)); callArguments.AddFirst(indexList); } else { // 2. Add the parameters in !reverse! order foreach (Node item in this.arguments.Items) { callArguments.AddFirst(item.Generate(scope)); } } // 0. Add A+ environment as first argument for user defined functions callArguments.AddFirst(scope.GetRuntimeExpression()); // 1. Construct the method body callArguments.AddFirst(this.method.Generate(scope)); DLR.Expression result; if (scope.IsAssignment) { // (,x)[f{...;iota rho x}] result = AST.Assign.BuildIndexing( scope, this.arguments.Items.Last.Value.Generate(scope), BuildInvoke(runtime, callArguments) ); } else { // 3. Dynamic invoke of method // Order of arguments: // (method, Enviroment, argN, ... arg1, arg0) result = BuildInvoke(runtime, callArguments); } return(result); }