protected override ICode VisitStmt(Stmt s) { if (!this.IsOnlyRequestedTypes || !this.stmtTypes.Contains(s.StmtType)) { this.IsOnlyRequestedTypes = false; return s; } return base.VisitStmt(s); }
/// <summary> /// Ctor /// </summary> /// <param name="expr"></param> /// <param name="stmt"></param> public If(Expr expr, Stmt stmt) { this.Expr = expr; this.Stmt = stmt; if(this.Expr.Type != Type.Bool) this.Expr.Error("boolean required in if"); }
protected override ICode VisitStmt(Stmt s) { var r = this.replaces.ValueOrDefault(s); if (r != null) { return r; } return base.VisitStmt(s); }
public void Parse() { _result = ParseNextStmt(); if (_index != _tokens.Count) throw new Exception("expected EOF"); }
public CodeGen(Stmt stmt, string moduleName) { if (IO.Path.GetFileName(moduleName) != moduleName) { throw new System.Exception("can only output into current directory!"); } Reflect.AssemblyName name = new Reflect.AssemblyName(IO.Path.GetFileNameWithoutExtension(moduleName)); Emit.AssemblyBuilder asmb = System.AppDomain.CurrentDomain.DefineDynamicAssembly(name, Emit.AssemblyBuilderAccess.Save); Emit.ModuleBuilder modb = asmb.DefineDynamicModule(moduleName); Emit.TypeBuilder typeBuilder = modb.DefineType("Foo"); Emit.MethodBuilder methb = typeBuilder.DefineMethod("Main", Reflect.MethodAttributes.Static, typeof(void), System.Type.EmptyTypes); // CodeGenerator this.il = methb.GetILGenerator(); this.symbolTable = new Collections.Dictionary<string, Emit.LocalBuilder>(); // Go Compile! this.GenStmt(stmt); il.Emit(Emit.OpCodes.Ret); typeBuilder.CreateType(); modb.CreateGlobalFunctions(); asmb.SetEntryPoint(methb); asmb.Save(moduleName); this.symbolTable = null; this.il = null; }
public StmtCil(Ctx ctx, IEnumerable<Instruction> insts, Stmt endCil, SpecialBlock blockType = SpecialBlock.Normal) : base(ctx) { this.Insts = insts; this.BlockType = blockType; this.EndCil = endCil; this.StartStackSize = 0; this.EndStackSize = 0; }
protected override ICode VisitStmt(Stmt s) { if (!this.seen.Add(s)) { this.duplicates.Add(s); return s; } else { return base.VisitStmt(s); } }
/// <summary> /// Ctor /// </summary> /// <param name="expr">bool</param> /// <param name="stmt1">stmt for true</param> /// <param name="stmt2">stmt for false</param> public IfElse(Expr expr, Stmt stmt1, Stmt stmt2) { this.Expr = expr; this.Stmt1 = stmt1; this.Stmt2 = stmt2; if (this.Expr.Type != Sara.Type.Bool) this.Expr.Error("boolean required in if"); }
private static string GetStmtName(Stmt s) { if (s.StmtType == Stmt.NodeType.Cil) { var sCil = (StmtCil)s; if (sCil.Insts != null && sCil.Insts.Any()) { return string.Format("IL_{0:x4}", sCil.Insts.First().Offset); } } return string.Format("{0:x8}", s.GetHashCode()); }
public Parser(Collections.IList<object> tokens) { this.tokens = tokens; this.index = 0; this.result = this.ParseStmt(); if (this.index != this.tokens.Count) throw new System.Exception("expected EOF"); }
public Parser(Collections.IList<object> tokens) { this.tokens = tokens; this.indice = 0; this.resultado = this.ParseStmt(); if (this.indice != this.tokens.Count) throw new System.Exception("se esperaba el final del archivo"); }
internal static void Print(Stmt stmt, string name, bool verbose) { if (verbose) { if (name != null && name.StartsWith("Visitor")) { name = name.Substring(7); } Console.WriteLine(" --- AST Transform Step {0}{1} ---", stmt.Ctx.step++, name == null ? "" : (" '" + name + "'")); Console.WriteLine(ShowVisitor.V(stmt)); Console.WriteLine(); } }
public Parser(IList<Token> Tokens) { this.Tokens = Tokens; Index = 0; result = this.ParseStmt(); if (Index != Tokens.Count) { // Parser exited before EOF throw new RPExeption(20, App.Current.TryFindResource("x_nexpend").ToString(), Line, Column); } }
protected override ICode VisitStmt(Stmt s) { var jsStmtType = (JsStmtType)s.StmtType; switch (jsStmtType) { case JsStmtType.JsExplicit: return this.VisitJsExplicit((StmtJsExplicit)s); default: if ((int)jsStmtType >= (int)JsStmtType.First) { throw new NotImplementedException("Cannot handle: " + jsStmtType); } else { return base.VisitStmt(s); } } }
void IInstructionMappable.Map(Dictionary<Instruction, List<Stmt>> map) { // Get the nested mapping, just inside this 'try' statement this.Try = map[this.@try].SkipWhile(x => x != this).Skip(1).First(); if (this.@catch != null) { this.Catches = new[] { new Catch(map[this.@catch][0], new ExprVarLocal(this.Ctx, this.catchType)) }; } else { this.Catches = null; } if (this.@finally != null) { this.Finally = map[this.@finally][0]; } else { this.Finally = null; } }
internal static Stmt DoStep(Func<Stmt, Stmt> fnStep, Stmt stmt, string name, bool verbose) { var s1 = fnStep(stmt); if (s1 != stmt) { Print(s1, name, verbose); var dupStmts = VisitorFindDuplicateStmts.Find(s1); if (dupStmts.Any()) { Console.WriteLine("*** ERROR *** {0} DUPLICATE STMT(S) ***", dupStmts.Count()); foreach (var dup in dupStmts) { Console.WriteLine(); Console.WriteLine(ShowVisitor.V(dup)); } throw new InvalidOperationException("Duplicate stmt(s) found"); } } return s1; }
protected override ICode VisitIf(StmtIf s) { if (!VisitorFindContinuations.Any(s)) { // 'If' contains no continuations, so no distribution can be done return s; } if (VisitorOnlyStatements.Only(s, Stmt.NodeType.If, Stmt.NodeType.Continuation) && this.ifInfo == null) { // 'If' only contains continuations, so no distribution can be done // Must visit base method to find contained continuations return base.VisitIf(s); } bool finalise = false; if (this.ifInfo == null) { finalise = true; this.ifInfo = new IfInfo(); } this.ifInfo.Conditions.Push(s.Condition); var then = this.Visit(s.Then); this.ifInfo.Conditions.Pop(); this.ifInfo.Conditions.Push(this.ctx.ExprGen.NotAutoSimplify(s.Condition)); var @else = this.Visit(s.Else); this.ifInfo.Conditions.Pop(); if (then != s.Then || @else != s.Else) { var @if = new StmtIf(s.Ctx, s.Condition, (Stmt)then, (Stmt)@else); if (finalise && this.ifInfo.AddToIf.Any()) { var ifStmts = this.ifInfo.AddToIf.GroupBy(x => x.Item1.To, x => x.Item2).Select(x => new StmtIf(s.Ctx, x.Aggregate((a, b) => this.ctx.ExprGen.Or(a, b)), this.ifInfo.AddToIf.First(y => y.Item1.To == x.Key).Item1, null) ); var stmts = new Stmt[] { @if }.Concat(ifStmts).ToArray(); this.ifInfo = null; return new StmtBlock(s.Ctx, stmts); } else { if (finalise) { this.ifInfo = null; } return @if; } } else { // In this case, no continuations will have been found, so there cannot be any conditions to add if (finalise) { this.ifInfo = null; } return s; } }
public static bool AreSame(Stmt a, Stmt b) { if (a == null && b == null) { return true; } if (a == null || b == null) { return false; } if (a.StmtType != b.StmtType) { return false; } switch (a.StmtType) { case Stmt.NodeType.Continuation: var aCont = (StmtContinuation)a; var bCont = (StmtContinuation)b; return aCont.To == bCont.To; default: return false; } }
public CodeGen(Stmt stmt, string moduleName) { if (string.IsNullOrEmpty(moduleName)) throw new ArgumentException("must have a module name", "moduleName"); _stmt = stmt; _moduleName = moduleName; if (Path.GetFileName(moduleName) != moduleName) throw new Exception("can only output into current directory!"); var filename = Path.GetFileNameWithoutExtension(moduleName); var asmName = new AssemblyName(filename); _asmb = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Save); _modb = _asmb.DefineDynamicModule(moduleName); _typeBuilder = _modb.DefineType("Foo"); _methb = _typeBuilder.DefineMethod("Main", MethodAttributes.Static, typeof(void), Type.EmptyTypes); _il = _methb.GetILGenerator(); SymbolTable = new Dictionary<string, LocalBuilder>(); }
private Tuple<Stmt, Stmt> RemoveContinuation(Stmt s) { // Return Item1 = Statement 's' with continuation removed // Return Item2 = Block that only continuation in 's' points to, otherwise null // This must not return a null statement if empty, as then the 'try' statements won't know // if it is a 'catch' or 'finally' statement. Uses a StmtEmpty instead. var contCount = VisitorFindContinuations.Get(s).Count(); if (contCount == 0) { // Blocks with no continuations must end with a 'throw' return Tuple.Create(s, (Stmt)null); } if (contCount != 1) { return null; } switch (s.StmtType) { case Stmt.NodeType.Block: var statements = ((StmtBlock)s).Statements.ToArray(); if (statements.Length == 0) { return null; } if (statements.Last().StmtType != Stmt.NodeType.Continuation) { return null; } var cont = (StmtContinuation)statements.Last(); if (!cont.LeaveProtectedRegion) { return null; } if (statements.Length == 1) { return Tuple.Create((Stmt)new StmtEmpty(s.Ctx), cont.To); } return Tuple.Create((Stmt)new StmtBlock(s.Ctx, statements.Take(statements.Length - 1)), cont.To); case Stmt.NodeType.Continuation: var sCont = (StmtContinuation)s; if (!sCont.LeaveProtectedRegion) { return null; } return Tuple.Create((Stmt)new StmtEmpty(s.Ctx), sCont.To); default: return null; } }
private Block GetBlock() { if (Test(TokenType.True)) { Next(); return(new Block().SetValue(true)); } if (Test(TokenType.False)) { Next(); return(new Block().SetValue(false)); } if (Test(TokenType.Int)) { var token = Match(TokenType.Int); if (int.TryParse(token.value, out int intValue)) { return(new Block().SetValue(intValue)); } throw new RuntimeException($"{token.GetExceptionString()} {token.value}不能转化为整数"); } if (Test(TokenType.Str)) { return(new Block().SetValue(Match(TokenType.Str).value)); } if (Test(TokenType.Semicolon)) { Next(); return(null); } if (Test(TokenType.Name)) { // 检测remap函数 string value = Value().value; //Console.WriteLine("in this "+value); if (value.StartsWith("$")) { if (int.TryParse(value.Substring(1), out int no)) { Next(); Block block = new Block(); lasyBlocks[no] = block; return(block); } } } if (Test(TokenType.LBrace)) { Next(); Block block = Expr(); Match(TokenType.RBrace); return(block); } else { List <Stmt> stmts = new List <Stmt>(); while (true) { //Console.WriteLine($"cur: {index}"); Stmt stmt = GetStmt(); if (Test(TokenType.Semicolon)) { Next(); } if (stmt == null) { break; } stmts.Add(stmt); if (Test(TokenType.RBrace)) { break; } } if (stmts.Any()) { return(new Block().SetValue(stmts)); } } return(null); }
public Case(Expr expr, Stmt statement) { this.expr = expr; this.stmt = statement; }
public Labeled(Id id, Stmt statement) { this.id = id; this.stmt = statement; }
private void Resolve(Stmt stmt) { stmt.Accept(this); }
public ContextExp(ContextProc procContext, Stmt stmt) { ProcContext = procContext; Stmt = stmt; }
private Type GetIdentType(Stmt stmt) { var ident = ((ReadConsoleIn)stmt).Ident; if (!SymbolTable.ContainsKey(ident)) throw new Exception("undeclared variable '" + ident + "'"); return SymbolTable[ident].LocalType; }
public void PushStmt(Stmt stmt) { StmtStack.Push(stmt); }
private void RunStmt(Stmt stmt) { if (flagBreak) { return; } //Application.DoEvents(); #region Sequence if (stmt is Sequence) { Sequence seq = (Sequence)stmt; RunStmt(seq.First); RunStmt(seq.Second); } #endregion #region DeclareVar else if (stmt is DeclareVar) { // declare DeclareVar declare = (DeclareVar)stmt; CodeDeclareSymbol(declare); //TODO: (Z) Sustituir lo anterior por esto cuando se // arregle el código de asignación + declaración. //Assign assign = new Assign(); //assign.Ident = declare.Ident; //assign.Expr = declare.Expr; //RunStmt(assign); } #endregion #region Assign else if (stmt is Assign) { Assign assign = (Assign)stmt; CodeStoreSymbol(assign); } #endregion #region Print / PrintLine / Clear else if (stmt is Print) { Print print = (Print)stmt; CodeExecutePrint(print); } else if (stmt is PrintLine) { PrintLine printLine = (PrintLine)stmt; CodeExecutePrintLine(printLine); } else if (stmt is Clear) { CodeExecuteClear(); } #endregion #region FunctionStmt else if (stmt is FunctionStmt) { FunctionStmt fun = (FunctionStmt)stmt; CodeExecuteFunction(fun.Function); } #endregion #region ReadVar else if (stmt is ReadVar) { ReadVar read = (ReadVar)stmt; ReadVarItem readVarItem; Assign assign; List <ReadVarItem> readVarItmes = new List <ReadVarItem>(); foreach (var pair in read.Vars) { readVarItem = new ReadVarItem(); readVarItem.VarIdent = pair.Key.Ident; readVarItem.VarValue = CodeReadSymbol(pair.Key); readVarItem.Label = GenExpr(pair.Value); readVarItmes.Add(readVarItem); } if (CodeExecuteReadVars(readVarItmes)) { foreach (ReadVarItem vi in readVarItmes) { assign = new Assign(); //assign.Ident = vi.Var.Ident; assign.Ident = vi.VarIdent; assign.Expr = ValueToExpr(vi.VarValue.GetType(), vi.VarNewValueText); RunStmt(assign); } } } #endregion #region BreakStmt else if (stmt is BreakStmt) { flagBreak = true; return; } #endregion #region FoorLoop else if (stmt is ForLoop) { // example: // for x = 0 to 100 // print "hello"; // end for; ForLoop forLoop = (ForLoop)stmt; IntVal numFrom = new IntVal(); IntVal numTo = new IntVal(); Assign assignFrom = new Assign(); assignFrom.Ident = forLoop.Ident; assignFrom.Expr = forLoop.From; RunStmt(assignFrom); numFrom.Value = Convert.ToInt32(GenExpr(forLoop.From)); numTo.Value = Convert.ToInt32(GenExpr(forLoop.To)); while (numFrom.Value <= numTo.Value) { if (flagBreak) { break; } RunStmt(forLoop.Body); numFrom.Value++; assignFrom.Expr = numFrom; RunStmt(assignFrom); } if (flagBreak) { flagBreak = false; } } #endregion #region FoorEachLoop else if (stmt is ForEachLoop) { // example: // foreach x in myColec // print "hello"; // print x.MyProp; // end foreach; ForEachLoop forEachLoop = (ForEachLoop)stmt; object colec = GenExpr(forEachLoop.Colec); foreach (object o in (IEnumerable <object>)colec) { if (flagBreak) { break; } // TODO: Pending susutiruir CodeSpecialStoreObject by CodeStoreSymbol // In the future, CodeStoreSymbol should store the variable // if it had not previously been declared. CodeSpecialStoreObject(forEachLoop.Ident, o); // CodeStoreSymbol(forEachLoop.Ident, o); RunStmt(forEachLoop.Body); } if (flagBreak) { flagBreak = false; } } #endregion #region IfStmt else if (stmt is IfStmt) { // example: // if a == 10 then // print "hello"; // else // print "bye"; // end if; IfStmt ifStmt = (IfStmt)stmt; IntVal ifExp = new IntVal(); ifExp.Value = Convert.ToInt32(GenExpr(ifStmt.TestExpr)); if (ifExp.Value != 0) { RunStmt(ifStmt.BodyIf); } else { if (ifStmt.DoElse) { RunStmt(ifStmt.BodyElse); } } } #endregion #region WhileStmt else if (stmt is WhileStmt) { // example: // while a <= 10 // print "hello"; // a = a + 1; // end while; WhileStmt whileStmt = (WhileStmt)stmt; IntVal whileExp = new IntVal(); while (true) { if (flagBreak) { break; } whileExp.Value = Convert.ToInt32(GenExpr(whileStmt.TestExpr)); if (whileExp.Value == 0) { break; } RunStmt(whileStmt.Body); } if (flagBreak) { flagBreak = false; } } #endregion else { throw new System.Exception("don't know how to gen a " + stmt.GetType().Name); } }
public void Run(Stmt stmt) { // Go Run! RunStmt(stmt); }
private void execute(Stmt stmt) { stmt.accept(this); }
private void GenStmt(Stmt stmt) { //Обработка элемента последовательности дерева if (stmt is Sequence) { Sequence seq = (Sequence)stmt; //Выполним обработку левой части дерева this.GenStmt(seq.First); //Выполним обработку правой части дерева this.GenStmt(seq.Second); } //Обработка элемента дерева - "Объявление" else if (stmt is DeclareVar) { // Добавим переменную в список переменных DeclareVar declare = (DeclareVar)stmt; this.varTable[declare.Ident] = this.TypeOfExpr(declare.Expression); //Приведем элемент типа "Объевление" к типу "Присвоение" Assign assign = new Assign(); assign.Ident = declare.Ident; assign.Expression = declare.Expression; //Запишем тип переменной accum.Append(string.Format("\n{0} ", this.TypeOfExpr(declare.Expression).Name)); //Запустим на обработку this.GenStmt(assign); } //Обработка элемента дерева - "Присвоение" else if (stmt is Assign) { Assign assign = (Assign)stmt; accum.Append(string.Format("{0}=", assign.Ident)); //Обработка правой части элемента this.GenAssign(assign.Expression); accum.Append(";"); } //Обработка элемента дерева - "Вывод данных" else if (stmt is Print) { Print print = (Print)stmt; accum.Append(print.VarExpression != null ? string.Format("\nConsole.WriteLine(\"{0}\", {1});", this.GetExprValue(print.Expression), this.GetExprValue(print.VarExpression)) : string.Format("\nConsole.WriteLine(\"{0}\");", this.GetExprValue(print.Expression))); } //Обработка элемента дерева - "Ввод данных" else if (stmt is ReadValue) { ReadValue readValue = (ReadValue)stmt; accum.Append(readValue.Exp != null ? string.Format("\n{0} = Console.ReadLine(\"{1}\");", readValue.Ident, this.GetExprValue(readValue.Exp)) : string.Format("\n{0} = Console.ReadLine();", readValue.Ident)); //Проверка, что переменная объявлена ранее //CheckVariable } else if (stmt is IfElse) { IfElse ifElse = (IfElse)stmt; string operation = string.Empty; switch (ifElse.Condition.Operation) { case ConOperation.Equal: operation = "="; break; case ConOperation.Less: operation = "<"; break; case ConOperation.LessEqual: operation = "<="; break; case ConOperation.More: operation = ">"; break; case ConOperation.MoreEqual: operation = ">="; break; } accum.Append(string.Format("\nif ({0}{1}{2})", this.GetExprValue(ifElse.Condition.Left), operation, this.GetExprValue(ifElse.Condition.Right))); if (ifElse.BodyThen != null) { accum.Append("\n{\n"); this.GenStmt(ifElse.BodyThen); accum.Append("\n}"); } if (ifElse.BodyElse != null) { if (ifElse.BodyThen == null) { throw new System.Exception("error if - else"); } accum.Append("\nelse\n{\n"); this.GenStmt(ifElse.BodyElse); accum.Append("\n}"); } } else if (stmt is ForNext) { ForNext forNext = (ForNext)stmt; accum.Append(string.Format("\nfor(")); Assign assign = new Assign(); assign.Ident = forNext.Ident; assign.Expression = forNext.From; this.GenStmt(assign); accum.Append(string.Format("{0}<{1};{2}++)", forNext.Ident, this.GetExprValue(forNext.To), forNext.Ident)); this.varTable[forNext.Ident] = typeof(int); if (forNext.Body != null) { accum.Append("\n{"); this.GenStmt(forNext.Body); accum.Append("\n}"); } } else { throw new System.Exception("Отсутствует инструкция для генерирования операции: " + stmt.GetType().Name); } }
private void GenStmt(Stmt stmt) { if (stmt is Sequence) { var seq = (Sequence)stmt; GenStmt(seq.First); GenStmt(seq.Second); } else if (stmt is DeclareVar) { // declare a local var declare = (DeclareVar)stmt; _symbolTable[declare.Ident] = _il.DeclareLocal(declare.Expr.GetType()); // set the initial value var assign = new Assign(declare.Ident, declare.Expr); GenStmt(assign); } else if (stmt is Assign) { var assign = (Assign)stmt; GenerateLoadToStackForExpr(assign.Expr, assign.Expr.GetType()); GenerateStoreFromStack(assign.Ident, assign.Expr.GetType()); } else if (stmt is Print) { // the "print" statement is an alias for System.Console.WriteLine. // it uses the string case GenerateLoadToStackForExpr(((Print)stmt).Expr, typeof(string)); //Generate console.writeline _il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new[] { typeof(string) })); } else if (stmt is ReadInt) { _il.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadLine", BindingFlags.Public | BindingFlags.Static, null, Array.Empty <Type>(), null)); _il.Emit(OpCodes.Call, typeof(int).GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(string) }, null)); GenerateStoreFromStack(((ReadInt)stmt).Ident, typeof(int)); } else if (stmt is ReadString) { _il.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadLine", BindingFlags.Public | BindingFlags.Static, null, Array.Empty <Type>(), null)); GenerateStoreFromStack(((ReadString)stmt).Ident, typeof(string)); } else if (stmt is ForLoop) { // example: // for x = 0 to 100 do // print "hello"; // end; // x = 0 var forLoop = (ForLoop)stmt; var assign = new Assign(forLoop.Ident, forLoop.From); GenStmt(assign); // jump to the test var test = _il.DefineLabel(); _il.Emit(OpCodes.Br, test); // statements in the body of the for loop var body = _il.DefineLabel(); _il.MarkLabel(body); GenStmt(forLoop.Body); // to (increment the value of x) _il.Emit(OpCodes.Ldloc, SymbolTable[forLoop.Ident]); _il.Emit(OpCodes.Ldc_I4, 1); _il.Emit(OpCodes.Add); GenerateStoreFromStack(forLoop.Ident, typeof(int)); // **test** does x equal 100? (do the test) _il.MarkLabel(test); _il.Emit(OpCodes.Ldloc, SymbolTable[forLoop.Ident]); GenerateLoadToStackForExpr(forLoop.To, typeof(int)); _il.Emit(OpCodes.Blt, body); } else { throw new Exception("don't know how to gen a " + stmt.GetType().Name); } }
public Seq(Stmt stmt1, Stmt stmt2) { this.Stmt1 = stmt1; this.Stmt2 = stmt2; }
public SymbolTable(SymbolTable p, Stmt belong, string name = "") : this(p, name) { Belong = belong; }
public LabeledStmt(ref ptr <Ident> Label = default, token.Pos Colon = default, Stmt Stmt = default) { this.Label = Label; this.Colon = Colon; this.Stmt = Stmt; }
public If(Expr condition, Stmt main, Stmt el) { Condition = condition; MainBlock = main; ElseBlock = el; }
public FunctionDeclaration(TypeSpecifier returnType, Token identifier, List <Parameter> parameters, Stmt functionBody) { ReturnType = returnType; Identifier = identifier; Parameters = parameters; FunctionBody = functionBody; }
private void Resolve(Stmt statement) { statement.Accept(this); }
public Do() { this.Expr = null; this.Stmt = null; }
protected override void Populate() { VariableDeclarations.Populate(cx, Stmt.Declaration, this, 0); cx.BindComments(this, Stmt.GetLocation()); }
void IVisitor.VisitOnStmtSeparator(Stmt stmt, int offset, int i) { this.ParentExists(stmt); }
public StmtTry(StmtBlock body_block, Stmt stmt, StmtBlock catch_block) { this.Body = body_block; this.Stmt = stmt; this.Catch = catch_block; }
public Default(Stmt statement) { this.stmt = statement; }
public StmtExpr(Stmt stmt) { this.Stmt = stmt; }
public Do(Expr expr, Stmt stmt) : base(new CompoundStmt(new List <Stmt> { stmt })) { this.expr = expr; }
public StmtFinally(Stmt stmt) { this.Stmt = stmt; }
private Stmt Visit(Stmt statement) { return(statement.Accept(this)); }
public If(Expr condition, Stmt thenBranch, Stmt elseBranch) { Condition = condition; ThenBranch = thenBranch; ElseBranch = elseBranch; }
private void GenStmt(Stmt stmt) { if (stmt is Sequence) { Sequence seq = (Sequence)stmt; this.GenStmt(seq.First); this.GenStmt(seq.Second); } else if (stmt is DeclareVar) { // declare a local DeclareVar declare = (DeclareVar)stmt; this.symbolTable[declare.Ident] = this.il.DeclareLocal(this.TypeOfExpr(declare.Expr)); // set the initial value Assign assign = new Assign(); assign.Ident = declare.Ident; assign.Expr = declare.Expr; this.GenStmt(assign); } else if (stmt is Assign) { Assign assign = (Assign)stmt; this.GenExpr(assign.Expr, this.TypeOfExpr(assign.Expr)); this.Store(assign.Ident, this.TypeOfExpr(assign.Expr)); } else if (stmt is Print) { // the "print" statement is an alias for System.Console.WriteLine. // it uses the string case this.GenExpr(((Print)stmt).Expr, typeof(string)); this.il.Emit(Emit.OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new System.Type[] { typeof(string) })); } else if (stmt is ReadInt) { this.il.Emit(Emit.OpCodes.Call, typeof(System.Console).GetMethod("ReadLine", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, new System.Type[] { }, null)); this.il.Emit(Emit.OpCodes.Call, typeof(int).GetMethod("Parse", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, new System.Type[] { typeof(string) }, null)); this.Store(((ReadInt)stmt).Ident, typeof(int)); } else if (stmt is ForLoop) { // example: // for x = 0 to 100 do // print "hello"; // end; // x = 0 ForLoop forLoop = (ForLoop)stmt; Assign assign = new Assign(); assign.Ident = forLoop.Ident; assign.Expr = forLoop.From; this.GenStmt(assign); // jump to the test Emit.Label test = this.il.DefineLabel(); this.il.Emit(Emit.OpCodes.Br, test); // statements in the body of the for loop Emit.Label body = this.il.DefineLabel(); this.il.MarkLabel(body); this.GenStmt(forLoop.Body); // to (increment the value of x) this.il.Emit(Emit.OpCodes.Ldloc, this.symbolTable[forLoop.Ident]); this.il.Emit(Emit.OpCodes.Ldc_I4, 1); this.il.Emit(Emit.OpCodes.Add); this.Store(forLoop.Ident, typeof(int)); // **test** does x equal 100? (do the test) this.il.MarkLabel(test); this.il.Emit(Emit.OpCodes.Ldloc, this.symbolTable[forLoop.Ident]); this.GenExpr(forLoop.To, typeof(int)); this.il.Emit(Emit.OpCodes.Blt, body); } else { throw new System.Exception("don't know how to gen a " + stmt.GetType().Name); } }
public While(Expr condition, Stmt body) { Condition = condition; Body = body; }
private void CreateOrMergeBsi(Stmt s, Expr[] stack, Expr[] locals, Expr[] args) { if (s.StmtType == Stmt.NodeType.Try) { var sTry = (StmtTry)s; // It is fine to use 'locals' and 'args' in catch/finally because the phi clustering performed later // will conglomerate all the necessary variables if (sTry.Catches != null) { var catch0 = sTry.Catches.First(); this.CreateOrMergeBsi(catch0.Stmt, new Expr[] { catch0.ExceptionVar }, locals, args); } if (sTry.Finally != null) { this.CreateOrMergeBsi(sTry.Finally, new Expr[0], locals, args); } this.CreateOrMergeBsi(sTry.Try, stack, locals, args); return; } if (s.StmtType != Stmt.NodeType.Cil) { throw new InvalidCastException("Should not be seeing: " + s.StmtType); } // Perform create/merge Func<Expr, IEnumerable<Expr>> flattenPhiExprs = null; flattenPhiExprs = e => { if (e.ExprType == Expr.NodeType.VarPhi) { return ((ExprVarPhi)e).Exprs.SelectMany(x => flattenPhiExprs(x)); } return new[] { e }; }; Action<ExprVarPhi[], IEnumerable<Expr>> merge = (bsiVars, thisVars) => { foreach (var v in bsiVars.Zip(thisVars, (a, b) => new { phi = a, add = b })) { if (v.add != null) { v.phi.Exprs = flattenPhiExprs(v.add).Concat(v.phi.Exprs).Where(x => x != null && x != v.phi).Distinct().ToArray(); } } }; BlockInitInfo bsi; if (!this.blockStartInfos.TryGetValue(s, out bsi)) { Func<IEnumerable<Expr>, ExprVarPhi[]> create = exprs => exprs.Select(x => { if (x == null) { return new ExprVarPhi(this.ctx) { Exprs = new Expr[0] }; } if (x.ExprType == Expr.NodeType.VarPhi) { return (ExprVarPhi)x; } return new ExprVarPhi(this.ctx) { Exprs = new[] { x } }; }).ToArray(); bsi = new BlockInitInfo { Stack = create(stack), Locals = create(locals), Args = create(args), }; this.blockStartInfos.Add(s, bsi); } else { merge(bsi.Stack, stack); merge(bsi.Locals, locals); merge(bsi.Args, args); // Forward-merge through already-processed nodes for vars that are not changed in a node var fmSeen = new HashSet<Stmt>(); Action<Stmt> forwardMerge = null; forwardMerge = (stmt) => { if (fmSeen.Add(stmt)) { var fmBsi = this.blockStartInfos.ValueOrDefault(stmt); var fmChanges = this.stmtVarsChanged.ValueOrDefault(stmt); if (fmBsi != null && fmChanges != null) { var fmStack = fmBsi.Stack.Take(fmChanges.Stack.Length).Select((x, i) => fmChanges.Stack[i] ? x : null).ToArray(); var fmLocals = fmBsi.Locals.Take(fmChanges.Locals.Length).Select((x, i) => fmChanges.Locals[i] ? x : null).ToArray(); var fmArgs = fmBsi.Args.Take(fmChanges.Args.Length).Select((x, i) => fmChanges.Args[i] ? x : null).ToArray(); if (fmStack.Any(x => x != null) || fmLocals.Any(x => x != null) || fmArgs.Any(x => x != null)) { var fmConts = VisitorFindContinuations.Get(stmt); foreach (var fmCont in fmConts) { var fmContBsi = this.blockStartInfos.ValueOrDefault(fmCont.To); if (fmContBsi != null) { merge(fmContBsi.Stack, fmStack); merge(fmContBsi.Locals, fmLocals); merge(fmContBsi.Args, fmArgs); forwardMerge(fmCont.To); } } } } } }; forwardMerge(s); } }
private Stmt ParseStmt() { Stmt result = null; if (this.index == this.tokens.Count) { throw new System.Exception("expected statement, got EOF"); } // <stmt> := print <expr> // <expr> := <string> // | <int> // | <arith_expr> // | <ident> if (this.tokens[this.index].Equals(languageSetting["End"])) { this.index++; } else if (this.tokens[this.index].Equals(languageSetting["Start"])) { this.index++; return(ParseStmt()); } else if (this.tokens[this.index].Equals(languageSetting["Print"])) { this.index++; Print print = new Print(); print.Expr = this.ParseExpr(); result = print; } else if (this.tokens[this.index] == Scanner.Call) { VoidMethodCall vmc = new VoidMethodCall(); vmc.Expr = this.ParseExpr(); result = vmc; } else if (this.tokens[this.index].Equals(languageSetting["VariableDeclaration"])) { this.index++; DeclareVar declareVar = new DeclareVar(); if (this.index < this.tokens.Count && this.tokens[this.index] is string) { declareVar.Ident = (string)this.tokens[this.index]; } else { throw new System.Exception("expected variable name after 'var'"); } this.index++; if (this.index == this.tokens.Count || this.tokens[this.index] != Scanner.Equal) { throw new System.Exception("expected = after 'var ident'"); } this.index++; declareVar.Expr = this.ParseExpr(); result = declareVar; } else if (this.tokens[this.index].Equals(languageSetting["if"])) { this.index++; IfCondition ifCon = new IfCondition(); ifCon.BooleanExp = this.ParseExpr(); if (!this.tokens[++this.index].Equals(languageSetting["Start"])) { throw new System.Exception("Start Expected"); } ifCon.Body = this.ParseStmt(); if (!this.tokens[this.index++].Equals(languageSetting["End"])) { throw new System.Exception("End Expected"); } result = ifCon; } else if (this.tokens[this.index].Equals(languageSetting["while"])) { this.index++; WhileLoop whileLoop = new WhileLoop(); whileLoop.BooleanExp = this.ParseExpr(); if (!this.tokens[++this.index].Equals(languageSetting["Start"])) { throw new System.Exception("Start Expected"); } whileLoop.Body = this.ParseStmt(); if (!this.tokens[this.index++].Equals(languageSetting["End"])) { throw new System.Exception("End Expected"); } result = whileLoop; } else if (this.tokens[this.index].Equals("read_int")) { this.index++; ReadInt readInt = new ReadInt(); if (this.index < this.tokens.Count && this.tokens[this.index] is string) { readInt.Ident = (string)this.tokens[this.index++]; result = readInt; } else { throw new System.Exception("expected variable name after 'read_int'"); } } else if (this.tokens[this.index].Equals("for")) { this.index++; ForLoop forLoop = new ForLoop(); if (this.index < this.tokens.Count && this.tokens[this.index] is string) { forLoop.Ident = (string)this.tokens[this.index]; } else { throw new System.Exception("expected identifier after 'for'"); } this.index++; if (this.index == this.tokens.Count || this.tokens[this.index] != Scanner.Equal) { throw new System.Exception("for missing '='"); } this.index++; forLoop.From = this.ParseSingleExpression(); if (this.index == this.tokens.Count || !this.tokens[this.index].Equals("to")) { throw new System.Exception("expected 'to' after for"); } this.index++; forLoop.To = this.ParseSingleExpression(); if (this.index == this.tokens.Count || !this.tokens[this.index].Equals("do")) { throw new System.Exception("expected 'do' after from expression in for loop"); } this.index++; forLoop.Body = this.ParseStmt(); result = forLoop; if (this.index == this.tokens.Count || !this.tokens[this.index].Equals("end")) { throw new System.Exception("unterminated 'for' loop body"); } this.index++; } else if (this.tokens[this.index] is string) { // assignment Assign assign = new Assign(); assign.Ident = (string)this.tokens[this.index++]; if (this.index == this.tokens.Count || this.tokens[this.index] != Scanner.Equal) { throw new System.Exception("expected '='"); } this.index++; assign.Expr = this.ParseExpr(); result = assign; } else { throw new System.Exception("parse error at token " + this.index + ": " + this.tokens[this.index]); } if (this.index < this.tokens.Count && this.tokens[this.index] == Scanner.Semi) { this.index++; if (this.index < this.tokens.Count && !this.tokens[this.index].Equals(languageSetting["End"])) { Sequence sequence = new Sequence(); sequence.First = result; sequence.Second = this.ParseStmt(); result = sequence; } } return(result); }
public bool VisitStmt(Stmt stmt) { throw new NotImplementedException(); }
public Stmt IfThen(Expr cond, Stmt then) { return null; }
public TrashObject Execute(Stmt stmt) { return(stmt.Accept(this)); }
public Stmt IfThenElse(Expr cond, Stmt t, Stmt e) { return null; }
private void GenStmt(Stmt stmt) { if (stmt is Sequence) { var seq = (Sequence)stmt; GenStmt(seq.First); GenStmt(seq.Second); } else if (stmt is DeclareVariable) { // declare a local var declare = (DeclareVariable)stmt; SymbolTable[declare.Ident] = _il.DeclareLocal(declare.Expr.GetType()); // set the initial value var assign = new Assign { Ident = declare.Ident, Expr = declare.Expr }; GenStmt(assign); } else if (stmt is Assign) { var assign = (Assign)stmt; GenerateLoadToStackForExpr(assign.Expr, assign.Expr.GetType()); GenerateStoreFromStack(assign.Ident, assign.Expr.GetType()); } else if (stmt is ConsoleOut) { // the "ConsoleOut" statement is an alias for System.Console.WriteLine. // it uses the string case GenerateLoadToStackForExpr(((ConsoleOut)stmt).Expr, typeof(string)); //Generate console.writeline _il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new[] { typeof(string) })); } else if (stmt is ReadConsoleIn) { _il.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadLine", BindingFlags.Public | BindingFlags.Static, null, new Type[] { }, null)); Type identType = GetIdentType(stmt); if(identType == typeof(int)) _il.Emit(OpCodes.Call, typeof(int).GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(string) }, null)); GenerateStoreFromStack(((ReadConsoleIn)stmt).Ident, identType); } else if (stmt is ForLoop) { // example: // for x = 0 to 100 up // "hello"; // end; // x = 0 var forLoop = (ForLoop)stmt; var assign = new Assign { Ident = forLoop.Ident, Expr = forLoop.From }; GenStmt(assign); // jump to the test var test = _il.DefineLabel(); _il.Emit(OpCodes.Br, test); // statements in the body of the for loop var body = _il.DefineLabel(); _il.MarkLabel(body); GenStmt(forLoop.Body); // to (increment the value of x) _il.Emit(OpCodes.Ldloc, SymbolTable[forLoop.Ident]); _il.Emit(OpCodes.Ldc_I4, 1); _il.Emit(forLoop.Type == ArithOp.Up ? OpCodes.Add : OpCodes.Sub); GenerateStoreFromStack(forLoop.Ident, typeof(int)); // **test** does x equal 100? (do the test) _il.MarkLabel(test); _il.Emit(OpCodes.Ldloc, SymbolTable[forLoop.Ident]); GenerateLoadToStackForExpr(forLoop.To, typeof(int)); _il.Emit(forLoop.Type == ArithOp.Up ? OpCodes.Blt : OpCodes.Bgt, body); } else { throw new Exception("don't know how to gen a " + stmt.GetType().Name); } }
public IfStmt(token.Pos If = default, Stmt Init = default, Expr Cond = default, ref ptr <BlockStmt> Body = default, Stmt Else = default) { this.If = If; this.Init = Init; this.Cond = Cond; this.Body = Body; this.Else = Else; }
public StmtDefer(Stmt stmt) { this.Stmt = stmt; }
public While() { this.Expr = null; this.Stmt = null; }