private bool ParseTermExpression(TokenReader reader, out Expression result) { result = null; Token start = reader.Peek(); Expression outer = null; if (!this.ParseFactorExpression(reader, out outer)) { return false; } Token tok = reader.Peek(); while (tok.Is(Keyword.Star) || tok.Is(Keyword.Slash) || tok.Is(Keyword.Div) || tok.Is(Keyword.And) || tok.Is(Keyword.Mod)) { reader.Read(); Expression factor = null; if (!this.ParseFactorExpression(reader, out factor)) { return false; } outer = new TermExpression(start, outer, ((KeywordToken)tok).Value, factor); tok = reader.Peek(); } result = outer; return true; }
private bool TryEmitTermExpression( TermExpression 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.Star: { method.Statements.Add(new AsmStatement { Instruction = "fmulp" }); } break; case Keyword.Slash: { method.Statements.Add(new AsmStatement { Instruction = "fdivp" }); } 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.Star: { method.Statements.Add(new AsmStatement { Instruction = "imul eax,ecx" }); } break; case Keyword.Mod: { method.Statements.Add(new AsmStatement { Instruction = "xor edx,edx" }); method.Statements.Add(new AsmStatement { Instruction = "idiv ecx" }); method.Statements.Add(new AsmStatement { Instruction = "mov eax,edx" }); } break; case Keyword.And: { method.Statements.Add(new AsmStatement { Instruction = "and eax,ecx" }); } break; case Keyword.Div: { method.Statements.Add(new AsmStatement { Instruction = "xor edx,edx" }); method.Statements.Add(new AsmStatement { Instruction = "idiv ecx" }); } break; } } } valueType = leftSideType; return true; }