public override void Accept(TupleExpression tuple) { IodineLabel startLabel = methodBuilder.CreateLabel(); IodineLabel endLabel = methodBuilder.CreateLabel(); int item = methodBuilder.CreateTemporary(); PatternCompiler compiler = new PatternCompiler(symbolTable, methodBuilder, item, parentVisitor); for (int i = 0; i < tuple.Children.Count; i++) { if (tuple.Children [i] is NameExpression && ((NameExpression)tuple.Children [i]).Value == "_") { continue; } methodBuilder.EmitInstruction(tuple.Location, Opcode.LoadLocal, temporary); methodBuilder.EmitInstruction(tuple.Location, Opcode.LoadConst, methodBuilder.Module.DefineConstant(new IodineInteger(i))); methodBuilder.EmitInstruction(tuple.Location, Opcode.LoadIndex); methodBuilder.EmitInstruction(tuple.Location, Opcode.StoreLocal, item); tuple.Children [i].Visit(compiler); methodBuilder.EmitInstruction(tuple.Location, Opcode.JumpIfFalse, endLabel); } methodBuilder.EmitInstruction(tuple.Location, Opcode.LoadTrue); methodBuilder.EmitInstruction(tuple.Location, Opcode.Jump, startLabel); methodBuilder.MarkLabelPosition(endLabel); methodBuilder.EmitInstruction(tuple.Location, Opcode.LoadFalse); methodBuilder.MarkLabelPosition(startLabel); }
public override void Accept(MatchExpression match) { AstNode value = match.Children [0]; value.Visit(this); int temporary = methodBuilder.CreateTemporary(); methodBuilder.EmitInstruction(match.Location, Opcode.StoreLocal, temporary); PatternCompiler compiler = new PatternCompiler(symbolTable, methodBuilder, temporary, this); IodineLabel nextLabel = methodBuilder.CreateLabel(); IodineLabel endLabel = methodBuilder.CreateLabel(); for (int i = 1; i < match.Children.Count; i++) { if (i > 1) { methodBuilder.MarkLabelPosition(nextLabel); nextLabel = methodBuilder.CreateLabel(); } CaseExpression clause = match.Children [i] as CaseExpression; clause.Pattern.Visit(compiler); methodBuilder.EmitInstruction(match.Location, Opcode.JumpIfFalse, nextLabel); if (clause.Condition != null) { clause.Condition.Visit(this); methodBuilder.EmitInstruction(match.Location, Opcode.JumpIfFalse, nextLabel); } clause.Value.Visit(this); methodBuilder.EmitInstruction(match.Location, Opcode.Jump, endLabel); } methodBuilder.MarkLabelPosition(endLabel); }
public override void Accept(ForeachStatement foreachStmt) { IodineLabel foreachLabel = methodBuilder.CreateLabel(); IodineLabel breakLabel = methodBuilder.CreateLabel(); breakLabels.Push(breakLabel); continueLabels.Push(foreachLabel); foreachStmt.Iterator.Visit(this); int tmp = methodBuilder.CreateTemporary(); methodBuilder.EmitInstruction(foreachStmt.Iterator.Location, Opcode.Dup); methodBuilder.EmitInstruction(foreachStmt.Iterator.Location, Opcode.StoreLocal, tmp); methodBuilder.EmitInstruction(foreachStmt.Iterator.Location, Opcode.IterReset); methodBuilder.MarkLabelPosition(foreachLabel); methodBuilder.EmitInstruction(foreachStmt.Iterator.Location, Opcode.LoadLocal, tmp); methodBuilder.EmitInstruction(foreachStmt.Iterator.Location, Opcode.IterMoveNext); methodBuilder.EmitInstruction(foreachStmt.Iterator.Location, Opcode.JumpIfFalse, breakLabel); methodBuilder.EmitInstruction(foreachStmt.Iterator.Location, Opcode.LoadLocal, tmp); methodBuilder.EmitInstruction(foreachStmt.Iterator.Location, Opcode.IterGetNext); methodBuilder.EmitInstruction(foreachStmt.Iterator.Location, Opcode.StoreLocal, symbolTable.GetSymbol (foreachStmt.Item).Index); foreachStmt.Body.Visit(this); methodBuilder.EmitInstruction(foreachStmt.Body.Location, Opcode.Jump, foreachLabel); methodBuilder.MarkLabelPosition(breakLabel); breakLabels.Pop(); continueLabels.Pop(); }
public override void Accept(TryExceptStatement tryExcept) { IodineLabel exceptLabel = methodBuilder.CreateLabel(); IodineLabel endLabel = methodBuilder.CreateLabel(); methodBuilder.EmitInstruction(tryExcept.Location, Opcode.PushExceptionHandler, exceptLabel); tryExcept.TryBody.Visit(this); methodBuilder.EmitInstruction(tryExcept.TryBody.Location, Opcode.PopExceptionHandler); methodBuilder.EmitInstruction(tryExcept.TryBody.Location, Opcode.Jump, endLabel); methodBuilder.MarkLabelPosition(exceptLabel); tryExcept.TypeList.Visit(this); if (tryExcept.TypeList.Children.Count > 0) { methodBuilder.EmitInstruction(tryExcept.ExceptBody.Location, Opcode.BeginExcept, tryExcept.TypeList.Children.Count); } if (tryExcept.ExceptionIdentifier != null) { methodBuilder.EmitInstruction(tryExcept.ExceptBody.Location, Opcode.LoadException); methodBuilder.EmitInstruction(tryExcept.ExceptBody.Location, Opcode.StoreLocal, symbolTable.GetSymbol(tryExcept.ExceptionIdentifier).Index); } tryExcept.ExceptBody.Visit(this); methodBuilder.MarkLabelPosition(endLabel); }
public override void Accept(TernaryExpression ifExpr) { IodineLabel elseLabel = methodBuilder.CreateLabel(); IodineLabel endLabel = methodBuilder.CreateLabel(); ifExpr.Condition.Visit(this); methodBuilder.EmitInstruction(ifExpr.Expression.Location, Opcode.JumpIfFalse, elseLabel); ifExpr.Expression.Visit(this); methodBuilder.EmitInstruction(ifExpr.ElseExpression.Location, Opcode.Jump, endLabel); methodBuilder.MarkLabelPosition(elseLabel); ifExpr.ElseExpression.Visit(this); methodBuilder.MarkLabelPosition(endLabel); }
public override void Accept(IfStatement ifStmt) { IodineLabel elseLabel = methodBuilder.CreateLabel(); IodineLabel endLabel = methodBuilder.CreateLabel(); ifStmt.Condition.Visit(this); methodBuilder.EmitInstruction(ifStmt.Body.Location, Opcode.JumpIfFalse, elseLabel); ifStmt.Body.Visit(this); methodBuilder.EmitInstruction(ifStmt.ElseBody.Location, Opcode.Jump, endLabel); methodBuilder.MarkLabelPosition(elseLabel); ifStmt.ElseBody.Visit(this); methodBuilder.MarkLabelPosition(endLabel); }
public override void Accept(GivenStatement switchStmt) { foreach (AstNode node in switchStmt.WhenStatements.Children) { WhenStatement caseStmt = node as WhenStatement; caseStmt.Values.Visit(this); caseStmt.Body.Visit(this); } switchStmt.GivenValue.Visit(this); methodBuilder.EmitInstruction(switchStmt.Location, Opcode.SwitchLookup, switchStmt.WhenStatements.Children.Count); IodineLabel endLabel = methodBuilder.CreateLabel(); methodBuilder.EmitInstruction(switchStmt.Location, Opcode.JumpIfTrue, endLabel); switchStmt.DefaultStatement.Visit(this); methodBuilder.MarkLabelPosition(endLabel); }
public override void Accept(DoStatement doStmt) { IodineLabel doLabel = methodBuilder.CreateLabel(); IodineLabel breakLabel = methodBuilder.CreateLabel(); breakLabels.Push(breakLabel); continueLabels.Push(doLabel); methodBuilder.MarkLabelPosition(doLabel); doStmt.Body.Visit(this); doStmt.Condition.Visit(this); methodBuilder.EmitInstruction(doStmt.Condition.Location, Opcode.JumpIfTrue, doLabel); methodBuilder.MarkLabelPosition(breakLabel); breakLabels.Pop(); continueLabels.Pop(); }
public override void Accept(WhileStatement whileStmt) { IodineLabel whileLabel = methodBuilder.CreateLabel(); IodineLabel breakLabel = methodBuilder.CreateLabel(); breakLabels.Push(breakLabel); continueLabels.Push(whileLabel); methodBuilder.MarkLabelPosition(whileLabel); whileStmt.Condition.Visit(this); methodBuilder.EmitInstruction(whileStmt.Condition.Location, Opcode.JumpIfFalse, breakLabel); whileStmt.Body.Visit(this); methodBuilder.EmitInstruction(whileStmt.Body.Location, Opcode.Jump, whileLabel); methodBuilder.MarkLabelPosition(breakLabel); breakLabels.Pop(); continueLabels.Pop(); }
public override void Accept(ListCompExpression list) { IodineLabel foreachLabel = methodBuilder.CreateLabel(); IodineLabel breakLabel = methodBuilder.CreateLabel(); IodineLabel predicateSkip = methodBuilder.CreateLabel(); int tmp = methodBuilder.CreateTemporary(); int set = methodBuilder.CreateTemporary(); methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.BuildList, 0); methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.StoreLocal, set); symbolTable.NextScope(); list.Iterator.Visit(this); methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.Dup); methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.StoreLocal, tmp); methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.IterReset); methodBuilder.MarkLabelPosition(foreachLabel); methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.LoadLocal, tmp); methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.IterMoveNext); methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.JumpIfFalse, breakLabel); methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.LoadLocal, tmp); methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.IterGetNext); methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.StoreLocal, symbolTable.GetSymbol (list.Identifier).Index); if (list.Predicate != null) { list.Predicate.Visit(this); methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.JumpIfFalse, predicateSkip); } list.Expression.Visit(this); methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.LoadLocal, set); methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.LoadAttribute, methodBuilder.Module.DefineConstant(new IodineName("add"))); methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.Invoke, 1); methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.Pop); if (list.Predicate != null) { methodBuilder.MarkLabelPosition(predicateSkip); } methodBuilder.EmitInstruction(list.Expression.Location, Opcode.Jump, foreachLabel); methodBuilder.MarkLabelPosition(breakLabel); methodBuilder.EmitInstruction(list.Iterator.Location, Opcode.LoadLocal, set); symbolTable.LeaveScope(); }
public override void Accept(ForStatement forStmt) { IodineLabel forLabel = methodBuilder.CreateLabel(); IodineLabel breakLabel = methodBuilder.CreateLabel(); IodineLabel skipAfterThought = methodBuilder.CreateLabel(); breakLabels.Push(breakLabel); continueLabels.Push(forLabel); forStmt.Initializer.Visit(this); methodBuilder.EmitInstruction(forStmt.Location, Opcode.Jump, skipAfterThought); methodBuilder.MarkLabelPosition(forLabel); forStmt.AfterThought.Visit(this); methodBuilder.MarkLabelPosition(skipAfterThought); forStmt.Condition.Visit(this); methodBuilder.EmitInstruction(forStmt.Condition.Location, Opcode.JumpIfFalse, breakLabel); forStmt.Body.Visit(this); forStmt.AfterThought.Visit(this); methodBuilder.EmitInstruction(forStmt.AfterThought.Location, Opcode.Jump, skipAfterThought); methodBuilder.MarkLabelPosition(breakLabel); breakLabels.Pop(); continueLabels.Pop(); }
public override void Accept(BinaryExpression pattern) { IodineLabel shortCircuitTrueLabel = methodBuilder.CreateLabel(); IodineLabel shortCircuitFalseLabel = methodBuilder.CreateLabel(); IodineLabel endLabel = methodBuilder.CreateLabel(); pattern.Left.Visit(this); /* * Short circuit evaluation */ switch (pattern.Operation) { case BinaryOperation.And: methodBuilder.EmitInstruction(pattern.Location, Opcode.Dup); methodBuilder.EmitInstruction(pattern.Location, Opcode.JumpIfFalse, shortCircuitFalseLabel); break; case BinaryOperation.Or: methodBuilder.EmitInstruction(pattern.Location, Opcode.Dup); methodBuilder.EmitInstruction(pattern.Location, Opcode.JumpIfTrue, shortCircuitTrueLabel); break; } pattern.Right.Visit(this); methodBuilder.EmitInstruction(pattern.Location, Opcode.BinOp, (int)pattern.Operation); methodBuilder.EmitInstruction(pattern.Location, Opcode.Jump, endLabel); methodBuilder.MarkLabelPosition(shortCircuitTrueLabel); methodBuilder.EmitInstruction(pattern.Location, Opcode.Pop); methodBuilder.EmitInstruction(pattern.Location, Opcode.LoadTrue); methodBuilder.EmitInstruction(pattern.Location, Opcode.Jump, endLabel); methodBuilder.MarkLabelPosition(shortCircuitFalseLabel); methodBuilder.EmitInstruction(pattern.Location, Opcode.Pop); methodBuilder.EmitInstruction(pattern.Location, Opcode.LoadFalse); methodBuilder.MarkLabelPosition(endLabel); }
public override void Accept(BinaryExpression binop) { if (binop.Operation == BinaryOperation.Assign) { binop.Right.Visit(this); if (binop.Left is NameExpression) { NameExpression ident = (NameExpression)binop.Left; Symbol sym = symbolTable.GetSymbol(ident.Value); if (sym.Type == SymbolType.Local) { methodBuilder.EmitInstruction(ident.Location, Opcode.StoreLocal, sym.Index); methodBuilder.EmitInstruction(ident.Location, Opcode.LoadLocal, sym.Index); } else { int globalIndex = methodBuilder.Module.DefineConstant(new IodineName(ident.Value)); methodBuilder.EmitInstruction(ident.Location, Opcode.StoreGlobal, globalIndex); methodBuilder.EmitInstruction(ident.Location, Opcode.LoadGlobal, globalIndex); } } else if (binop.Left is GetExpression) { GetExpression getattr = binop.Left as GetExpression; getattr.Target.Visit(this); int attrIndex = methodBuilder.Module.DefineConstant(new IodineName(getattr.Field)); methodBuilder.EmitInstruction(getattr.Location, Opcode.StoreAttribute, attrIndex); getattr.Target.Visit(this); methodBuilder.EmitInstruction(getattr.Location, Opcode.LoadAttribute, attrIndex); } else if (binop.Left is IndexerExpression) { IndexerExpression indexer = binop.Left as IndexerExpression; indexer.Target.Visit(this); indexer.Index.Visit(this); methodBuilder.EmitInstruction(indexer.Location, Opcode.StoreIndex); binop.Left.Visit(this); } } else if (binop.Operation == BinaryOperation.InstanceOf) { binop.Right.Visit(this); binop.Left.Visit(this); methodBuilder.EmitInstruction(binop.Location, Opcode.InstanceOf); } else if (binop.Operation == BinaryOperation.NotInstanceOf) { binop.Right.Visit(this); binop.Left.Visit(this); methodBuilder.EmitInstruction(binop.Location, Opcode.InstanceOf); methodBuilder.EmitInstruction(binop.Location, Opcode.UnaryOp, (int)UnaryOperation.BoolNot); } else if (binop.Operation == BinaryOperation.DynamicCast) { binop.Right.Visit(this); binop.Left.Visit(this); methodBuilder.EmitInstruction(binop.Location, Opcode.DynamicCast); } else if (binop.Operation == BinaryOperation.NullCoalescing) { binop.Right.Visit(this); binop.Left.Visit(this); methodBuilder.EmitInstruction(binop.Location, Opcode.NullCoalesce); } else { IodineLabel shortCircuitTrueLabel = methodBuilder.CreateLabel(); IodineLabel shortCircuitFalseLabel = methodBuilder.CreateLabel(); IodineLabel endLabel = methodBuilder.CreateLabel(); binop.Left.Visit(this); /* * Short circuit evaluation */ switch (binop.Operation) { case BinaryOperation.BoolAnd: methodBuilder.EmitInstruction(binop.Location, Opcode.Dup); methodBuilder.EmitInstruction(binop.Location, Opcode.JumpIfFalse, shortCircuitFalseLabel); break; case BinaryOperation.BoolOr: methodBuilder.EmitInstruction(binop.Location, Opcode.Dup); methodBuilder.EmitInstruction(binop.Location, Opcode.JumpIfTrue, shortCircuitTrueLabel); break; } binop.Right.Visit(this); methodBuilder.EmitInstruction(binop.Location, Opcode.BinOp, (int)binop.Operation); methodBuilder.EmitInstruction(binop.Location, Opcode.Jump, endLabel); methodBuilder.MarkLabelPosition(shortCircuitTrueLabel); methodBuilder.EmitInstruction(binop.Location, Opcode.Pop); methodBuilder.EmitInstruction(binop.Location, Opcode.LoadTrue); methodBuilder.EmitInstruction(binop.Location, Opcode.Jump, endLabel); methodBuilder.MarkLabelPosition(shortCircuitFalseLabel); methodBuilder.EmitInstruction(binop.Location, Opcode.Pop); methodBuilder.EmitInstruction(binop.Location, Opcode.LoadFalse); methodBuilder.MarkLabelPosition(endLabel); } }