private bool ParseSimpleExpression(TokenReader reader, out Expression result) { Token start = reader.Peek(); result = null; Expression outer = null; if (!this.ParseTermExpression(reader, out outer)) { return false; } Token tok = reader.Peek(); while (tok.Is(Keyword.Plus) || tok.Is(Keyword.Minus) || tok.Is(Keyword.Or)) { reader.Read(); Expression term = null; if (!this.ParseTermExpression(reader, out term)) { return false; } outer = new SimpleExpression(start, outer, ((KeywordToken)tok).Value, term); tok = reader.Peek(); } result = outer; return true; }
private bool TryEmitSimpleExpression( SimpleExpression expression, CompilerContext context, Scope scope, MethodImpl method, out TypeDefinition valueType) { TypeDefinition rightSideType = null; if (!this.TryEmitExpression(expression.Right, context, scope, method, out rightSideType)) { valueType = null; return false; } this.PushResult(method, rightSideType); TypeDefinition leftSideType = null; if (!this.TryEmitExpression(expression.Left, context, scope, method, out leftSideType)) { valueType = null; return false; } if (leftSideType.IsFloatingPoint) { if (rightSideType.IsFloatingPoint) { if (rightSideType.Size == 8) { method.Statements.Add(new AsmStatement { Instruction = "fld qword ptr [esp]" }); } else { method.Statements.Add(new AsmStatement { Instruction = "fld dword ptr [esp]" }); } method.Statements.Add(new AsmStatement { Instruction = "add esp," + rightSideType.Size }); } else if (rightSideType.Size <= 4) { method.Statements.Add(new AsmStatement { Instruction = "fild [esp]" }); method.Statements.Add(new AsmStatement { Instruction = "add esp," + rightSideType.Size }); } switch (expression.Operator) { case Keyword.Plus: { method.Statements.Add(new AsmStatement { Instruction = "faddp" }); } break; case Keyword.Minus: { method.Statements.Add(new AsmStatement { Instruction = "fsubp" }); } break; } } else if (leftSideType.Size <= 4) { if (rightSideType.Size <= 4 && !rightSideType.IsFloatingPoint) { method.Statements.Add(new AsmStatement { Instruction = "pop ecx" }); switch (expression.Operator) { case Keyword.Plus: { method.Statements.Add(new AsmStatement { Instruction = "add eax,ecx" }); } break; case Keyword.Minus: { method.Statements.Add(new AsmStatement { Instruction = "sub eax,ecx" }); } break; case Keyword.Or: { method.Statements.Add(new AsmStatement { Instruction = "or eax,ecx" }); } break; } } } valueType = leftSideType; return true; }