public static void BuildStatementList(Grammar g, string patternName, Pattern statementBlock, Pattern statementNonBlock, Pattern optionalEdition) { g.AddPattern(patternName, seq( rep(alt(p("ws"), p("statementSeps")), 0, -1), p("optLabelMarker"), rep(alt(p("ws"), p("statementSeps")), 0, -1), alt( seq( n("statement", statementBlock), opt(seq( alt( seq( lb("}"), t("\n"), opt(p("statementSeps"))), p("statementSeps")), optionalEdition))), seq( n("statement", statementNonBlock), opt(seq( alt( seq( t("\n"), opt(p("statementSeps"))), p("statementSeps")), optionalEdition.Regen(g))))), rep(alt(p("ws"), p("statementSeps")), 0, -1) )); }
public static void BuildRoutineDeclaration(Grammar g, string patternName, Pattern prefix, Pattern terminator) { g.AddPattern(patternName, seq( prefix, r(terminator, (Grammar gr) => { // descend into new subroutine-class Exec methodgen var c = gr.CodeGen; c.InvokeAssign(c["temp_typegen01"], c["GG"], "DescendIntoSub", c["AG"], c["current_typegen"], c["TG_top"], c["current_scope"], c["IN"], c["m"]["subName"], c["m"]["returnType"], c["m"]["subParams"]); c.InvokeAssign(c["cg"], c["GG"], "DescendIntoSub", c["cg"], c["current_typegen"], c["temp_typegen01"]); c.Assign(c["current_typegen"], c["temp_typegen01"]); c.Assign(c["current_scope"], c["current_typegen"].Field("FrameScope")); }), ows(), r(n("bodyStatements", p("statementListBlock")), (Grammar gr) => { var c = gr.CodeGen; c.If(c["cg"].Invoke("IsReachable")); { c.Increment(c["cg"].Field("InstructionCount")); c.Invoke(c["cg"], "Assign", c["cg"].Invoke("This").Invoke("Field", "Instruction"), c["cg"].Field("InstructionCount")); c.Invoke(c["cg"], "Label", "inst" + c["cg"].Field("InstructionCount").Invoke("ToString")); } c.End(); c.Invoke(c["cg"], "Goto", "csmeta_return_label"); c.Invoke(c["cg"], "Label", "inst0"); // at program-runtime, we've re-entered this frame from a child invocation (or // from a continuance of a continuation), so jump to the label (the CIL instruction) // corresponding to the saved instruction pointer (ends up JITted as a direct jump-table). c.Invoke(c["cg"], "Switch", c["cg"].Invoke("This").Invoke("Field", "Instruction"), c["GG"].Invoke("GetRoutineInstructionLabels", c["cg"])); //c.If(c["cg"].Invoke("IsReachable")); //{ c.Invoke(c["cg"], "Label", "csmeta_return_label"); c.Invoke(c["TG_top"].Field("FrameGen"), "RevertContextualsIn", c["current_scope"], c["cg"]); c.Invoke(c["cg"], "Return", c["cg"].Invoke("This").Invoke("Field", "Caller")); //} //c.End(); c.Assign(c["last_typegen"], c["current_typegen"]); c.Invoke(c["cg"], "Complete"); c.InvokeAssign(c["current_typegen"], c["GG"], "AscendOutofSub", c["last_typegen"]); c.InvokeAssign(c["cg"], c["GG"], "AscendOutofSub", 1); c.Assign(c["current_scope"], c["current_scope"].Field("Parent").Cast(typeof(FrameScope))); c.Invoke(c["cg"], "AssignNew", c["cg"].Invoke("This").Invoke("Field", c["last_typegen"].Field("NamedSubMangledName")), c["last_typegen"], c["cg"].Invoke("This")); c.Assign(c["m"].Field("Result"), c["cg"].Invoke("This").Invoke("Field", c["last_typegen"].Field("NamedSubMangledName"))); //c.WriteLine("finished declaring a sub"); }) )); }
public static void BuildExpressions(Grammar g, ref int counter, string expressionName, string termName, string termishName) { var Counter = counter; g.AddPattern("postTerm", n("postTerm", seq(n("term", p(termName)), alt( r(seq( t("."), n("methodName", p("varname")), t("("), n("args", opt(p("argsList"))), t(")") ), (Grammar gr) => { var c = gr.CodeGen; var match = c["m"]; c.Assign(c["OpArray"], c["GG"].Invoke("BindArgs", 1, c["m"]["args"])); c.If(c["IN"].Invoke("Match", match["methodName"]) == "new"); { c.InvokeAssign(match.Field("Parent").Cast(typeof(Match)).Field("Result"), typeof(Exp), "New", match["term"].Field("Result").Property("Type"), c["OpArray"]); } c.Else(); { c.Assign(match.Field("Parent").Cast(typeof(Match)).Field("Result"), match["term"].Field("Result").Invoke("InvokeOverride", c["IN"].Invoke("Match", match["methodName"]), c["OpArray"])); } c.End(); }), r(seq( t("."), n("fieldName", p("varname")) ), (Grammar gr) => { var c = gr.CodeGen; var match = c["m"]; c.If(c["IN"].Invoke("Match", match["methodName"]) == "new"); { c.InvokeAssign(match.Field("Parent").Cast(typeof(Match)).Field("Result"), typeof(Exp), "New", match["term"].Field("Result").Property("Type")); } c.Else(); { c.Try(); { c.Assign(match.Field("Parent").Cast(typeof(Match)).Field("Result"), match["term"].Field("Result").Invoke("Field", c["IN"].Invoke("Match", match["fieldName"]))); } c.CatchAll(); { c.Assign(match.Field("Parent").Cast(typeof(Match)).Field("Result"), match["term"].Field("Result").Invoke("Property", c["IN"].Invoke("Match", match["fieldName"]))); } c.End(); } c.End(); }), r(seq(t("["), ows(), n("indexer", p(expressionName)), ows(), t("]")), (Grammar gr) => { var c = gr.CodeGen; var match = c["m"]; //c.Assign(c["OpArray"], Exp.NewArray(typeof(Operand), 1)); //c.Assign(c["OpArray"][0], match["indexer"].Field("Result")); c.InvokeAssign(match.Field("Parent").Cast(typeof(Match)).Field("Result"), match["term"].Field("Result"), "ApplyIndexer", match["indexer"].Field("Result")); }), r(empty(), (Grammar gr) => { var c = gr.CodeGen; var match = c["m"]; c.Assign(match.Field("Parent").Cast(typeof(Match)).Field("Result"), match["term"].Field("Result")); }) )))); g.AddPattern(expressionName, r(n("InfixExpression", seq( ows(), r( n("NewLeftOperand", p("postTerm")) , (Grammar gr) => { var c = gr.CodeGen; c.Assign(c["m"].Field("Result"), c["m"]["NewLeftOperand"].Field("Result")); }) , opt( seq( ows(), n("InfixOp", new InfixOp()), ows(), n("RightOperand", p("postTerm")), r(empty(), (Grammar gr) => { var c = g.CodeGen; var s = c["s"]; var o = c["o"]; var m = c["m"]; var endmarker = "ReduceInfix" + Counter++; var found = c["IN"].Invoke("Match", m["InfixOp"]); var left = m["NewLeftOperand"]; var right = m["RightOperand"]; //c.WriteLine("dispatching left " + c["IN"].Invoke("Match", left) + ": " + left.Field("Start") + " to " + left.Field("End") + " " + left.Field("Name")); c.GotoFalse(right.IsInstanceOf(typeof(object)), endmarker); //c.WriteLine("dispatching right " + c["IN"].Invoke("Match", right) + ": " + right.Field("Start") + " to " + right.Field("End") + " " + right.Field("Name")); c.GotoFalse(found.IsInstanceOf(typeof(object)), endmarker); c.Switch(found); foreach (var target in g.InfixOperators.Keys) { var op = g.InfixOperators[target]; if (op.ReduceActionGen != null) { c.Case(target); //c.WriteLine("dispatching infix<" + target + ">"); op.ReduceActionGen(g, target, left, right); } } c.End(); c.Label(endmarker); }))) )), (Grammar gr) => { var c = gr.CodeGen; c.Assign(c["m"].Field("Result"), c["m"]["InfixExpression"].Field("Result")); //c.WriteLine("type of expression at " + c["o"] + " : "); //c.Try(); //c.WriteLine(c["m"].Field("Result").Invoke("GetType")); //c.CatchAll(); //c.End(); })) ; g.AddPattern(termishName, alt( seq(new PrefixOp(), p(expressionName)), //p("statementListBlock"), new CircumfixOp(p(expressionName)), r(p("ScalarRef"), (Grammar gr) => { var c = gr.CodeGen; var match = c["m"]; var varname = c["IN"].Invoke("Match", match["Scalar"]); c.If(c["current_scope"].Invoke("ContainsKey", varname).LogicalNot()); { //c.WriteLine(c["current_scope"].Invoke("KeysString")); c.Throw(Exp.New(typeof(Exception), "usage of undeclared variable " + varname + " at offset " + c["o"])); } c.End(); c.If(c["current_scope"][varname].Field("Scope").Field("Typegen").Invoke("GetName").EQ((c["current_typegen"]).Invoke("GetName"))); { c.Assign(match.Field("Result"), c["cg"].Invoke("This").Invoke("Field", c["current_scope"][varname].Field("MangledName"))); } c.Else(); { c.Assign(match.Field("Result"), c["cg"].Invoke("This").Invoke("Field", c["current_scope"][varname].Field("Scope").Field("Typegen").Field("FrameGen").Invoke("GetName")).Invoke("Field", c["current_scope"][varname].Field("MangledName"))); } c.End(); }), r(p("ContextualRef"), (Grammar gr) => { var c = gr.CodeGen; var match = c["m"]; var varname = c["IN"].Invoke("Match", match["Scalar"]); c.InvokeAssign(c["s01"], c["TG_top"], "GetMangledContextual", c["current_typegen"], c["current_scope"], c["root_scope"], varname); c.If(c["current_typegen"].Invoke("GetName") == "TopLevelFrame"); { c.Assign(match.Field("Result"), c["cg"].Invoke("This").Invoke("Field", "_ctxl_" + c["s01"])); } c.Else(); { c.Assign(match.Field("Result"), c["cg"].Invoke("This").Invoke("Field", "TopLevelFrame").Invoke("Field", "_ctxl_" + c["s01"])); } c.End(); }), p("stringLiteral"), p("decimalIntLiteral"), p("frameKeyword"), p("selfKeyword"), p("staticInvocation"), p("subDeclaration"), p("typeLiteral") )); g.AddPattern("typeLiteral", r(n("literalTypeName", p("typeName")), (Grammar gr) => { var c = gr.CodeGen; c.Assign(c["m"].Field("Result"), c["m"]["literalTypeName"].Field("Result")); })); g.AddPattern(termName, finished(alt( seq(t("("), ows(), r(n("InnerExpr", p(expressionName)), (Grammar gr) => { var c = gr.CodeGen; c.Assign(c["m"].Field("Result"), c["m"]["InnerExpr"].Field("Result")); }), ows(), t(")")), p("subInvocation"), p(termishName) ))); g.AddPattern("staticInvocation", n("invocation", r(seq( n("typeName", p("typeName")), t("."), n("methodName", p("varname")), t("("), n("args", opt(p("argsList"))), t(")") ), (Grammar gr) => { var c = gr.CodeGen; var match = c["m"]; c.Assign(c["type1"], match["typeName"].Field("Result").Cast(typeof(TypeLiteral)).Property("ConstantValue").Cast(typeof(Type))); //c.WriteLine(c["IN"].Invoke("Match", match["NamespaceAndClass"]) + " resolved to " + c["type1"]); c.If(c["IN"].Invoke("Match", match["methodName"]) == "new"); { c.InvokeAssign(match.Field("Parent").Cast(typeof(Match)).Field("Result"), typeof(Exp), "New", c["type1"], c["GG"].Invoke("BindArgs", 1, c["m"]["args"])); } c.Else(); { //c.WriteLine("static method name is " + c["IN"].Invoke("Match", match["methodName"])); c.Assign(match.Field("Parent").Cast(typeof(Match)).Field("Result"), c["cg"].Invoke("InvokeStatic", c["type1"], c["IN"].Invoke("Match", match["methodName"]), 1, c["GG"].Invoke("BindArgs", 1, c["m"]["args"]))); /*c.If(match.Field("Parent").Cast(typeof(Match)).Field("Result").Property("Type").Invoke("Equals", typeof(void))); * { * c.Invoke(match.Field("Parent").Cast(typeof(Match)).Field("Result"), "ForceEmit", c["cg"]); * } * c.Else(); * { * c.Assign(c["operand01"], c["cg"][c["GG"].Invoke("GetNextEphemeral"), match.Field("Parent").Cast(typeof(Match)).Field("Result").Property("Type")]); * c.Invoke(c["cg"], "Assign", c["cg"][c["GG"].Invoke("GetLastEphemeral")], c["m"].Field("Result")); * } * c.End();*/ } c.End(); }))); g.AddPattern("subInvocation", r(n("invocation", r(seq( n("subName", alt(p("varname"), p("ScalarRef"))), t("("), n("args", p("argsList")), t(")") ), (Grammar gr) => { var c = gr.CodeGen; var match = c["m"]["invocation"]; var varname = c["IN"].Invoke("Match", match["subName"]); c.Assign(c["OpArray"], c["GG"].Invoke("BindArgs", c["cg"], c["m"]["args"])); // increment the instruction count at parse time. c.Increment(c["cg"].Field("InstructionCount")); //c.Invoke(c["cg"], "Assign", c["cg"].Invoke("This").Invoke("Field", "Instruction"), -1); // using that unique instruction count, record a program-runtime assignment to this frame instance's instruction pointer slot. c.Invoke(c["cg"], "Assign", c["cg"].Invoke("This").Invoke("Field", "Instruction"), c["cg"].Field("InstructionCount")); c.If(!c["current_scope"].Invoke("ContainsKey", varname)); { c.Throw(Exp.New(typeof(InvalidOperationException), varname + " has not been declared.")); } c.End(); c.If(c["current_scope"][varname].Field("Invokable").LogicalNot()); { c.Throw(Exp.New(typeof(InvalidOperationException), varname + " is not invokable")); } c.End(); //c.WriteLine("looking up " + c["current_scope"][varname].Field("Type").Property("Name")); c.Assign(c["temp_typegen01"], c["GG"].Field("ClassesByName")[c["current_scope"][varname].Field("Type").Property("Name")]); // parse-time, store the return type of this invokable in a type variable named type1 c.If(!c["GG"].Field("ReturnTypesByInterface").Invoke("ContainsKey", c["current_scope"][varname].Field("Type").Property("Name"))); { c.Assign(c["type1"], c["GG"].Field("ReturnTypesByInterface")[c["temp_typegen01"].Field("IntGen").Invoke("GetName")]); } c.Else(); { //c.WriteLine("found a return type for: " + c["current_scope"][varname].Field("TypeGen").Invoke("GetName")); c.Assign(c["type1"], c["GG"].Field("ReturnTypesByInterface")[c["temp_typegen01"].Invoke("GetName")]); //c.WriteLine("return type: " + c["type1"]); } c.End(); // create a slot in this frame for the callsite's return value c.InvokeAssign(c["temp_fieldgen01"], c["current_typegen"].Field("FrameGen"), "PublicField", c["type1"], "_csmeta_callsite_returnslot_" + c["cg"].Field("InstructionCount")); c.Invoke(c["current_typegen"].Field("FrameGen").Field("CloneGen"), "Assign", c["current_typegen"].Field("FrameGen").Field("CloneGen")["clone"].Invoke("Field", "_csmeta_callsite_returnslot_" + c["cg"].Field("InstructionCount")), c["current_typegen"].Field("FrameGen").Field("CloneGen").Invoke("This").Invoke("Field", "_csmeta_callsite_returnslot_" + c["cg"].Field("InstructionCount"))); c.If(c["current_scope"][varname].Field("Scope").Field("Typegen").Invoke("GetName").EQ((c["current_typegen"]).Invoke("GetName"))); { c.Invoke(c["cg"], "InvokeAssign", c["cg"]["next_frame"], c["cg"].Invoke("This").Invoke("Field", c["current_scope"][varname].Field("MangledName")) /*.Invoke("Cast", c["current_scope"][varname].Field("TypeGen").Field("IntGen"))*/, "Bind", c["OpArray"]); } c.Else(); { //c.WriteLine(c["current_scope"][varname].Field("Scope").Field("Typegen").Invoke("GetName")); c.Invoke(c["cg"], "InvokeAssign", c["cg"]["next_frame"], c["cg"].Invoke("This").Invoke("Field", c["current_scope"][varname].Field("Scope").Field("Typegen").Field("FrameGen").Invoke("GetName")).Invoke("Field", c["current_scope"][varname].Field("MangledName")) /*.Invoke("Cast", c["current_scope"][varname].Field("TypeGen").Field("IntGen"))*/, "Bind", c["OpArray"]); //c.Invoke(c["cg"], "InvokeAssign", c["cg"]["next_frame"], c["cg"].Invoke("This").Invoke("Field", c["current_scope"][varname].Field("Scope").Field("Typegen").Invoke("GetName")).Invoke("Field", c["current_scope"][varname].Field("MangledName"))/*.Invoke("Cast", c["current_scope"][varname].Field("TypeGen").Field("IntGen"))*/, "Bind", c["OpArray"]); } c.End(); c.Invoke(c["cg"], "Assign", c["cg"].Invoke("This").Invoke("Field", "Callee"), c["cg"]["next_frame"]); c.Invoke(c["cg"], "Return", c["cg"]["next_frame"]); c.Assign(c["type1"], c["GG"].Invoke("ResolveReturnType", c["type1"])); c.Invoke(c["cg"], "Label", "inst" + c["cg"].Field("InstructionCount").Invoke("ToString")); //c.WriteLine("return intgen: " + c["type1"]); c.Invoke(c["cg"], "Assign", c["cg"].Invoke("This").Invoke("Field", "_csmeta_callsite_returnslot_" + c["cg"].Field("InstructionCount")), c["cg"].Invoke("This").Invoke("Field", "Callee").Invoke("Cast", c["type1"]).Invoke("Invoke", "GetReturnValue")); c.Assign(match.Field("Result"), c["cg"].Invoke("This").Invoke("Field", "_csmeta_callsite_returnslot_" + c["cg"].Field("InstructionCount"))); })), (Grammar gr) => { var c = gr.CodeGen; c.Assign(c["m"].Field("Result"), c["m"]["invocation"].Field("Result")); })); g.AddPattern("argsList", n("argsList", seq( ows(), opt(seq( n("nextArg", p(expressionName)), opt(seq( ows(), t(","), p("argsList"))) )), ows() ))); g.AddPattern("paramsList", n("paramsList", seq( ows(), opt(seq( n("nextParam", p("param")), opt(seq( ows(), t(","), p("paramsList"))) )), ows() ))); g.AddPattern("param", seq( n("myTypeName", p("typeName")), p("ws"), n("myVarName", p("ScalarRef")) )); counter = Counter; }
public static void BuildTerminals(Grammar g, ref int counter, string expressionName, string termName, string termishName) { var Counter = counter; g.AddPattern("varname", finished(rep(alt(t("_"), new RangeChar((uint)'A', (uint)'Z'), new RangeChar((uint)'a', (uint)'z'), new RangeChar((uint)'0', (uint)'9')), 1, -1))); g.AddPattern("typeName", alt( finished(r(seq( t("Callable["), ows(), t(":"), ows(), t("("), ows(), n("typeParamsList", p("typeParamsList")), ows(), t("-->"), ows(), n("returnType", p("typeName")), ows(), t(")"), ows(), t("]") ), (Grammar gr) => { var c = gr.CodeGen; var match = c["m"]; c.Assign(match.Field("Result"), c["GG"].Invoke("ResolveClosureType", c["AG"], match)); })), r(seq( n("parametricTypeName", p("NamespaceAndClass")), opt(seq( t("["), n("typeParamsList", p("typeParamsList")), t("]") )) ), (Grammar gr) => { var c = gr.CodeGen; var match = c["m"]; c.Try(); { c.InvokeAssign(match.Field("Result"), c["GG"], "ResolveParametricType", c["AG"], c["IN"].Invoke("Match", match["parametricTypeName"]), match); } c.CatchAll(); { c.Assign(c["assertion"], false); } c.Finally(); c.End(); //c.WriteLine(match.Field("Result").Property("ConstantValue")); }), new Assert()) ); g.AddPattern("typeParamsList", finished(seq( ows(), opt(seq( n("nextTypeParam", p("typeName")), opt(seq( ows(), t(","), n("typeParamsList", p("typeParamsList")))) )), ows() ))); //g.AddPattern("typeNameList", BuildCommaList(p("typeName"), "typeNameList")); g.AddPattern("ScalarRef", n("Scalar", seq(t("$"), n("JustTheVarName", p("varname"))))); g.AddPattern("ArrayRef", n("Scalar", seq(t("@"), p("varname")))); g.AddPattern("ContextualRef", n("Scalar", seq(t("$*"), p("varname")))); g.AddPattern("decimalIntLiteral", finished(r(n("digits", seq(opt(t("-")), new RangeChar((uint)'0', (uint)'9'), opt(rep(alt(t("_"), new RangeChar((uint)'0', (uint)'9')), 1, -1)))), (Grammar gr) => { var c = gr.CodeGen; var match = c["m"]; var value = c["IN"].Invoke("Match", match["digits"]); c.InvokeAssign(c["i3"], typeof(Int32), "Parse", value.Invoke("Replace", "_", "")); c.Assign(match.Field("Result"), Exp.New(typeof(TriAxis.RunSharp.Operands.IntLiteral), typeof(int), c["i3"])); })) ); g.AddPattern("stringLiteral", finished(alt( r(seq(t("'"), n("strLit", rep(alt(seq(new Not(t("'")), new Not(t("\\'")), new AnyChar()), t("\\'")), 1, -1)), t("'")), (Grammar gr) => { var c = gr.CodeGen; var match = c["m"]; c.Assign(match.Field("Result"), Exp.New(typeof(StringLiteral), c["IN"].Invoke("Match", match["strLit"]).Invoke("Replace", "\\'", "'"))); }), r(seq(t("\""), n("strLit", rep(alt(seq(new Not(t("\"")), new Not(t("\\\"")), new AnyChar()), t("\\\"")), 1, -1)), t("\"")), (Grammar gr) => { var c = gr.CodeGen; var match = c["m"]; c.Assign(match.Field("Result"), Exp.New(typeof(StringLiteral), c["IN"].Invoke("Match", match["strLit"]).Invoke("Replace", "\\\"", "\""))); }) ))); g.AddPattern("NamespaceAndClass", finished(seq( p("varname"), opt(seq(t("::"), p("NamespaceAndClass")))))); g.AddPattern("ws", finished(rep( alt( t(" "), t("\t"), r(alt(t(new String(new char[] { (char)13, (char)10 })), t(new String(new char[] { (char)10 })), t("\r"), t("\n")), (Grammar gr) => { var c = gr.CodeGen; c.If(c["o"] > c["last_position"]); { //c.WriteLine("passing line " + c["last_line"] + " at " + c["o"] + " with " + c["i"][c["o"] - 1] + " and " + c["i"][c["o"]]); c.Increment(c["last_line"]); c["last_position"] = c["o"]; } c.End(); }), seq( t("#"), rep(seq(new Not(t(new String(new char[] { (char)13, (char)10 }))), new Not(t(new String(new char[] { (char)10 }))), new Not(t("\r")), new Not(t("\n")), new AnyChar()), 0, -1) ) ), 1, -1 ))); g.AddPattern("statementSeps", finished(seq( ows(), t(";"), opt(p("statementSeps")) ))); g.AddPattern("frameKeyword", r(seq(t("_cc") /*, new Lookahead(t(","))*/), (Grammar gr) => { var c = gr.CodeGen; c.Assign(c["m"].Field("Result"), c["cg"].Invoke("This")); })); g.AddPattern("selfKeyword", r(seq(t("self"), new Not(p("varname"))), (Grammar gr) => { var c = gr.CodeGen; c.Assign(c["m"].Field("Result"), c["cg"].Invoke("This").Invoke("Field", "__csmeta_invocant")); })); counter = Counter; }
public static void BuildDeclarations(Grammar g, ref int counter, string expressionName, string termName, string termishName) { var Counter = counter; g.AddPattern("myDeclaration", seq(r(seq( t("my"), p("ws"), opt(seq(n("myTypeName", p("typeName")), p("ws"))), n("myVarName", p("ScalarRef")), ows() //,d("found a my declaration") ), (Grammar gr) => { var c = gr.CodeGen; var varname = c["IN"].Invoke("Match", c["m"]["myVarName"]); var typename = c["IN"].Invoke("Match", c["m"]["myTypeName"]); c.Try(); { c.If(c["m"]["myTypeName"].Field("Success").LogicalAnd(c["m"]["myTypeName"].Field("Result").IsNotNull())); { c.If(c["m"]["myTypeName"].Field("Result").IsNotNull().LogicalAnd(c["m"]["myTypeName"].Field("Result").Cast(typeof(TypeLiteral)).IsNotNull())); { c.Assign(c["type1"], c["m"]["myTypeName"].Field("Result").Cast(typeof(TypeLiteral)).Property("ConstantValue")); } c.Else(); { c.InvokeAssign(c["type1"], c["GG"], "ResolveType", typename); } c.End(); //c.WriteLine(c["type1"]); c.Invoke(c["current_scope"], "AddHere", varname, Exp.New(typeof(FrameLocal), varname, c["type1"], c["current_scope"])); c.If(c["m"]["myTypeName"].Field("Result").IsNotNull().LogicalAnd(c["m"]["myTypeName"].Field("Result").Cast(typeof(TypeLiteral)).IsNotNull()).LogicalAnd(c["m"]["myTypeName"].Field("Result").Cast(typeof(TypeLiteral)).Property("ConstantValue").Cast(typeof(Type)).Property("Name").Invoke("StartsWith", "_IClosure"))); { c.Assign(c["current_scope"][varname].Field("Invokable"), true); } c.End(); c.InvokeAssign(c["temp_fieldgen01"], c["current_typegen"].Field("FrameGen"), "PublicField", c["type1"], c["current_scope"][varname].Field("MangledName")); c.Invoke(c["current_typegen"].Field("FrameGen").Field("CloneGen"), "Assign", c["current_typegen"].Field("FrameGen").Field("CloneGen")["clone"].Invoke("Field", c["current_scope"][varname].Field("MangledName")), c["current_typegen"].Field("FrameGen").Field("CloneGen").Invoke("This").Invoke("Field", c["current_scope"][varname].Field("MangledName"))); } c.End(); } c.CatchAll(); { c.Assign(c["assertion"], false); //c.Throw(Exp.New(typeof(Exception), "parse failure; got to line " + c["last_line"] + ", or incorrect redeclaration of " + varname + " at offset " + c["o"])); } c.End(); //c.WriteLine("declared " + varname + " of type " + typename + " at " + c["o"]); }), new Assert(), alt(r(seq( t("="), ows(), n("myInitializer", p(expressionName)) //,d("found an initializer") ), (Grammar gr) => { var c = gr.CodeGen; var varname = c["IN"].Invoke("Match", c["m"]["myVarName"]); c.If(c["current_scope"].Invoke("HasOwnKey", varname).LogicalNot()); { c.Assign(c["type1"], c["m"]["myInitializer"].Field("Result").Property("Type")); c.If(c["type1"].Property("Name").Invoke("StartsWith", "_Closure")); { c.Assign(c["type1"], c["GG"].Field("ClosuresByName")[c["type1"].Property("Name")].Field("IntGen")); } c.End(); c.Invoke(c["current_scope"], "AddHere", varname, Exp.New(typeof(FrameLocal), varname, c["type1"], c["current_scope"])); //c.WriteLine("declared local with initializer of type " + c["type1"].Property("FullName")); c.If(c["type1"].Property("Name").Invoke("StartsWith", "_IClosure")); { c.Assign(c["current_scope"][varname].Field("TypeGen"), c["GG"].Field("ClosuresByName")[c["type1"].Property("Name")]); //c.WriteLine("gave " + varname + " the typegen " + c["GG"].Field("ClosuresByName")[c["type1"].Property("Name")]); c.Assign(c["current_scope"][varname].Field("TypeGen").Field("IntGen"), c["GG"].Field("ClosuresByName")[c["type1"].Property("Name")]); c.Assign(c["current_scope"][varname].Field("Invokable"), true); } c.End(); c.InvokeAssign(c["temp_fieldgen01"], c["current_typegen"].Field("FrameGen"), "PublicField", c["type1"], c["current_scope"][varname].Field("MangledName")); c.Invoke(c["current_typegen"].Field("FrameGen").Field("CloneGen"), "Assign", c["current_typegen"].Field("FrameGen").Field("CloneGen")["clone"].Invoke("Field", c["current_scope"][varname].Field("MangledName")), c["current_typegen"].Field("FrameGen").Field("CloneGen").Invoke("This").Invoke("Field", c["current_scope"][varname].Field("MangledName"))); } c.Else(); { c.If(c["type1"].Property("Name").Invoke("StartsWith", "_Closure").LogicalOr(c["type1"].Property("Name").Invoke("StartsWith", "_IClosure"))); { c.Assign(c["current_scope"][varname].Field("Invokable"), true); } c.End(); } c.End(); c.Invoke(c["cg"], "Assign", c["cg"].Invoke("This").Invoke("Field", c["current_scope"][varname].Field("MangledName")), c["m"]["myInitializer"].Field("Result")); c.Assign(c["m"].Field("Result"), c["cg"].Invoke("This").Invoke("Field", c["current_scope"][varname].Field("MangledName"))); }), r(empty(), (Grammar gr) => { var c = gr.CodeGen; var varname = c["IN"].Invoke("Match", c["m"]["myVarName"]); c.If(c["m"]["myTypeName"].Field("Success").LogicalNot()); { c.Throw(Exp.New(typeof(Exception), "To declare " + varname + " without an explicit type annotation, provide an initializer at offset " + c["o"])); } c.End(); })))); g.AddPattern("contextualAssignment", seq(r(seq( t("my"), p("ws"), //opt(seq(n("myTypeName", p("varname")), p("ws"))), n("myVarName", p("ContextualRef")), ows(), t("="), ows(), n("myInitializer", p(expressionName)) ), (Grammar gr) => { var c = gr.CodeGen; var varname = c["IN"].Invoke("Match", c["m"]["myVarName"]); var value = c["m"]["myInitializer"].Field("Result"); // get the toplevel's slot for this contextual c.InvokeAssign(c["s01"], c["TG_top"], "GetMangledContextual", c["current_typegen"], c["current_scope"], c["root_scope"], value.Property("Type"), varname); var mangled_name = c["s01"]; c.If(c["current_typegen"].Invoke("GetName") == "TopLevelFrame"); { // if at runtime the program hasn't already pushed a new contextual in the current lexical scope, c.Invoke(c["cg"], "If", c["cg"].Invoke("This").Invoke("Field", "_assigned_" + c["current_scope"].Field("ID") + "_" + mangled_name).Invoke("EQ", 0)); { c.Assign(c["OpArray"], Exp.NewArray(typeof(Operand), 1)); c.Assign(c["OpArray"][0], c["cg"].Invoke("This").Invoke("Field", "_ctxl_" + mangled_name)); // push a copy of the current contextual value onto its reversion stack, c.Invoke(c["cg"], "Invoke", c["cg"].Invoke("This").Invoke("Field", "_stack_" + mangled_name), "Push", c["OpArray"]); // assign the current contextual value to the toplevel frame's slot for this contextual, c.Invoke(c["cg"], "Assign", c["cg"].Invoke("This").Invoke("Field", "_ctxl_" + mangled_name), value); // and mark that the program pushed a value to this contextual in the current lexical scope; c.Invoke(c["cg"], "Assign", c["cg"].Invoke("This").Invoke("Field", "_assigned_" + c["current_scope"].Field("ID") + "_" + mangled_name), 1); } c.Invoke(c["cg"], "Else"); { // otherwise, just assign to the contextual's global slot again c.Invoke(c["cg"], "Assign", c["cg"].Invoke("This").Invoke("Field", "_ctxl_" + mangled_name), value); } c.Invoke(c["cg"], "End"); } c.Else(); { // if at runtime the program hasn't already pushed a new contextual in the current lexical scope, c.Invoke(c["cg"], "If", c["cg"].Invoke("This").Invoke("Field", "_assigned_" + c["current_scope"].Field("ID") + "_" + mangled_name).Invoke("EQ", 0)); { c.Assign(c["OpArray"], Exp.NewArray(typeof(Operand), 1)); c.Assign(c["OpArray"][0], c["cg"].Invoke("This").Invoke("Field", "TopLevelFrame").Invoke("Field", "_ctxl_" + mangled_name)); // push a copy of the current contextual value onto its reversion stack, c.Invoke(c["cg"], "Invoke", c["cg"].Invoke("This").Invoke("Field", "TopLevelFrame").Invoke("Field", "_stack_" + mangled_name), "Push", c["OpArray"]); // assign the current contextual value to the toplevel frame's slot for this contextual, c.Invoke(c["cg"], "Assign", c["cg"].Invoke("This").Invoke("Field", "TopLevelFrame").Invoke("Field", "_ctxl_" + mangled_name), value); // and mark that the program pushed a value to this contextual in the current lexical scope; c.Invoke(c["cg"], "Assign", c["cg"].Invoke("This").Invoke("Field", "_assigned_" + c["current_scope"].Field("ID") + "_" + mangled_name), 1); } c.Invoke(c["cg"], "Else"); { // otherwise, just assign to the contextual's global slot again c.Invoke(c["cg"], "Assign", c["cg"].Invoke("This").Invoke("Field", "TopLevelFrame").Invoke("Field", "_ctxl_" + mangled_name), value); } c.Invoke(c["cg"], "End"); } c.End(); }))); g.AddPattern("fieldDeclaration", r(seq( t("has"), p("ws"), n("fieldType", p("typeName")), p("ws"), p("ScalarRef") ), (Grammar gr) => { var c = gr.CodeGen; var match = c["m"]; var fieldType = match["fieldType"].Field("Result").Cast(typeof(TypeLiteral)).Property("ConstantValue").Cast(typeof(Type)); var varname = c["IN"].Invoke("Match", match["Scalar"]["JustTheVarName"]); c.Invoke(c["current_classgen"], "PublicField", fieldType, varname); })); g.AddPattern("classPreDeclaration", seq( t("class"), p("ws"), n("className", p("NamespaceAndClass")), ows(), r(new Lookahead(seq(t("{"), ows(), t("..."))), (Grammar gr) => { var c = gr.CodeGen; var match = c["m"]; var className = c["IN"].Invoke("Match", match["className"]); c.If(c["GG"].Field("ClassesByName").Invoke("ContainsKey", className)); { c.Throw(Exp.New(typeof(InvalidOperationException), "already predeclared class with name " + className)); } c.End(); c.Assign(c["current_classgen"], c["AG"].Property("Public").Invoke("Class", className)); c.Invoke(c["GG"].Field("ClassesByName"), "Add", className, c["current_classgen"]); //c.WriteLine("Predeclared class " + className); c.Assign(c["current_scope"], Exp.New(typeof(FrameScope), c["current_typegen"], c["current_scope"])); }), ows(), r(n("bodyStatements", p("classStatementListBlock")), (Grammar gr) => { var c = gr.CodeGen; var match = c["m"]; c.Assign(match.Field("Result"), Exp.New(typeof(TypeLiteral), c["current_classgen"])); c.Assign(c["current_scope"], c["current_scope"].Field("Parent").Cast(typeof(FrameScope))); c.Assign(c["current_classgen"], c["TG_top"]); }) )); g.AddPattern("classDeclaration", seq( t("class"), p("ws"), n("className", p("NamespaceAndClass")), opt(seq(p("ws"), t("is"), p("ws"), n("parentType", p("typeName")))), r(ows(), (Grammar gr) => { var c = gr.CodeGen; var match = c["m"]; var className = c["IN"].Invoke("Match", match["className"]); c.If(c["GG"].Field("ClassesByName").Invoke("ContainsKey", className)); { c.Assign(c["current_classgen"], c["GG"].Field("ClassesByName")[className]); } c.Else(); { c.If(match.Invoke("HasOwnKey", "parentType")); { c.Assign(c["current_classgen"], c["AG"].Property("Public").Invoke("Class", className, c["GG"].Invoke("ResolveParametricType", c["AG"], c["IN"].Invoke("Match", match["parentType"]), match).Cast(typeof(TypeLiteral)).Field("t"))); } c.Else(); { c.Assign(c["current_classgen"], c["AG"].Property("Public").Invoke("Class", className)); } c.End(); c.Invoke(c["GG"].Field("ClassesByName"), "Add", className, c["current_classgen"]); } c.End(); c.Assign(c["current_scope"], Exp.New(typeof(FrameScope), c["current_typegen"], c["current_scope"])); }), ows(), r(n("bodyStatements", p("classStatementListBlock")), (Grammar gr) => { var c = gr.CodeGen; var match = c["m"]; c.Assign(match.Field("Result"), Exp.New(typeof(TypeLiteral), c["current_classgen"])); c.Assign(c["current_scope"], c["current_scope"].Field("Parent").Cast(typeof(FrameScope))); }) )); BuildRoutineDeclaration(g, "subDeclaration", seq(t("sub"), p("ws"), opt(seq(n("subName", p("varname")), ows())), t("("), n("subParams", p("paramsList")), t("-->"), ows(), n("returnType", p("typeName")), ows()), t(")")); g.AddPattern("methodDeclaration", seq( t("method"), p("ws"), opt(seq(n("subName", p("varname")), ows())), t("("), n("subParams", p("paramsList")), opt(seq(t("-->"), ows(), n("returnType", p("typeName")))), ows(), r(t(")"), (Grammar gr) => { // descend into new subroutine-class Exec methodgen var c = gr.CodeGen; c.InvokeAssign(c["temp_typegen01"], c["GG"], "DescendIntoMethod", c["AG"], c["current_typegen"], c["TG_top"], c["current_scope"], c["IN"], c["m"]["subName"], c["m"]["returnType"], c["m"]["subParams"], c["current_classgen"]); c.InvokeAssign(c["cg"], c["GG"], "DescendIntoSub", c["cg"], c["current_typegen"], c["temp_typegen01"]); c.Assign(c["current_typegen"], c["temp_typegen01"]); c.Assign(c["current_scope"], c["current_typegen"].Field("FrameScope")); }), ows(), r(n("bodyStatements", p("statementListBlock")), (Grammar gr) => { var c = gr.CodeGen; c.If(c["cg"].Invoke("IsReachable")); { c.Increment(c["cg"].Field("InstructionCount")); c.Invoke(c["cg"], "Assign", c["cg"].Invoke("This").Invoke("Field", "Instruction"), c["cg"].Field("InstructionCount")); c.Invoke(c["cg"], "Label", "inst" + c["cg"].Field("InstructionCount").Invoke("ToString")); } c.End(); c.Invoke(c["cg"], "Goto", "csmeta_return_label"); c.Invoke(c["cg"], "Label", "inst0"); // at program-runtime, we've re-entered this frame from a child invocation (or // from a continuance of a continuation), so jump to the label (the CIL instruction) // corresponding to the saved instruction pointer (ends up JITted as a direct jump-table). c.Invoke(c["cg"], "Switch", c["cg"].Invoke("This").Invoke("Field", "Instruction"), c["GG"].Invoke("GetRoutineInstructionLabels", c["cg"])); //c.If(c["cg"].Invoke("IsReachable")); //{ c.Invoke(c["cg"], "Label", "csmeta_return_label"); c.Invoke(c["TG_top"].Field("FrameGen"), "RevertContextualsIn", c["current_scope"], c["cg"]); c.Invoke(c["cg"], "Return", c["cg"].Invoke("This").Invoke("Field", "Caller")); //} //c.End(); c.Assign(c["last_typegen"], c["current_typegen"]); c.Invoke(c["cg"], "Complete"); c.InvokeAssign(c["current_typegen"], c["GG"], "AscendOutofSub", c["last_typegen"]); c.InvokeAssign(c["cg"], c["GG"], "AscendOutofSub", 1); c.Assign(c["current_scope"], c["current_scope"].Field("Parent").Cast(typeof(FrameScope))); c.Invoke(c["cg"], "AssignNew", c["cg"].Invoke("This").Invoke("Field", c["last_typegen"].Field("NamedSubMangledName")), c["last_typegen"], c["cg"].Invoke("This")); c.Assign(c["OpArray"], Exp.NewArray(typeof(Operand), 1)); c.Assign(c["OpArray"][0], c["cg"].Invoke("This").Invoke("Field", c["last_typegen"].Field("NamedSubMangledName"))); c.Invoke(c["cg"], "InvokeStatic", c["current_classgen"], "__csmeta_init_" + c["last_typegen"].Invoke("ToString"), c["OpArray"]); c.Assign(c["m"].Field("Result"), c["cg"].Invoke("This").Invoke("Field", c["last_typegen"].Field("NamedSubMangledName"))); }) )); counter = Counter; }
public static void BuildControlFlow(Grammar g, ref int counter, string expressionName, string termName, string termishName) { var Counter = counter; g.AddPattern("statement", finished(alt(p("statementBlock"), p("statementNonBlock")))); g.AddPattern("optStatementList", seq( opt(p("statementList")), alt( p("statementSeps"), p("ws"), empty() ) )); g.AddPattern("optClassStatementList", seq( opt(p("classStatementList")), alt( p("statementSeps"), p("ws"), empty() ) )); g.AddPattern("ifBlock", seq( t("if"), p("ws"), r( n("protasis", p(expressionName)), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["if_stack"], "Push", c["if_current"]); c.Increment(c["if_counter"]); c.Assign(c["if_current"], c["if_counter"]); c.Invoke(c["cg"], "If", c["m"]["protasis"].Field("Result")); c.Assign(c["current_scope"], Exp.New(typeof(FrameScope), c["current_typegen"], c["current_scope"])); }), ows(), r(p("statementListBlock"), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["TG_top"].Field("FrameGen"), "RevertContextualsIn", c["current_scope"], c["cg"]); c.Assign(c["current_scope"], c["current_scope"].Field("Parent").Cast(typeof(FrameScope))); c.Invoke(c["cg"], "Goto", "csmeta_endif_" + c["if_current"]); c.Invoke(c["cg"], "End"); }), ows(), r(alt( p("ElsifChain"), p("ElseBlock"), empty() ), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["cg"], "Label", "csmeta_endif_" + c["if_current"]); c.Assign(c["if_current"], c["if_stack"].Invoke("Pop")); }) )); g.AddPattern("whileBlock", seq( t("while"), p("ws"), r(n("protasis", p(expressionName)), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["if_stack"], "Push", c["if_current"]); c.Increment(c["if_counter"]); c.Assign(c["if_current"], c["if_counter"]); c.Invoke(c["cg"], "Label", "csmeta_begif_" + c["if_current"]); c.Invoke(c["cg"], "GotoFalse", c["m"]["protasis"].Field("Result"), "csmeta_endif_" + c["if_current"]); c.Invoke(c["cg"], "Assign", c["cg"].Invoke("This").Invoke("Field", "Instruction"), c["cg"].Field("InstructionCount")); c.Assign(c["current_scope"], Exp.New(typeof(FrameScope), c["current_typegen"], c["current_scope"])); }), ows(), r(p("statementListBlock"), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["TG_top"].Field("FrameGen"), "RevertLexicalsIn", c["current_scope"], c["cg"]); c.Invoke(c["TG_top"].Field("FrameGen"), "RevertContextualsIn", c["current_scope"], c["cg"]); c.Invoke(c["cg"], "Goto", "csmeta_begif_" + c["if_current"]); c.Invoke(c["cg"], "Label", "csmeta_endif_" + c["if_current"]); c.Assign(c["current_scope"], c["current_scope"].Field("Parent").Cast(typeof(FrameScope))); c.Assign(c["if_current"], c["if_stack"].Invoke("Pop")); }) )); g.AddPattern("repeatWhileStatement", seq( t("repeat"), p("ws"), r(new Lookahead(t("{")), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["loop_stack"], "Push", c["loop_current"]); c.Increment(c["loop_counter"]); c.Assign(c["loop_current"], c["loop_counter"]); var state_local = c["cg"].Invoke("This").Invoke("Field", c["current_scope"][c["loop_current"].Invoke("ToString") + "$$"].Field("MangledName")); c.Invoke(c["current_scope"], "AddHere", c["loop_current"].Invoke("ToString") + "$$", Exp.New(typeof(FrameLocal), c["loop_current"].Invoke("ToString") + "$$", typeof(int), c["current_scope"])); c.InvokeAssign(c["temp_fieldgen01"], c["current_typegen"].Field("FrameGen"), "PublicField", typeof(int), c["current_scope"][c["loop_current"].Invoke("ToString") + "$$"].Field("MangledName")); c.Invoke(c["cg"], "Assign", state_local, 1); c.Invoke(c["cg"], "While", state_local.Invoke("GE", 1)); c.Invoke(c["cg"], "If", state_local.Invoke("EQ", 1)); { c.Invoke(c["cg"], "Assign", state_local, 2); c.Invoke(c["cg"], "Goto", c["loop_current"] + "loop_start"); } c.Invoke(c["cg"], "End"); c.Invoke(c["cg"], "Goto", c["loop_current"] + "loop_test"); c.Invoke(c["cg"], "Label", c["loop_current"] + "loop_start"); c.Assign(c["current_scope"], Exp.New(typeof(FrameScope), c["current_typegen"], c["current_scope"])); }), r(p("statementListBlock"), (Grammar gr) => { var c = gr.CodeGen; c.Assign(c["last_scope"], c["current_scope"]); c.Assign(c["current_scope"], c["current_scope"].Field("Parent").Cast(typeof(FrameScope))); }), ows(), n("while_until", alt(t("while"), t("until"))), p("ws"), n("protasis", p(expressionName)), r(ows(), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["cg"], "Label", c["loop_current"] + "loop_test"); c.If(c["IN"].Invoke("Match", c["m"]["while_until"]) == "while"); { c.Invoke(c["cg"], "If", c["m"]["protasis"].Field("Result")); } c.Else(); { c.Invoke(c["cg"], "If", c["m"]["protasis"].Field("Result").Invoke("LogicalNot")); } c.End(); { c.Invoke(c["cg"], "Goto", c["loop_current"] + "loop_start"); } c.Invoke(c["cg"], "End"); c.Invoke(c["cg"], "Break"); c.Assign(c["loop_current"], c["loop_stack"].Invoke("Pop")); c.Invoke(c["cg"], "End"); c.Invoke(c["TG_top"].Field("FrameGen"), "RevertContextualsIn", c["last_scope"], c["cg"]); }) )); g.AddPattern("repeatWhileBlock", seq( t("repeat"), p("ws"), t("while"), p("ws"), r(n("protasis", p(expressionName)), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["loop_stack"], "Push", c["loop_current"]); c.Increment(c["loop_counter"]); c.Assign(c["loop_current"], c["loop_counter"]); var state_local = c["cg"].Invoke("This").Invoke("Field", c["current_scope"][c["loop_current"].Invoke("ToString") + "$$"].Field("MangledName")); c.Invoke(c["current_scope"], "AddHere", c["loop_current"].Invoke("ToString") + "$$", Exp.New(typeof(FrameLocal), c["loop_current"].Invoke("ToString") + "$$", typeof(int), c["current_scope"])); c.InvokeAssign(c["temp_fieldgen01"], c["current_typegen"].Field("FrameGen"), "PublicField", typeof(int), c["current_scope"][c["loop_current"].Invoke("ToString") + "$$"].Field("MangledName")); c.Invoke(c["cg"], "Assign", state_local, 1); c.Invoke(c["cg"], "While", state_local.Invoke("GE", 1)); c.Invoke(c["cg"], "If", state_local.Invoke("EQ", 1)); { c.Invoke(c["cg"], "Assign", state_local, 2); c.Invoke(c["cg"], "Goto", c["loop_current"] + "loop_start"); } c.Invoke(c["cg"], "End"); c.Invoke(c["cg"], "Goto", c["loop_current"] + "loop_test"); c.Invoke(c["cg"], "Label", c["loop_current"] + "loop_start"); c.Assign(c["current_scope"], Exp.New(typeof(FrameScope), c["current_typegen"], c["current_scope"])); }), ows(), r(p("statementListBlock"), (Grammar gr) => { var c = gr.CodeGen; c.Assign(c["current_scope"], c["current_scope"].Field("Parent").Cast(typeof(FrameScope))); c.Invoke(c["cg"], "Label", c["loop_current"] + "loop_test"); c.Invoke(c["cg"], "If", c["m"]["protasis"].Field("Result")); { c.Invoke(c["cg"], "Goto", c["loop_current"] + "loop_start"); } c.Invoke(c["cg"], "End"); c.Invoke(c["cg"], "Break"); c.Assign(c["loop_current"], c["loop_stack"].Invoke("Pop")); c.Invoke(c["cg"], "End"); }) )); g.AddPattern("repeatUntilBlock", seq( t("repeat"), p("ws"), t("until"), p("ws"), r(n("protasis", p(expressionName)), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["loop_stack"], "Push", c["loop_current"]); c.Increment(c["loop_counter"]); c.Assign(c["loop_current"], c["loop_counter"]); var state_local = c["cg"].Invoke("This").Invoke("Field", c["current_scope"][c["loop_current"].Invoke("ToString") + "$$"].Field("MangledName")); c.Invoke(c["current_scope"], "AddHere", c["loop_current"].Invoke("ToString") + "$$", Exp.New(typeof(FrameLocal), c["loop_current"].Invoke("ToString") + "$$", typeof(int), c["current_scope"])); c.InvokeAssign(c["temp_fieldgen01"], c["current_typegen"].Field("FrameGen"), "PublicField", typeof(int), c["current_scope"][c["loop_current"].Invoke("ToString") + "$$"].Field("MangledName")); c.Invoke(c["cg"], "Assign", state_local, 1); c.Invoke(c["cg"], "While", state_local.Invoke("GE", 1)); c.Invoke(c["cg"], "If", state_local.Invoke("EQ", 1)); { c.Invoke(c["cg"], "Assign", state_local, 2); c.Invoke(c["cg"], "Goto", c["loop_current"] + "loop_start"); } c.Invoke(c["cg"], "End"); c.Invoke(c["cg"], "Goto", c["loop_current"] + "loop_test"); c.Invoke(c["cg"], "Label", c["loop_current"] + "loop_start"); c.Assign(c["current_scope"], Exp.New(typeof(FrameScope), c["current_typegen"], c["current_scope"])); }), ows(), r(p("statementListBlock"), (Grammar gr) => { var c = gr.CodeGen; c.Assign(c["current_scope"], c["current_scope"].Field("Parent").Cast(typeof(FrameScope))); c.Invoke(c["cg"], "Label", c["loop_current"] + "loop_test"); c.Invoke(c["cg"], "If", c["m"]["protasis"].Field("Result")); { c.Invoke(c["cg"], "Break"); } c.Invoke(c["cg"], "End"); c.Invoke(c["cg"], "Goto", c["loop_current"] + "loop_start"); c.Assign(c["loop_current"], c["loop_stack"].Invoke("Pop")); c.Invoke(c["cg"], "End"); }) )); g.AddPattern("unlessBlock", seq( t("unless"), p("ws"), r( seq( t("("), ows(), n("protasis", p(expressionName)), ows(), t(")") ), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["if_stack"], "Push", c["if_current"]); c.Increment(c["if_counter"]); c.Assign(c["if_current"], c["if_counter"]); c.Invoke(c["cg"], "If", c["m"]["protasis"].Field("Result").Invoke("LogicalNot")); c.Assign(c["current_scope"], Exp.New(typeof(FrameScope), c["current_typegen"], c["current_scope"])); }), ows(), r(p("statementListBlock"), (Grammar gr) => { var c = gr.CodeGen; c.Assign(c["current_scope"], c["current_scope"].Field("Parent").Cast(typeof(FrameScope))); c.Invoke(c["cg"], "Goto", "csmeta_endif_" + c["if_counter"]); c.Invoke(c["cg"], "End"); }), ows(), r(alt( p("ElseBlock"), empty() ), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["cg"], "Label", "csmeta_endif_" + c["if_current"]); c.Assign(c["if_current"], c["if_stack"].Invoke("Pop")); }) )); g.AddPattern("untilBlock", seq( t("until"), p("ws"), r( seq( t("("), ows(), n("protasis", p(expressionName)), ows(), t(")") ), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["cg"], "While", c["m"]["protasis"].Field("Result").Invoke("LogicalNot")); c.Assign(c["current_scope"], Exp.New(typeof(FrameScope), c["current_typegen"], c["current_scope"])); }), ows(), r(p("statementListBlock"), (Grammar gr) => { var c = gr.CodeGen; c.Assign(c["current_scope"], c["current_scope"].Field("Parent").Cast(typeof(FrameScope))); c.Invoke(c["cg"], "End"); }) )); g.AddPattern("ElsifChain", seq(n("alternative", r(seq( ows(), t("elsif"), p("ws"), t("("), ows(), n("protasis", p(expressionName)), ows(), t(")") ), (Grammar gr) => { var c = gr.CodeGen; //c.Invoke(c["cg"], "Else"); c.Invoke(c["if_stack"], "Push", c["if_current"]); c.Increment(c["if_counter"]); c.Assign(c["if_current"], c["if_counter"]); c.Invoke(c["cg"], "If", c["m"]["protasis"].Field("Result")); c.Assign(c["current_scope"], Exp.New(typeof(FrameScope), c["current_typegen"], c["current_scope"])); })), ows(), r(p("statementListBlock"), (Grammar gr) => { var c = gr.CodeGen; c.Assign(c["current_scope"], c["current_scope"].Field("Parent").Cast(typeof(FrameScope))); c.Invoke(c["cg"], "Goto", "csmeta_endif_" + c["if_counter"]); c.Invoke(c["cg"], "End"); }), ows(), r(alt( p("ElsifChain"), p("ElseBlock"), empty() ), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["cg"], "Label", "csmeta_endif_" + c["if_current"]); c.Assign(c["if_current"], c["if_stack"].Invoke("Pop")); }))); g.AddPattern("ElseBlock", seq(n("alternative", r(seq( ows(), t("else"), ows() ), (Grammar gr) => { var c = gr.CodeGen; //c.Invoke(c["cg"], "Else"); c.Assign(c["current_scope"], Exp.New(typeof(FrameScope), c["current_typegen"], c["current_scope"])); })), ows(), r(p("statementListBlock"), (Grammar gr) => { var c = gr.CodeGen; c.Assign(c["current_scope"], c["current_scope"].Field("Parent").Cast(typeof(FrameScope))); }), ows() )); g.AddPattern("loopBlock", n("loopBlock", alt(seq( t("loop"), p("ws"), r(t("("), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["loop_stack"], "Push", c["loop_current"]); c.Increment(c["loop_counter"]); c.Assign(c["loop_current"], c["loop_counter"]); var state_local = c["cg"].Invoke("This").Invoke("Field", c["current_scope"][c["loop_current"].Invoke("ToString") + "$$"].Field("MangledName")); c.Invoke(c["current_scope"], "AddHere", c["loop_current"].Invoke("ToString") + "$$", Exp.New(typeof(FrameLocal), c["loop_current"].Invoke("ToString") + "$$", typeof(int), c["current_scope"])); c.InvokeAssign(c["temp_fieldgen01"], c["current_typegen"].Field("FrameGen"), "PublicField", typeof(int), c["current_scope"][c["loop_current"].Invoke("ToString") + "$$"].Field("MangledName")); c.Invoke(c["cg"], "Assign", state_local, 1); //c.Assign(c["current_scope"], Exp.New(typeof(FrameScope), c["current_typegen"], c["current_scope"])); }), opt(p("statement")), ows(), t(";"), opt(n("protasis", p(expressionName))), r(ows(), (Grammar gr) => { var c = gr.CodeGen; var state_local = c["cg"].Invoke("This").Invoke("Field", c["current_scope"][c["loop_current"].Invoke("ToString") + "$$"].Field("MangledName")); c.Invoke(c["cg"], "While", state_local.Invoke("GE", 1)); c.Invoke(c["cg"], "If", state_local.Invoke("EQ", 1)); { c.Invoke(c["cg"], "Assign", state_local, 2); c.Invoke(c["cg"], "Goto", "loop_entry" + c["loop_current"]); } c.Invoke(c["cg"], "End"); c.Invoke(c["cg"], "Label", "loop_tail" + c["loop_current"]); }), t(";"), opt(n("tailstatement", p("statement"))), ows(), r(t(")"), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["cg"], "Label", "loop_entry" + c["loop_current"]); c.If(c["m"].Invoke("HasOwnKey", "protasis").LogicalAnd(c["m"]["protasis"].Field("Result").IsInstanceOf(typeof(object)))); { c.Invoke(c["cg"], "If", c["m"]["protasis"].Field("Result").Invoke("LogicalNot")); { c.Invoke(c["cg"], "Break"); } c.Invoke(c["cg"], "End"); } c.End(); }), ows(), r(p("statementListBlock"), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["cg"], "Goto", "loop_tail" + c["loop_current"]); c.Invoke(c["cg"], "Label", "loop_exit" + c["loop_current"]); c.Invoke(c["cg"], "End"); c.Assign(c["loop_current"], c["loop_stack"].Invoke("Pop")); //c.Assign(c["current_scope"], c["current_scope"].Field("Parent").Cast(typeof(FrameScope))); }) ), seq( t("loop"), r(p("ws"), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["loop_stack"], "Push", c["loop_current"]); c.Increment(c["loop_counter"]); c.Assign(c["loop_current"], c["loop_counter"]); var state_local = c["cg"].Invoke("This").Invoke("Field", c["current_scope"][c["loop_current"].Invoke("ToString") + "$$"].Field("MangledName")); c.Invoke(c["current_scope"], "AddHere", c["loop_current"].Invoke("ToString") + "$$", Exp.New(typeof(FrameLocal), c["loop_current"].Invoke("ToString") + "$$", typeof(int), c["current_scope"])); c.InvokeAssign(c["temp_fieldgen01"], c["current_typegen"].Field("FrameGen"), "PublicField", typeof(int), c["current_scope"][c["loop_current"].Invoke("ToString") + "$$"].Field("MangledName")); c.Invoke(c["cg"], "Assign", state_local, 1); //c.Assign(c["current_scope"], Exp.New(typeof(FrameScope), c["current_typegen"], c["current_scope"])); c.Invoke(c["cg"], "While", state_local.Invoke("EQ", 1)); }), ows(), r(p("statementListBlock"), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["cg"], "End"); c.Assign(c["loop_current"], c["loop_stack"].Invoke("Pop")); //c.Assign(c["current_scope"], c["current_scope"].Field("Parent").Cast(typeof(FrameScope))); }) )))); g.AddPattern("statementBlock", alt( p("ifBlock"), p("unlessBlock"), p("whileBlock"), p("untilBlock"), p("repeatWhileBlock"), p("repeatUntilBlock"), p("loopBlock"), p("statementListBlock") )); g.AddPattern("classStatementBlock", alt( p("methodDeclaration"), p("ifBlock"), p("unlessBlock"), p("whileBlock"), p("untilBlock"), p("repeatWhileBlock"), p("repeatUntilBlock"), p("loopBlock"), p("statementListBlock") )); g.AddPattern("statementListBlock", seq( t("{"), p("optStatementList"), t("}") )); g.AddPattern("classStatementListBlock", seq( t("{"), ows(), opt(t("...")), p("optClassStatementList"), t("}") )); BuildStatementList(g, "statementList", p("statementBlock"), p("statementNonBlock"), p("optStatementList")); BuildStatementList(g, "classStatementList", p("classStatementBlock"), p("classStatementNonBlock"), p("optClassStatementList")); g.AddPattern("returnStatement", n("returnStatement", seq( t("return"), p("ws"), r(n("retValue", p(expressionName)), (Grammar gr) => { var c = gr.CodeGen; c.Assign(c["current_typegen"].Property("CRT"), c["m"]["retValue"].Field("Result").Type); c.Invoke(c["cg"], "Assign", c["cg"].Invoke("This").Invoke("Field", "Return"), c["m"]["retValue"].Field("Result")); c.Invoke(c["cg"], "Goto", "csmeta_return_label"); }) ))); g.AddPattern("useStatement", n("useStatement", seq( t("use"), p("ws"), r(seq(n("filename", p("stringLiteral"))), (Grammar gr) => { var c = gr.CodeGen; c.Assign(c["l"], c["IN"].Invoke("InjectFileContent", c["o"], c["m"]["filename"].Field("Result").Cast(typeof(StringLiteral)).Property("ConstantValue").Cast(typeof(string)))); c.Assign(c["i"], c["IN"].Field("Chars")); }) ))); g.AddPattern("statementNonBlock", alt( p("useStatement"), p("gotoStatement"), p("nextStatement"), p("lastStatement"), p("repeatWhileStatement"), p("returnStatement"), p("myDeclaration"), p("contextualAssignment"), p("subDeclaration"), p("classPreDeclaration"), p("classDeclaration"), r(p(expressionName), (Grammar gr) => { var c = gr.CodeGen; c.If(c["m"].Field("Result").IsInstanceOf(typeof(Operand))); { c.If(c["m"].Field("Result").Property("Type").Invoke("Equals", typeof(void))); { c.Invoke(c["m"].Field("Result"), "ForceEmit", c["cg"]); } c.Else(); { c.Assign(c["operand01"], c["cg"][c["GG"].Invoke("GetNextEphemeral"), c["m"].Field("Result").Property("Type")]); c.Invoke(c["cg"], "Assign", c["cg"][c["GG"].Invoke("GetLastEphemeral")], c["m"].Field("Result")); } c.End(); } c.End(); }) )); g.AddPattern("classStatementNonBlock", alt( p("fieldDeclaration"), p("gotoStatement"), p("nextStatement"), p("lastStatement"), p("repeatWhileStatement"), // p("returnStatement"), // return statement not allowed in class declaration p("myDeclaration"), p("contextualAssignment"), p("subDeclaration"), r(p(expressionName), (Grammar gr) => { var c = gr.CodeGen; c.If(c["m"].Field("Result").IsInstanceOf(typeof(Operand))); { c.If(c["m"].Field("Result").Property("Type").Invoke("Equals", typeof(void))); { c.Invoke(c["m"].Field("Result"), "ForceEmit", c["cg"]); } c.Else(); { c.Assign(c["operand01"], c["cg"][c["GG"].Invoke("GetNextEphemeral"), c["m"].Field("Result").Property("Type")]); c.Invoke(c["cg"], "Assign", c["cg"][c["GG"].Invoke("GetLastEphemeral")], c["m"].Field("Result")); } c.End(); } c.End(); }) )); g.AddPattern("optLabelMarker", opt(r(seq(n("labelName", p("varname")), t(":"), p("ws")), (Grammar gr) => { var c = gr.CodeGen; var labelName = c["IN"].Invoke("Match", c["m"]["labelName"]); c.Invoke(c["cg"], "Label", labelName); }))); g.AddPattern("gotoStatement", alt(r(seq(t("goto"), p("ws"), n("labelName", p("varname"))), (Grammar gr) => { var c = gr.CodeGen; var labelName = c["IN"].Invoke("Match", c["m"]["labelName"]); c.Invoke(c["cg"], "Goto", labelName); }), r(seq(t("goto"), p("ws"), n("continuation", p(termName))), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["cg"], "Return", c["m"]["continuation"].Field("Result")); }))); g.AddPattern("lastStatement", r(seq(t("last"), new Not(p("varname")), new Lookahead(new AnyChar())), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["cg"], "Break"); })); g.AddPattern("nextStatement", alt(r(seq(t("next"), new Not(p("varname")), new Lookahead(new AnyChar())), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["cg"], "Continue"); }), r(seq(t("next"), p("ws"), n("labelName", p("varname"))), (Grammar gr) => { var c = gr.CodeGen; var labelName = c["IN"].Invoke("Match", c["m"]["labelName"]); c.Invoke(c["cg"], "Goto", labelName); }))); g.AddPattern("stmtCommas", seq( ows(), p("statement"), ows(), opt(seq( t(","), p("stmtCommas"))), ows() )); counter = Counter; }
public static Grammar BuildPerlesque(string imageName, bool saveStage1AssemblyToDisk, bool saveStage2AssemblyToDisk) { var g = new Grammar(imageName); var Counter = 0; var expressionName = "EXPR"; var termName = "Term"; var termishName = "Termish"; g.AddPattern("toplevel", seq( r(new Empty(), (Grammar gr) => { var c = gr.CodeGen; var unused = c["AG", typeof(AssemblyGen)]; //unused = c["AG2", typeof(AssemblyGen)]; unused = c["dyn_asmbly", typeof(Assembly)]; //unused = c["TG2", typeof(TypeGen)]; unused = c["TG", typeof(TypeGen)]; unused = c["TG_top", typeof(TypeGen)]; unused = c["MG", typeof(MethodGen)]; unused = c["TLMG", typeof(MethodGen)]; unused = c["TLBG", typeof(MethodGen)]; unused = c["temp_methodgen01", typeof(MethodGen)]; unused = c["cg_2", typeof(CodeGen)]; unused = c["cg", typeof(CodeGen)]; unused = c["null_value", typeof(Operand)]; unused = c["OpArray", typeof(Operand[])]; unused = c["OpArray2", typeof(Operand[])]; unused = c["VC", typeof(int)]; unused = c["assertion", typeof(bool)]; unused = c["assertion_counter", typeof(int)]; unused = c["ANew", typeof(Assembly)]; unused = c["current_scope", typeof(FrameScope)]; unused = c["last_scope", typeof(FrameScope)]; unused = c["root_scope", typeof(FrameScope)]; unused = c["current_typegen", typeof(TypeGen)]; unused = c["current_classgen", typeof(TypeGen)]; unused = c["temp_typegen01", typeof(TypeGen)]; unused = c["temp_typegen02", typeof(TypeGen)]; unused = c["temp_type", typeof(Type)]; unused = c["last_typegen", typeof(TypeGen)]; unused = c["assembly_name", typeof(string)]; unused = c["temp_fieldgen01", typeof(FieldGen)]; unused = c["if_counter", typeof(uint)]; unused = c["if_current", typeof(uint)]; unused = c["if_stack", typeof(Stack <uint>)]; unused = c["loop_counter", typeof(uint)]; unused = c["loop_current", typeof(uint)]; unused = c["loop_stack", typeof(Stack <uint>)]; unused = c["temp_field03", typeof(Field)]; unused = c["temp_subname", typeof(string)]; unused = c["s01", typeof(string)]; unused = c["last_line", typeof(int)]; unused = c["last_position", typeof(int)]; unused = c["foreach_string", typeof(string)]; c.Assign(c["loop_current"], 0); c.Assign(c["loop_counter"], 0); c.Assign(c["loop_stack"], Exp.New(typeof(Stack <uint>))); c.Assign(c["if_counter"], 0); c.Assign(c["if_current"], 0); c.Assign(c["if_stack"], Exp.New(typeof(Stack <uint>))); c.Assign(c["last_line"], 1); c.Assign(c["last_position"], 0); c.Assign(c["assertion_counter"], 0); c.Assign(c["VC"], 1); c.Assign(c["assembly_name"], c["GG"].Invoke("GetNextAssemblyName")); //c.Assign(c["AG2"], c["GG"].Invoke("GetAssemblyGen", c["assembly_name"] + "_throwaway")); //c.Assign(c["TG2"], c["GG"].Invoke("GetTypeGen", c["AG2"])); c.Assign(c["AG"], c["GG"].Invoke("GetAssemblyGen", c["assembly_name"])); c.Assign(c["TG"], c["GG"].Invoke("GetTypeGen", c["AG"])); c.Assign(c["MG"], c["GG"].Invoke("GetEntryPointGen", c["TG"])); c.Assign(c["cg_2"], c["MG"]); c.Assign(c["TG_top"], c["GG"].Invoke("GetToplevelTypeGen", c["AG"])); c.Assign(c["current_typegen"], c["TG_top"]); c.Assign(c["TLMG"], c["GG"].Invoke("GetExecGen", c["TG_top"])); c.Assign(c["type1"], c["GG"].Field("FrameBaseGen")); // empty implementation of Bind for the toplevel //c.Assign(c["TLBG"], c["GG"].Invoke("GetBindGen", c["TG_top"], c["type1"])); //c.Assign(c["type1"], Exp.New(typeof(Operand[]), 1)); //c.Assign(c["OpArray"][0], c["TG_top"].Invoke("GetTypeObject")); c.Assign(c["cg"], c["MG"]); c.Assign(c["cg"]["operand01"], c["cg"]["evaluator", c["TG_top"].Invoke("GetTypeObject")]); c.InvokeAssign(c["cg"]["evaluator"], typeof(Exp), "New", c["TG_top"].Invoke("GetTypeObject")); c.Invoke(c["cg"], "Invoke", c["cg"]["evaluator"], "Run"); c.Assign(c["cg"], c["TLMG"]); c.Assign(c["cg"]["operand01"], c["cg"]["next_frame", c["GG"].Field("FrameBaseGen")]); // create the base FrameScope c.Assign(c["current_scope"], Exp.New(typeof(FrameScope), c["current_typegen"])); c.Assign(c["root_scope"], c["current_scope"]); c.Invoke(c["cg"], "Goto", "csmeta_prologue"); c.Invoke(c["cg"], "Label", "csmeta_actual_start"); //c.Try(); }), p("optStatementList"), r(end(), (Grammar gr) => { var c = gr.CodeGen; c.Invoke(c["cg"], "Goto", "inst2"); c.Invoke(c["cg"], "Label", "csmeta_prologue"); // initialization code for the toplevelframe // (initialize stacks of contextuals) c.Invoke(c["TG_top"], "EmitPrologueInitializers", c["cg"]); c.Invoke(c["cg"], "Goto", "csmeta_actual_start"); c.Invoke(c["cg"], "Label", "inst0"); c.Invoke(c["cg"], "Switch", c["cg"].Invoke("This").Invoke("Field", "Instruction"), c["GG"].Invoke("GetRoutineInstructionLabels", c["cg"])); c.Invoke(c["cg"], "Label", "inst2"); c.Invoke(c["cg"], "Label", "csmeta_return_label"); c.Invoke(c["cg"], "Return", c["null_value"]); //c.CatchAll(); //c.WriteLine("parse failure; got to line " + c["last_line"]); //c.End(); c.Invoke(c["GG"], "AscendOutofSub", c["TG_top"]); if (saveStage2AssemblyToDisk) { c.Invoke(c["GG"], "SaveAndInvokeAssembly", c["AG"], c["assembly_name"]); } else { c.InvokeAssign(c["dyn_asmbly"], c["AG"], "GetAssembly"); c.Invoke(c["GG"], "InvokeEntryPoint", c["dyn_asmbly"]); } c.Goto(g.DoneLabel); //c.WriteLine("compiled to assembly " + c["assembly_name"] + ".dll"); //c.Invoke(c["GG"], "RunAssembly", c["assembly_name"]); }) )); BuildControlFlow(g, ref Counter, expressionName, termName, termishName); BuildTerminals(g, ref Counter, expressionName, termName, termishName); BuildOperators(g, ref Counter, expressionName, termName, termishName); BuildExpressions(g, ref Counter, expressionName, termName, termishName); BuildDeclarations(g, ref Counter, expressionName, termName, termishName); return(g); }