private bool checkAll(ReferenceExpression node){ if(node.ToCodeString()=="@__"){ var list = new HashLiteralExpression(); foreach (var namedarg in namedargs){ list.Items.Add( new ExpressionPair( namedarg.Key.toLiteral(), namedarg.Value.CloneNode() )); } node.ParentNode.Replace(node, list); return true; } return false; }
private bool checkSubstitution(ReferenceExpression node) { Match m = Regex.Match(node.ToCodeString(), @"^@_([\d\w]+?)(_)?$", RegexOptions.Compiled); if (m.Success){ int idx = 0; var isordered = int.TryParse(m.Groups[1].Value, out idx); bool accomodate_to_strings = m.Groups[2].Value != ""; Expression exp = new NullLiteralExpression(); if (isordered){ idx = idx - 1; if (idx < args.Count){ exp = args[idx]; } }else{ var name = m.Groups[1].Value; if(namedargs.ContainsKey(name)){ exp = namedargs[name]; } } if (accomodate_to_strings && (exp is ReferenceExpression)) { if (exp.ToCodeString().StartsWith("@")) { exp = new ReferenceExpression(exp.ToCodeString().Substring(1)); } else { exp = new StringLiteralExpression(exp.ToCodeString()); } } node.ParentNode.Replace(node, exp); return true; } return false; }
protected override Statement ExpandImpl(MacroStatement macro){ if (macro.Arguments.Count == 0){ throw new Exception("need at least one IEnumerable parameter"); } var result = new Block(); Expression src = macro.Arguments[0]; var idx = new ReferenceExpression("_idx"); Expression item = new ReferenceExpression("i"); var col = new ReferenceExpression("current_collection"); if (src is BinaryExpression){ item = ((BinaryExpression) src).Left; src = ((BinaryExpression) src).Right; } if (macro.Arguments.Count > 1){ idx = (ReferenceExpression) macro.Arguments[1]; } string prefix = macro.get<string>("_prefix") ?? ""; string suffix = macro.get<string>("_suffix") ?? ""; Func<string, MacroStatement> findmacro = s =>{ var r = macro.get<Node>(s); if (null == r){ return null; } if (!(r is MacroStatement)){ var m = new MacroStatement("stub"); m.Body = new Block().add(r); r = m; } return (MacroStatement) r; }; Func<MacroStatement, Block> extract = m =>{ if (null == m){ return null; } if (m.Body != null && !m.Body.IsEmpty){ if (m.Body.Statements.Count == 1){ if (m.Body.Statements[0] is ExpressionStatement){ Expression _ex = ((ExpressionStatement) m.Body.Statements[0]). Expression; if (_ex is LiteralExpression || !_ex.ToCodeString().ToLower().StartsWith("out")){ return new Block().add(_ex.writeOut()); } } } return m.Body; } if (m.Arguments.Count == 0){ return null; } var r = new Block(); if (!(m.Arguments[0] is MethodInvocationExpression)){ r.Add(BrailBuildingHelper.WriteOut(m.Arguments[0])); } else{ r.Add(m.Arguments[0]); } return r; }; MacroStatement beforeall_macro = findmacro("beforeall"); MacroStatement onitem_macro = findmacro("onitem") ?? macro; MacroStatement onerror_macro = findmacro("onerror"); ; MacroStatement between_macro = findmacro("between"); ; MacroStatement afterall_macro = findmacro("afterall"); ; MacroStatement onempty_macro = findmacro("onempty"); ; MacroStatement beforeeach_macro = findmacro("beforeeach"); ; MacroStatement aftereach_macro = findmacro("aftereach"); MacroStatement prepare_macro = findmacro("prepare"); ; Block beforeall = extract(beforeall_macro); Block onitem = extractMainItemBlock(macro, extract, onitem_macro, item, prefix, suffix); Block onerror = extract(onerror_macro); Block between = extract(between_macro); Block afterall = extract(afterall_macro); Block onempty = null; bool proceed_on_empty = false; if (onempty_macro != null && onempty_macro.Arguments.Count != 0 && onempty_macro.Arguments[0].ToCodeString() == "proceed"){ proceed_on_empty = true; } else{ onempty = extract(onempty_macro); } Block beforeeach = extract(beforeeach_macro); Block aftereach = extract(aftereach_macro); // _idx = 0 Statement betweener = getBetweener(idx, between); result.Add(col.assign(new MethodInvocationExpression(new ReferenceExpression("_wrapcollection"), src))); result.Add(new ReferenceExpression("___proceed").assign(new BoolLiteralExpression(proceed_on_empty))); var mainblock = new Block(); mainblock.Add(idx.assign(0)); mainblock.Add(new IfStatement( new BinaryExpression(BinaryOperatorType.Equality, new NullLiteralExpression(), col), new Block().add(new BinaryExpression(BinaryOperatorType.Assign, col, new MethodInvocationExpression( new ReferenceExpression("_wrapcollection"), new ArrayLiteralExpression()))), null )); if (beforeall != null){ mainblock.Add(beforeall); } var maincycle = new ForStatement(); maincycle.Iterator = col; string declname = item.ToCodeString(); TypeReference decltype = null; if (item is TryCastExpression){ declname = ((TryCastExpression) item).Target.ToCodeString(); decltype = ((TryCastExpression) item).Type; } maincycle.Declarations.Add(new Declaration(maincycle.LexicalInfo, declname, decltype)); maincycle.Block = new Block(); maincycle.ThenBlock = afterall; if (betweener != null){ maincycle.Block.Add(betweener); } if (null != prepare_macro){ maincycle.Block.Add(prepare_macro.Body); } if (null != beforeeach){ maincycle.Block.Add(beforeeach); } if (onerror == null){ maincycle.Block.Add(onitem); } else{ var trycatch = new TryStatement(); var exchandler = new ExceptionHandler(); exchandler.Block = onerror; exchandler.Declaration = new Declaration("_ex", new SimpleTypeReference("System.Exception")); trycatch.ProtectedBlock = onitem; trycatch.ExceptionHandlers.Add(exchandler); maincycle.Block.Add(trycatch); } if (null != aftereach){ maincycle.Block.Add(aftereach); } maincycle.Block.Add(new UnaryExpression(UnaryOperatorType.Increment, idx)); mainblock.Add(maincycle); result.Add( new IfStatement( getMainCondition(col), mainblock, onempty ) ); // if null!=items and (items as IEnumerable).Cast[of System.Object]().Count() != 0: return result; }