private bool ParseStatement(TokenReader reader, out Statement result) { result = null; Token tok = reader.Peek(); Token start = tok; if (tok.Is(Keyword.SemiColon)) { return true; // empty statement. } if (tok.Is(Keyword.If)) { return this.ParseIfStatement(reader, out result); } if (tok.Is(Keyword.While)) { return this.ParseWhileStatement(reader, out result); } if (tok.Is(Keyword.Delete)) { return this.ParseDeleteStatement(reader, out result); } if (tok.Is(Keyword.Begin)) { BlockStatement block = null; bool success = this.ParseBlockStatement(reader, out block); result = block; return success; } ReferenceExpression lhs = null; if (!this.ParseReferenceExpression(reader, out lhs)) { return false; } tok = reader.Peek(); if (tok.Is(Keyword.Assign)) { reader.Read(); Expression rhs = null; if (!this.ParseExpression(reader, out rhs)) { return false; } result = new AssignmentStatement(start, lhs, rhs); return true; } else { result = new CallStatement(start, lhs); return true; } }
private bool TryEmitAssignment( AssignmentStatement assignmentStatement, CompilerContext context, Scope scope, MethodImpl method) { string location = null; TypeDefinition storageType = null; TypeDefinition valueType = null; if (!this.TryEmitExpression(assignmentStatement.Value, context, scope, method, out valueType)) { return false; } this.PushResult(method, valueType); MethodInfo calleeMethod = null; if (!this.TryEmitReference(assignmentStatement.Storage, context, scope, method, out location, out storageType, out calleeMethod)) { return false; } if (!this.ValidateCanCast(assignmentStatement, storageType, valueType)) { return false; } if (valueType.Size == 8 && !valueType.IsClass) { method.Statements.Add(new AsmStatement { Instruction = "pop eax" }); method.Statements.Add(new AsmStatement { Instruction = "pop edx" }); method.Statements.Add(new AsmStatement { Instruction = string.Format("lea ecx,{0}", location) }); method.Statements.Add(new AsmStatement { Instruction = "mov [ecx],eax" }); method.Statements.Add(new AsmStatement { Instruction = "add ecx,4" }); method.Statements.Add(new AsmStatement { Instruction = "mov [ecx],edx" }); } else if (valueType.Size <= 4 && !valueType.IsClass) { method.Statements.Add(new AsmStatement { Instruction = "pop eax" }); switch (storageType.Size) { case 1: { method.Statements.Add(new AsmStatement { Instruction = string.Format("mov byte ptr {0},al", location) }); } break; case 2: { method.Statements.Add(new AsmStatement { Instruction = string.Format("mov word ptr {0},ax", location) }); } break; default: { method.Statements.Add(new AsmStatement { Instruction = string.Format("mov {0},eax", location) }); } break; } } else { method.Statements.Add(new AsmStatement { Instruction = "mov esi,esp" }); method.Statements.Add(new AsmStatement { Instruction = string.Format("lea edi,{0}", location) }); method.Statements.Add(new AsmStatement { Instruction = string.Format("mov ecx,{0}", valueType.Size) }); method.Statements.Add(new AsmStatement { Instruction = "cld" }); method.Statements.Add(new AsmStatement { Instruction = "rep movsb" }); method.Statements.Add(new AsmStatement { Instruction = string.Format("add esp,{0}", valueType.Size) }); } return true; }