예제 #1
0
파일: Parser.cs 프로젝트: strunberg/TEA
        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;
            }
        }
예제 #2
0
        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;
        }