private bool ReadFunctionDecl(StringReader p, ref CodeBlock block) { FunctionCode funcRead; if (ReadFunctionBody(p, true, out funcRead)) { AddCode(ref block, funcRead, true); return true; } return false; }
private void Expect(StringReader p, bool truth, string msg = "expected") { if (!truth) throw new Exception(msg + "\n" + p.RestOf); }
private void ReqVal(StringReader p, out ExprPiece val) { if (!ReadValue(p, out val)) throw new Exception("value expected" + "\n" + p.RestOf); }
private bool ReadValueItem(StringReader p, List<object> mixture) { ExprPiece vaux; OperationExpr op; // valor simples, unario+valor+unario if (ReadSimpleValue(p, out vaux)) mixture.Add(vaux); else if (ReadUnaryPreOp(p, out op)) { mixture.Add(op); Expect(p, ReadSimpleValue(p, out vaux), "simple"); mixture.Add(vaux); } else return false; if (ReadUnaryPosOp(p, out op)) mixture.Add(op); return true; }
private bool ReadVar(StringReader p, ref CodeBlock block) { if (p.ThisWord("var")) { ANOTHER: var jsvar = new VarCode(); Expect(p, ReadIdent(p, out jsvar.Name), "var name"); if (p.ThisText("=")) ReqVal(p, out jsvar.Value); AddCode(ref block, jsvar); if (p.ThisText(",")) goto ANOTHER; return true; } return false; }
private bool ReadTry(StringReader p, ref CodeBlock block) { if (p.ThisWord("try")) { var jstry = new TryCode(); ReqText(p, "{"); ReadCodes(p, ref jstry.Code); ReqText(p, "}"); int catchCount = 0; int finallyCount = 0; if (p.ThisWord("catch")) { ReqText(p, "("); ReadIdent(p, out jstry.CatchName); ReqText(p, ")"); ReqText(p, "{"); ReadCodes(p, ref jstry.Catch); ReqText(p, "}"); catchCount++; } if (p.ThisWord("finally")) { ReqText(p, "{"); ReadCodes(p, ref jstry.Finally); ReqText(p, "}"); finallyCount++; } Expect(p, catchCount > 0 || finallyCount > 0, "catch/finally"); AddCode(ref block, jstry); return true; } return false; }
private bool ReadUnaryPreOp(StringReader p, out OperationExpr op) { op = null; int i; if (p.ThisText(new[] { "++", "--", "+", "-", "!", "~" }, out i)) { if (i == 0) op = new PreIncExpr(); else if (i == 1) op = new PreDecExpr(); else if (i == 2) op = new PlusExpr(); else if (i == 3) op = new NegExpr(); else if (i == 4) op = new BoolNotExpr(); else if (i == 5) op = new BitNotExpr(); } return op != null; }
private bool ReadNamedValue(StringReader p, out ExprPiece value) { string aux; if (ReadIdent(p, out aux)) { value = new NamedExpr { Name = aux }; return true; } value = null; return false; }
private bool ReadNewValue(StringReader p, out ExprPiece value) { if (p.ThisWord("new")) { ExprPiece creator; Expect(p, ReadNamedValue(p, out creator) || ReadFloatValue(p, out creator) || ReadStringValue(p, out creator) || ReadParensValue(p, out creator) || ReadArrayValue(p, out creator) || ReadObjectValue(p, out creator), "new arg"); while (ReadMemberValue(p, ref creator)) if (creator is ParamsExpr) break; value = new NewExpr { Creator = creator }; return true; } value = null; return false; }
private bool ReadIndexMember(StringReader p, ref ExprPiece value) { if (p.ThisText("[")) { var index = new IndexExpr(); index.Array = value; ReqVal(p, out index.Index); ReqText(p, "]"); value = index; return true; } return false; }
private bool ReadMemberValue(StringReader p, ref ExprPiece value) { return ReadDotMember(p, ref value) || ReadIndexMember(p, ref value) || ReadParamsMember(p, ref value); }
private bool ReadIf(StringReader p, ref CodeBlock block) { if (p.ThisWord("if")) { var jsif = new IfCode(); ReqText(p, "("); ReqVal(p, out jsif.Condition); ReqText(p, ")"); ReadCode(p, ref jsif.Then); if (p.ThisWord("else")) ReadCode(p, ref jsif.Else); AddCode(ref block, jsif); return true; } return false; }
private bool ReadIdent(StringReader p, out string ident) { var saved = p.Position; string wordRead; if (p.AnyWord(out wordRead)) { var isRw = ReservedWords.Any(w => w == wordRead); if (!isRw) { ident = wordRead; return true; } p.Position = saved; } ident = null; return false; }
private bool ReadFunctionValue(StringReader p, out ExprPiece value) { FunctionCode funcRead; if (ReadFunctionBody(p, false, out funcRead) || ReadClosure(p, out funcRead)) { value = new ClosureExpr { Function = funcRead }; return true; } value = null; return false; }
private bool ReadSwitch(StringReader p, ref CodeBlock block) { if (p.ThisWord("switch")) { var jsswitch = new SwitchCode(); ReqText(p, "("); ReqVal(p, out jsswitch.Arg); ReqText(p, ")"); ReqText(p, "{"); while (ReadCase(p, jsswitch)) ; if (p.ThisWord("default")) { ReqText(p, ":"); ReadCodes(p, ref jsswitch.Default); } ReqText(p, "}"); AddCode(ref block, jsswitch); return true; } return false; }
private bool ReadObjectValue(StringReader p, out ExprPiece value) { if (p.ThisText("{")) { var obj = new ObjectExpr(); while (ReadValuePair(p, obj)) if (!p.ThisText(",")) break; ReqText(p, "}"); value = obj; return true; } value = null; return false; }
private bool ReadSymbolValue(StringReader p, out ExprPiece value) { int wordRead; if (p.ThisWord(new[] { "null", "true", "false" }, out wordRead)) switch (wordRead) { case 0: value = new LiteralConst { Literal = null }; return true; case 1: value = new LiteralConst { Literal = true }; return true; case 2: value = new LiteralConst { Literal = false }; return true; } value = null; return false; }
private bool ReadParamsExpr(StringReader p, out ParamsExpr value) { if (p.ThisText("(")) { var list = new List<ExprPiece>(); ExprPiece paramRead; while (ReadValue(p, out paramRead)) { list.Add(paramRead); if (!p.ThisText(",")) break; } ReqText(p, ")"); value = new ParamsExpr { Params = list.ToArray() }; return true; } value = null; return false; }
private bool ReadUnaryPosOp(StringReader p, out OperationExpr op) { op = null; int i; if (p.ThisText(new[] { "++", "--" }, out i)) switch (i) { case 0: op = new PosIncExpr(); break; case 1: op = new PosDecExpr(); break; } return op != null; }
private bool ReadParamsMember(StringReader p, ref ExprPiece value) { ParamsExpr param; if (ReadParamsExpr(p, out param)) { param.FuncExpr = value; value = param; return true; } return false; }
private bool ReadValue(StringReader p, out ExprPiece value) { OperationExpr op; var mixture = new List<object>(); if (!ReadValueItem(p, mixture)) { value = null; return false; } while (ReadBinaryOp(p, out op)) { mixture.Add(op); Expect(p, ReadValueItem(p, mixture), "mix item"); } value = SplitOperands(mixture, 0, mixture.Count); return true; }
private bool ReadParensValue(StringReader p, out ExprPiece value) { if (p.ThisText("(")) { var parens = new ParensExpr(); ReadValue(p, out parens.InnerExpr); ReqText(p, ")"); value = parens; return true; } value = null; return false; }
private bool ReadValuePair(StringReader p, ObjectExpr obj) { var saved = p.Position; string pairName; if (ReadIdent(p, out pairName) || p.AnyQuoted(out pairName)) { if (p.ThisText(":")) { ExprPiece pairValue; ReqVal(p, out pairValue); (obj.Pairs ?? (obj.Pairs = new Dictionary<string, ExprPiece>())).Add(pairName, pairValue); return true; } p.Position = saved; } return false; }
private bool ReadReturn(StringReader p, ref CodeBlock block) { if (p.ThisWord("return")) { var jsret = new ReturnCode(); ReadValue(p, out jsret.Arg); AddCode(ref block, jsret); return true; } return false; }
private bool ReadWhile(StringReader p, ref CodeBlock block) { if (p.ThisWord("while")) { var jswhile = new WhileCode(); ReqText(p, "("); ReqVal(p, out jswhile.Condition); ReqText(p, ")"); ReadCode(p, ref jswhile.Code); AddCode(ref block, jswhile); return true; } return false; }
private bool ReadSimpleValue(StringReader p, out ExprPiece value) { if (ReadFunctionValue(p, out value) || ReadSymbolValue(p, out value) || ReadNewValue(p, out value) || ReadNamedValue(p, out value) || ReadFloatValue(p, out value) || ReadStringValue(p, out value) || ReadParensValue(p, out value) || ReadArrayValue(p, out value) || ReadObjectValue(p, out value)) { while (ReadMemberValue(p, ref value)) ; return true; } value = null; return false; }
private void ReqText(StringReader p, string text) { if (!p.ThisText(text)) throw new Exception("expected '" + text + "'" + "\n" + p.RestOf); }
private bool ReadStringValue(StringReader p, out ExprPiece value) { string s; if (p.AnyQuoted(out s)) { value = new LiteralConst { Literal = s }; return true; } value = null; return false; }
private bool ReadArrayValue(StringReader p, out ExprPiece value) { if (p.ThisText("[")) { var list = new List<ExprPiece>(); ExprPiece item; while (ReadValue(p, out item)) { list.Add(item); if (!p.ThisText(",")) break; } ReqText(p, "]"); value = new ArrayExpr { Items = list.ToArray() }; return true; } value = null; return false; }
private bool ReadFunctionBody(StringReader p, bool reqName, out FunctionCode func) { var saved = p.Position; if (p.ThisWord("function")) { var jsfn = new FunctionCode(); // esse Reader pode ser chamado para declaracao de funcoes ou para expressoes de funcoes anonimas // reqName diferencia esses dois usos, um tem nome o outro nao // ex.: function X(){} ou function(){} if (reqName) Expect(p, ReadIdent(p, out jsfn.Name), "func name"); ReqText(p, "("); var plist = new List<string>(); string pn; while (ReadIdent(p, out pn)) { plist.Add(pn); if (!p.ThisText(",")) break; } jsfn.Params = plist.Count > 0 ? plist.ToArray() : null; ReqText(p, ")"); ReqText(p, "{"); ReadCodes(p, ref jsfn.Code); ReqText(p, "}"); func = jsfn; return true; } func = null; return false; }