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 void Accept(BinaryExpression binop) { if (binop.Operation == BinaryOperation.Assign) { if (binop.Left is NameExpression) { NameExpression ident = (NameExpression)binop.Left; if (!this.symbolTable.IsSymbolDefined (ident.Value)) { this.symbolTable.AddSymbol (ident.Value); } } } binop.VisitChildren (this); }
public override void Accept (BinaryExpression pattern) { switch (pattern.Operation) { case BinaryOperation.Or: case BinaryOperation.And: pattern.Left.Visit (this); pattern.Right.Visit (this); break; default: errorLog.AddError (ErrorType.ParserError, pattern.Location, "Binary operator can not be used on patterns!"); break; } }
public static AstNode ParseAdditive(TokenStream stream) { AstNode expr = ParseMultiplicative (stream); while (stream.Match (TokenClass.Operator)) { switch (stream.Current.Value) { case "+": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.Add, expr, ParseMultiplicative (stream)); continue; case "-": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.Sub, expr, ParseMultiplicative (stream)); continue; default: break; } break; } return expr; }
private static AstNode ParseBoolAnd(TokenStream stream) { AstNode expr = ParseOr (stream); while (stream.Accept (TokenClass.Operator, "&&")) { expr = new BinaryExpression (stream.Location, BinaryOperation.BoolAnd, expr, ParseOr (stream)); } return expr; }
private static AstNode ParseAssign(TokenStream stream) { AstNode expr = ParseTernaryIfElse (stream); while (stream.Match (TokenClass.Operator)) { switch (stream.Current.Value) { case "=": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.Assign, expr, ParseTernaryIfElse (stream)); continue; case "+=": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.Assign, expr, new BinaryExpression (stream.Location, BinaryOperation.Add, expr, ParseTernaryIfElse (stream))); continue; case "-=": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.Assign, expr, new BinaryExpression (stream.Location, BinaryOperation.Sub, expr, ParseTernaryIfElse (stream))); continue; case "*=": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.Assign, expr, new BinaryExpression (stream.Location, BinaryOperation.Mul, expr, ParseTernaryIfElse (stream))); continue; case "/=": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.Assign, expr, new BinaryExpression (stream.Location, BinaryOperation.Div, expr, ParseTernaryIfElse (stream))); continue; case "%=": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.Assign, expr, new BinaryExpression (stream.Location, BinaryOperation.Mod, expr, ParseTernaryIfElse (stream))); continue; case "^=": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.Assign, expr, new BinaryExpression (stream.Location, BinaryOperation.Xor, expr, ParseTernaryIfElse (stream))); continue; case "&=": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.Assign, expr, new BinaryExpression (stream.Location, BinaryOperation.And, expr, ParseTernaryIfElse (stream))); continue; case "|=": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.Assign, expr, new BinaryExpression (stream.Location, BinaryOperation.Or, expr, ParseTernaryIfElse (stream))); continue; case "<<=": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.Assign, expr, new BinaryExpression (stream.Location, BinaryOperation.LeftShift, expr, ParseTernaryIfElse (stream))); continue; case ">>=": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.Assign, expr, new BinaryExpression (stream.Location, BinaryOperation.RightShift, expr, ParseTernaryIfElse (stream))); continue; default: break; } break; } return expr; }
public static AstNode ParseRelationalOp(TokenStream stream) { AstNode expr = ParseBitshift (stream); while (stream.Match (TokenClass.Operator)) { switch (stream.Current.Value) { case ">": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.GreaterThan, expr, ParseBitshift (stream)); continue; case "<": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.LessThan, expr, ParseBitshift (stream)); continue; case ">=": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.GreaterThanOrEqu, expr, ParseBitshift (stream)); continue; case "<=": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.LessThanOrEqu, expr, ParseBitshift (stream)); continue; case "is": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.InstanceOf, expr, ParseBitshift (stream)); continue; case "isnot": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.NotInstanceOf, expr, ParseBitshift (stream)); continue; case "as": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.DynamicCast, expr, ParseBitshift (stream)); continue; default: break; } break; } return expr; }
public static AstNode ParseOr(TokenStream stream) { AstNode expr = ParseXor (stream); while (stream.Accept (TokenClass.Operator, "|")) { expr = new BinaryExpression (stream.Location, BinaryOperation.Or, expr, ParseXor (stream)); } return expr; }
public static AstNode ParseEquals(TokenStream stream) { AstNode expr = ParseRelationalOp (stream); while (stream.Match (TokenClass.Operator)) { switch (stream.Current.Value) { case "==": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.Equals, expr, ParseRelationalOp (stream)); continue; case "!=": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.NotEquals, expr, ParseRelationalOp (stream)); continue; default: break; } break; } return expr; }
public static AstNode ParseAnd(TokenStream stream) { AstNode expr = ParseEquals (stream); while (stream.Accept (TokenClass.Operator, "&")) { expr = new BinaryExpression (stream.Location, BinaryOperation.And, expr, ParseEquals (stream)); } return expr; }
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); } }
public void Accept(BinaryExpression binop) { binop.Visit (functionCompiler); }
public static AstNode ParseMulDivMod(TokenStream stream) { AstNode expr = ParseUnary (stream); while (stream.Match (TokenClass.Operator)) { switch (stream.Current.Value) { case "*": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.Mul, expr, ParseUnary (stream)); continue; case "/": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.Div, expr, ParseUnary (stream)); continue; case "%": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.Mod, expr, ParseUnary (stream)); continue; default: break; } break; } return expr; }
public virtual void Accept(BinaryExpression binop) { }
private static AstNode ParseBoolOr(TokenStream stream) { AstNode expr = ParseBoolAnd (stream); while (stream.Match (TokenClass.Operator)) { switch (stream.Current.Value) { case "||": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.BoolOr, expr, ParseBoolAnd (stream)); continue; case "??": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.NullCoalescing, expr, ParseBoolAnd (stream)); continue; default: break; } break; } return expr; }
public static AstNode ParseBitshift(TokenStream stream) { AstNode expr = ParseAdditive (stream); while (stream.Match (TokenClass.Operator)) { switch (stream.Current.Value) { case "<<": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.LeftShift, expr, ParseAdditive (stream)); continue; case ">>": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.RightShift, expr, ParseAdditive (stream)); continue; default: break; } break; } return expr; }
private static AstNode ParseRange(TokenStream stream) { AstNode expr = ParseBoolOr (stream); while (stream.Match (TokenClass.Operator)) { switch (stream.Current.Value) { case "...": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.ClosedRange, expr, ParseBoolOr (stream)); continue; case "..": stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.HalfRange, expr, ParseBoolOr (stream)); continue; default: break; } break; } return expr; }
private static AstNode ParsePatternOr(TokenStream stream) { AstNode expr = ParsePatternAnd (stream); while (stream.Match (TokenClass.Operator, "|")) { stream.Accept (TokenClass.Operator); expr = new BinaryExpression (stream.Location, BinaryOperation.Or, expr, ParsePatternAnd (stream)); } return expr; }
public override void Accept (BinaryExpression binop) { if (binop.Operation == BinaryOperation.Assign) { if (binop.Left is NameExpression) { NameExpression ident = (NameExpression)binop.Left; if (!symbolTable.IsSymbolDefined (ident.Value)) { symbolTable.AddSymbol (ident.Value); } } } binop.Right.Visit (this); }