예제 #1
0
		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);
		}
예제 #2
0
 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);
 }
예제 #3
0
		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;
			}
		}
예제 #4
0
 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;
 }
예제 #5
0
 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;
 }
예제 #6
0
 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;
 }
예제 #7
0
 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;
 }
예제 #8
0
 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;
 }
예제 #9
0
 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;
 }
예제 #10
0
 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;
 }
예제 #11
0
		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);
			}
		}
예제 #12
0
 public void Accept(BinaryExpression binop)
 {
     binop.Visit (functionCompiler);
 }
예제 #13
0
파일: Parser.cs 프로젝트: iwatakeshi/Iodine
 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;
 }
예제 #14
0
 public virtual void Accept(BinaryExpression binop)
 {
 }
예제 #15
0
 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;
 }
예제 #16
0
 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;
 }
예제 #17
0
 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;
 }
예제 #18
0
 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;
 }
예제 #19
0
		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);
		}