Exemplo n.º 1
0
        public override void Generate(AsmCode asmCode, SymTable symTable)
        {
            int stackSize = 4;

            if (Childs[0] is ExpressionListNode el)
            {
                foreach (var node in el.Childs.AsEnumerable().Reverse())
                {
                    var child = (ExpressionNode)node;
                    child.Generate(asmCode, symTable);
                    stackSize += ((TypeSymbol)child.Type).Size;
                }
                string fmt = string.Join(
                    " ",
                    el.Childs.Cast <ExpressionNode>().
                    Select(i => _fmtDictionary[(TypeSymbol)i.Type]));
                string val = $"__@string{asmCode.CurrentID++}";
                if (!asmCode.ConstDictionary.ContainsKey(fmt))
                {
                    asmCode.ConstDictionary[fmt] = val;
                }
                asmCode.Add(AsmCmd.Cmd.Push, $"offset {asmCode.ConstDictionary[fmt]}");
            }
            else if (Childs[0] is StringNode sn)
            {
                sn.GenerateLValue(asmCode, symTable);
            }
//            asmCode.Add(AsmCmd.Cmd.And, AsmReg.Reg.Esp, -4);
            asmCode.Add(AsmCmd.Cmd.Call, "crt_printf");
            asmCode.Add(AsmCmd.Cmd.Add, AsmReg.Reg.Esp, stackSize);
        }
Exemplo n.º 2
0
        public override void GenerateLValue(AsmCode asmCode, SymTable symTable)
        {
            var       t     = symTable.LookUpLevel(Value.ToString());
            VarSymbol v     = (VarSymbol)t?.Item1;
            int       level = t.Value.Item2;

            asmCode.Add(AsmCmd.Cmd.Mov, AsmReg.Reg.Eax, AsmReg.Reg.Ebp);
            while (level-- > 0)
            {
                asmCode.Add(
                    AsmCmd.Cmd.Mov,
                    AsmReg.Reg.Eax,
                    new AsmOffset(-8, 4, AsmReg.Reg.Eax));
            }
            asmCode.Add(
                AsmCmd.Cmd.Lea,
                AsmReg.Reg.Eax,
                new AsmOffset(v.Offset, 0, AsmReg.Reg.Eax));
            if (v is ParameterSymbol ps &&
                ps.ParameterModifier != ParameterModifier.Value)
            {
                asmCode.Add(
                    AsmCmd.Cmd.Mov,
                    AsmReg.Reg.Eax,
                    new AsmOffset(0, 4, AsmReg.Reg.Eax));
            }
            asmCode.Add(AsmCmd.Cmd.Push, AsmReg.Reg.Eax);
        }
Exemplo n.º 3
0
 public override void Generate(AsmCode asmCode, SymTable symTable)
 {
     if (Type == TypeSymbol.IntTypeSymbol)
     {
         asmCode.Add(AsmCmd.Cmd.Push, Value.ToString());
     }
     else if (Type == TypeSymbol.CharTypeSymbol)
     {
         asmCode.Add(AsmCmd.Cmd.Push, Convert.ToInt32(Value).ToString());
     }
     else if (Type == TypeSymbol.RealTypeSymbol)
     {
         string val = $"__@real{HexConverter.DoubleToHexString((double) Value)}";
         if (!asmCode.ConstDictionary.ContainsKey(Value))
         {
             asmCode.ConstDictionary[Value] = val;
         }
         asmCode.Add(AsmCmd.Cmd.Sub, AsmReg.Reg.Esp, 8);
         asmCode.Add(
             AsmCmd.Cmd.Movsd,
             AsmReg.Reg.Xmm0,
             asmCode.ConstDictionary[Value]);
         asmCode.Add(
             AsmCmd.Cmd.Movsd,
             new AsmOffset(0, 8, AsmReg.Reg.Esp),
             AsmReg.Reg.Xmm0);
     }
 }
Exemplo n.º 4
0
        public void Generate(AsmCode asmCode)
        {
            asmCode.Add(AsmCmd.Cmd.Push, AsmReg.Reg.Ebp);
            asmCode.Add(AsmCmd.Cmd.Mov, AsmReg.Reg.Ebp, AsmReg.Reg.Esp);
            var curOffset = 0;

            foreach (string s in SymTable.Keys)
            {
                var t = SymTable[s];
                if (t.GetType() == typeof(VarSymbol)) // Must be EXACTLY var (cannot be parameters)
                {
                    var v = (VarSymbol)t;
                    curOffset += v.Type.Size;
                    v.Offset   = curOffset;
                }
            }
            asmCode.Add(AsmCmd.Cmd.Sub, AsmReg.Reg.Esp, curOffset.ToString());
            // TODO: Generate initial values
//            foreach (string s in SymTable.Keys)  // Must be EXACTLY var (cannot be parameters)
//            {
//                var t = SymTable[s];
//                if (t.GetType() == typeof(VarSymbol))
//                {
//                    var v = (VarSymbol)t;
//
//                }
//            }
            foreach (Statement st in StatementList)
            {
                st.Generate(asmCode, SymTable);
            }
            asmCode.Add(AsmCmd.Cmd.Leave);
        }
Exemplo n.º 5
0
        public override void GenerateLValue(AsmCode asmCode, SymTable symTable)
        {
            ((DesignatorNode)Childs[0]).GenerateLValue(asmCode, symTable);
            var t = (RecordTypeSymbol)((DesignatorNode)Childs[0]).Type;
            var f = ((VarSymbol)t.Fields[Childs[1].Value]);

            asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Eax);
            asmCode.Add(
                AsmCmd.Cmd.Lea,
                AsmReg.Reg.Eax,
                new AsmOffset(f.Offset, 0, AsmReg.Reg.Eax));
            asmCode.Add(AsmCmd.Cmd.Push, AsmReg.Reg.Eax);
        }
Exemplo n.º 6
0
        public override void Generate(AsmCode asmCode, SymTable symTable)
        {
            long id = asmCode.CurrentID++;

            StartLabel = new AsmLabel($"Cycle{id}Start");
            EndLabel   = new AsmLabel($"Cycle{id}End");
            asmCode.Add(StartLabel);
            asmCode.LoopStack.Push(this);
            foreach (var child in Childs)
            {
                child.Generate(asmCode, symTable);
            }
            asmCode.LoopStack.Pop();
            Condition.Generate(asmCode, symTable);
            asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Eax);
            asmCode.Add(AsmCmd.Cmd.Cmp, AsmReg.Reg.Eax, 0);
            asmCode.Add(AsmCmd.Cmd.Je, StartLabel);
            asmCode.Add(EndLabel);
        }
Exemplo n.º 7
0
        public void GenerateLValue(AsmCode asmCode, SymTable symTable)
        {
            string val = $"__@string{asmCode.CurrentID++}";

            if (!asmCode.ConstDictionary.ContainsKey(Value))
            {
                asmCode.ConstDictionary[Value] = val;
            }
            asmCode.Add(AsmCmd.Cmd.Push, $"offset {asmCode.ConstDictionary[Value]}");
        }
Exemplo n.º 8
0
        public override void Generate(AsmCode asmCode, SymTable symTable)
        {
            if (asmCode.SubprogramStack.Count == 0)
            {
                asmCode.Add(AsmCmd.Cmd.Exit);
                return;
            }
            var sp = asmCode.SubprogramStack.Peek();

            switch (sp)
            {
            case FunctionSymbol fs:
                Childs[0].Generate(asmCode, symTable);
                if (fs.ReturnType == TypeSymbol.IntTypeSymbol ||
                    fs.ReturnType == TypeSymbol.CharTypeSymbol)
                {
                    asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Eax);
                }
                else if (fs.ReturnType == TypeSymbol.RealTypeSymbol)
                {
                    asmCode.Add(
                        AsmCmd.Cmd.Movsd,
                        AsmReg.Reg.Xmm0,
                        new AsmOffset(0, 8, AsmReg.Reg.Esp));
                    asmCode.Add(AsmCmd.Cmd.Sub, AsmReg.Reg.Esp, 8);
                }
                else
                {
                    throw new NotImplementedException();
                }
                break;
            }
            asmCode.Add(AsmCmd.Cmd.Leave);
            asmCode.Add(AsmCmd.Cmd.Ret, $"{-sp.ParameterOffset - 4}");
        }
Exemplo n.º 9
0
 public override void Generate(AsmCode asmCode, SymTable symTable)
 {
     if (Subprogram is FunctionSymbol fs &&
         (fs.ReturnType is RecordTypeSymbol || fs.ReturnType is ArrayTypeSymbol))
     {
         throw new NotImplementedException();
     }
     foreach (var prm in Childs.AsEnumerable().
              Reverse().
              Zip(
                  Subprogram.Parameters.AsEnumerable().Reverse(),
                  (node, symbol) => (node, symbol)))
     {
         if (prm.symbol.ParameterModifier == ParameterModifier.Value)
         {
             prm.node.Generate(asmCode, symTable);
         }
         else
         {
             ((DesignatorNode)prm.node).GenerateLValue(asmCode, symTable);
         }
     }
     if (asmCode.SubprogramStack.Count > 0 &&
         asmCode.SubprogramStack.Peek() == Subprogram)
     {
         asmCode.Add(
             AsmCmd.Cmd.Mov,
             AsmReg.Reg.Eax,
             new AsmOffset(-8, 4, AsmReg.Reg.Ebp));
         asmCode.Add(AsmCmd.Cmd.Push, AsmReg.Reg.Eax);
     }
     else
     {
         asmCode.Add(AsmCmd.Cmd.Push, AsmReg.Reg.Ebp);
     }
     asmCode.Add(AsmCmd.Cmd.Call, Subprogram.Label.ToArgString());
     if (Subprogram is FunctionSymbol functionSymbol)
     {
         if (functionSymbol.ReturnType == TypeSymbol.IntTypeSymbol ||
             functionSymbol.ReturnType == TypeSymbol.CharTypeSymbol)
         {
             asmCode.Add(AsmCmd.Cmd.Push, AsmReg.Reg.Eax);
         }
         if (functionSymbol.ReturnType == TypeSymbol.RealTypeSymbol)
         {
             asmCode.Add(AsmCmd.Cmd.Sub, AsmReg.Reg.Esp, 8);
             asmCode.Add(
                 AsmCmd.Cmd.Movsd,
                 new AsmOffset(0, 8, AsmReg.Reg.Esp),
                 AsmReg.Reg.Xmm0);
         }
     }
 }
Exemplo n.º 10
0
        public override void GenerateLValue(AsmCode asmCode, SymTable symTable)
        {
            ((DesignatorNode)Childs[0]).GenerateLValue(asmCode, symTable);
            Childs[1].Generate(asmCode, symTable);
            var t = (ArrayTypeSymbol)((DesignatorNode)Childs[0]).Type;

            asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Eax);
            asmCode.Add(AsmCmd.Cmd.Imul, AsmReg.Reg.Eax, t.ElementType.Size);
            asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Ebx);
            asmCode.Add(
                AsmCmd.Cmd.Lea,
                AsmReg.Reg.Eax,
                new AsmArrayAddr(
                    t.Range.Begin * t.ElementType.Size,
                    1,
                    AsmReg.Reg.Ebx,
                    AsmReg.Reg.Eax));
//            asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Eax);
//            asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Ebx);
//            asmCode.Add(AsmCmd.Cmd.Lea, AsmReg.Reg.Eax,
//                new AsmArrayAddr(t.Range.Begin * t.ElementType.Size, t.ElementType.AddressSize, AsmReg.Reg.Eax, AsmReg.Reg.Ebx));
            asmCode.Add(AsmCmd.Cmd.Push, AsmReg.Reg.Eax);
        }
Exemplo n.º 11
0
        public override void Generate(AsmCode asmCode, SymTable symTable)
        {
            Childs[0].Generate(asmCode, symTable);
            var opName = (Tokenizer.TokenSubType)Value;

            if ((Childs[0] as ExpressionNode).Type == TypeSymbol.IntTypeSymbol)
            {
                var op = AsmCmd.TokenUnIntOps[opName];
                if (op == AsmCmd.Cmd.None)
                {
                    return;
                }
                asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Eax);
                asmCode.Add(op, AsmReg.Reg.Eax);
                asmCode.Add(AsmCmd.Cmd.Push, AsmReg.Reg.Eax);
            }
            else if ((Childs[0] as ExpressionNode).Type == TypeSymbol.RealTypeSymbol)
            {
                if (opName == Tokenizer.TokenSubType.Plus)
                {
                    return;
                }
                asmCode.Add(
                    AsmCmd.Cmd.Movsd,
                    AsmReg.Reg.Xmm0,
                    new AsmOffset(0, 8, AsmReg.Reg.Esp));
                asmCode.Add(AsmCmd.Cmd.Add, AsmReg.Reg.Esp, 8);
                string neg = $"__@real{HexConverter.DoubleToHexString(-0.0)}";
                asmCode.ConstDictionary[-0.0] = neg;
                asmCode.Add(AsmCmd.Cmd.Sub, AsmReg.Reg.Esp, 8);
                asmCode.Add(AsmCmd.Cmd.Movsd, AsmReg.Reg.Xmm1, neg);
                asmCode.Add(AsmCmd.Cmd.Pxor, AsmReg.Reg.Xmm0, AsmReg.Reg.Xmm1);
                asmCode.Add(
                    AsmCmd.Cmd.Movsd,
                    new AsmOffset(0, 8, AsmReg.Reg.Esp),
                    AsmReg.Reg.Xmm0);
            }
        }
Exemplo n.º 12
0
        public override void Generate(AsmCode asmCode, SymTable symTable)
        {
            asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Eax);
            var v = (TypeSymbol)Type;

            if (v == TypeSymbol.IntTypeSymbol)
            {
                asmCode.Add(AsmCmd.Cmd.Push, new AsmOffset(0, 4, AsmReg.Reg.Eax));
            }
            else if (v == TypeSymbol.CharTypeSymbol)
            {
                asmCode.Add(
                    AsmCmd.Cmd.Movsx,
                    AsmReg.Reg.Eax,
                    new AsmOffset(0, 1, AsmReg.Reg.Eax));
                asmCode.Add(AsmCmd.Cmd.Push, AsmReg.Reg.Eax);
            }
            else if (v == TypeSymbol.RealTypeSymbol)
            {
                asmCode.Add(
                    AsmCmd.Cmd.Movsd,
                    AsmReg.Reg.Xmm0,
                    new AsmOffset(0, 8, AsmReg.Reg.Eax));
                asmCode.Add(AsmCmd.Cmd.Sub, AsmReg.Reg.Esp, 8);
                asmCode.Add(
                    AsmCmd.Cmd.Movsd,
                    new AsmOffset(0, 8, AsmReg.Reg.Esp),
                    AsmReg.Reg.Xmm0);
            }
            else if (v is ArrayTypeSymbol || v is RecordTypeSymbol)
            {
                for (int i = v.Size - 4; i >= 0; i -= 4)
                {
                    asmCode.Add(AsmCmd.Cmd.Push, new AsmOffset(-i, 4, AsmReg.Reg.Eax));
                }
            }
        }
Exemplo n.º 13
0
        public override void Generate(AsmCode asmCode, SymTable symTable)
        {
            long id = asmCode.CurrentID++;

            StartLabel = new AsmLabel($"Cycle{id}Start");
            EndLabel   = new AsmLabel($"Cycle{id}End");
            AsmLabel bodyLabel = new AsmLabel($"Cycle{id}Body");

            asmCode.Add(AsmCmd.Cmd.Jmp, StartLabel);
            asmCode.Add(bodyLabel);
            asmCode.LoopStack.Push(this);
            Childs[0].Generate(asmCode, symTable);
            asmCode.LoopStack.Pop();
            asmCode.Add(StartLabel);
            Condition.Generate(asmCode, symTable);
            asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Eax);
            asmCode.Add(AsmCmd.Cmd.Cmp, AsmReg.Reg.Eax, 0);
            asmCode.Add(AsmCmd.Cmd.Jne, bodyLabel);
            asmCode.Add(EndLabel);
        }
Exemplo n.º 14
0
        public override void Generate(AsmCode asmCode, SymTable symTable)
        {
            long id        = asmCode.CurrentID++;
            var  elseLabel = new AsmLabel($"Condtion{id}Else");
            var  endLabel  = new AsmLabel($"Condtion{id}End");

            Childs[0].Generate(asmCode, symTable);
            asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Eax);
            asmCode.Add(AsmCmd.Cmd.Cmp, AsmReg.Reg.Eax, 0);
            asmCode.Add(AsmCmd.Cmd.Je, elseLabel);
            Childs[1].Generate(asmCode, symTable);
            asmCode.Add(AsmCmd.Cmd.Jmp, endLabel);
            asmCode.Add(elseLabel);
            if (Childs.Count > 2)
            {
                Childs[2].Generate(asmCode, symTable);
            }
            asmCode.Add(endLabel);
        }
Exemplo n.º 15
0
        public override void Generate(AsmCode asmCode, SymTable symTable)
        {
            var child = (ExpressionNode)Childs[0];
            var ct    = (TypeSymbol)child.Type;
            var pt    = (TypeSymbol)Type;

            child.Generate(asmCode, symTable);
            if (ct == TypeSymbol.IntTypeSymbol && pt == TypeSymbol.RealTypeSymbol)
            {
                asmCode.Add(
                    AsmCmd.Cmd.Cvtsi2sd,
                    AsmReg.Reg.Xmm0,
                    new AsmOffset(0, 4, AsmReg.Reg.Esp));
                asmCode.Add(AsmCmd.Cmd.Sub, AsmReg.Reg.Esp, 4);
                asmCode.Add(
                    AsmCmd.Cmd.Movsd,
                    new AsmOffset(0, 8, AsmReg.Reg.Esp),
                    AsmReg.Reg.Xmm0);
            }
            if (ct == TypeSymbol.RealTypeSymbol && pt == TypeSymbol.IntTypeSymbol)
            {
                asmCode.Add(
                    AsmCmd.Cmd.Cvttsd2si,
                    AsmReg.Reg.Eax,
                    new AsmOffset(0, 8, AsmReg.Reg.Esp));
                asmCode.Add(AsmCmd.Cmd.Add, AsmReg.Reg.Esp, 4);
                asmCode.Add(
                    AsmCmd.Cmd.Mov,
                    new AsmOffset(0, 4, AsmReg.Reg.Esp),
                    AsmReg.Reg.Eax);
            }
            if (ct == TypeSymbol.CharTypeSymbol && pt == TypeSymbol.IntTypeSymbol)
            {
                // Char is 4 bytes for now
            }
            if (ct == TypeSymbol.IntTypeSymbol && pt == TypeSymbol.CharTypeSymbol)
            {
                // Char is 4 bytes for now
            }
        }
Exemplo n.º 16
0
        public override void Generate(AsmCode asmCode, SymTable symTable)
        {
            var left  = (DesignatorNode)Childs[0];
            var right = (ExpressionNode)Childs[1];

            right.Generate(asmCode, symTable);
            left.GenerateLValue(asmCode, symTable);
            if (right.Type == TypeSymbol.IntTypeSymbol)
            {
                asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Eax);
                asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Ebx);
                asmCode.Add(
                    AsmCmd.Cmd.Mov,
                    new AsmOffset(0, 4, AsmReg.Reg.Eax),
                    AsmReg.Reg.Ebx);
            }
            else if (right.Type == TypeSymbol.CharTypeSymbol)
            {
                asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Eax);
                asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Ebx);
                asmCode.Add(
                    AsmCmd.Cmd.Mov,
                    new AsmOffset(0, 1, AsmReg.Reg.Eax),
                    AsmReg.Reg.Bl);
            }
            else if (right.Type == TypeSymbol.RealTypeSymbol)
            {
                asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Eax);
                asmCode.Add(
                    AsmCmd.Cmd.Movsd,
                    AsmReg.Reg.Xmm0,
                    new AsmOffset(0, 8, AsmReg.Reg.Esp));
                asmCode.Add(AsmCmd.Cmd.Add, AsmReg.Reg.Esp, 8);
                asmCode.Add(
                    AsmCmd.Cmd.Movsd,
                    new AsmOffset(0, 8, AsmReg.Reg.Eax),
                    AsmReg.Reg.Xmm0);
            }
            else if (right.Type is ArrayTypeSymbol || right.Type is RecordTypeSymbol)
            {
                asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Eax);
                for (int i = 0; i < ((TypeSymbol)right.Type).Size; i += 4)
                {
                    asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Ebx);
                    asmCode.Add(
                        AsmCmd.Cmd.Mov,
                        new AsmOffset(-i, 4, AsmReg.Reg.Eax),
                        AsmReg.Reg.Ebx);
                }
            }
        }
Exemplo n.º 17
0
 public override void Generate(AsmCode asmCode, SymTable symTable)
 {
     asmCode.Add(AsmCmd.Cmd.Jmp, asmCode.LoopStack.Peek().StartLabel);
 }
Exemplo n.º 18
0
        public override void Generate(AsmCode asmCode, SymTable symTable)
        {
            long id = asmCode.CurrentID++;

            StartLabel = new AsmLabel($"Cycle{id}Start");
            EndLabel   = new AsmLabel($"Cycle{id}End");
            AsmLabel bodyLabel = new AsmLabel($"Cycle{id}Body");
            var      v         = (VarSymbol)symTable.LookUp(Childs[0].Value.ToString());

            Childs[1].Generate(asmCode, symTable);                    // Initial value
            ((IdentNode)Childs[0]).GenerateLValue(asmCode, symTable); // Cycle counter
            asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Eax);
            asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Ebx);

            asmCode.Add(AsmCmd.Cmd.Sub, AsmReg.Reg.Ebx, 1);

            asmCode.Add(
                AsmCmd.Cmd.Mov,
                new AsmOffset(0, v.Type.Size, AsmReg.Reg.Eax),
                AsmReg.Reg.Ebx);
            // Value initialized
            asmCode.Add(AsmCmd.Cmd.Jmp, StartLabel);
            asmCode.Add(bodyLabel);
            asmCode.LoopStack.Push(this);
            Childs[3].Generate(asmCode, symTable); // Cycle body
            asmCode.LoopStack.Pop();

            asmCode.Add(StartLabel);

            ((IdentNode)Childs[0]).GenerateLValue(asmCode, symTable);
            asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Eax);
            asmCode.Add(AsmCmd.Cmd.Inc, new AsmOffset(0, v.Type.Size, AsmReg.Reg.Eax));


            Childs[2].Generate(asmCode, symTable); // Cycle counter target

            ((IdentNode)Childs[0]).GenerateLValue(asmCode, symTable);
            asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Eax);

            asmCode.Add(
                AsmCmd.Cmd.Mov,
                AsmReg.Reg.Eax,
                new AsmOffset(0, v.Type.Size, AsmReg.Reg.Eax));
            asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Ebx);
            asmCode.Add(AsmCmd.Cmd.Cmp, AsmReg.Reg.Eax, AsmReg.Reg.Ebx);
            asmCode.Add(AsmCmd.Cmd.Jle, bodyLabel);
            asmCode.Add(EndLabel);
        }
Exemplo n.º 19
0
        public override void Generate(AsmCode asmCode, SymTable symTable)
        {
            Childs[0].Generate(asmCode, symTable);
            Childs[1].Generate(asmCode, symTable);
            var val = (Tokenizer.TokenSubType)Value;

            if (Parser.RelOps.Contains(val))
            {
                var t = (TypeSymbol)((ExpressionNode)Childs[0]).Type;
                if (t == TypeSymbol.IntTypeSymbol || t == TypeSymbol.CharTypeSymbol)
                {
                    asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Ebx);
                    asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Eax);
                    asmCode.Add(AsmCmd.Cmd.Cmp, AsmReg.Reg.Eax, AsmReg.Reg.Ebx);
                    asmCode.Add(AsmCmd.TokenCmpIntOps[val], AsmReg.Reg.Al);
                    asmCode.Add(AsmCmd.Cmd.Movsx, AsmReg.Reg.Eax, AsmReg.Reg.Al);
                    asmCode.Add(AsmCmd.Cmd.Sub, AsmReg.Reg.Eax, 1);
                    asmCode.Add(AsmCmd.Cmd.Push, AsmReg.Reg.Eax);
                    return;
                }
                if (t == TypeSymbol.RealTypeSymbol)
                {
                    asmCode.Add(
                        AsmCmd.Cmd.Movsd,
                        AsmReg.Reg.Xmm1,
                        new AsmOffset(0, 8, AsmReg.Reg.Esp));
                    asmCode.Add(AsmCmd.Cmd.Add, AsmReg.Reg.Esp, 8);
                    asmCode.Add(
                        AsmCmd.Cmd.Movsd,
                        AsmReg.Reg.Xmm0,
                        new AsmOffset(0, 8, AsmReg.Reg.Esp));
                    asmCode.Add(AsmCmd.Cmd.Add, AsmReg.Reg.Esp, 8);
                    var cmpop = AsmCmd.TokenBinRealOps[val];
                    asmCode.Add(cmpop, AsmReg.Reg.Xmm0, AsmReg.Reg.Xmm1);
                    asmCode.Add(AsmCmd.Cmd.Sub, AsmReg.Reg.Esp, 4);
                    asmCode.Add(
                        AsmCmd.Cmd.Movd,
                        new AsmOffset(0, 4, AsmReg.Reg.Esp),
                        AsmReg.Reg.Xmm0);
                    return;
                }
                throw new InvalidOperationException("Non-scalar compared");
            }
            if (Type == TypeSymbol.IntTypeSymbol)
            {
                var op = AsmCmd.TokenBinIntOps[val];
                switch (op)
                {
                case AsmCmd.Cmd.Add:
                case AsmCmd.Cmd.Sub:
                case AsmCmd.Cmd.Or:
                case AsmCmd.Cmd.Xor:
                case AsmCmd.Cmd.And:
                    asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Ebx);
                    asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Eax);
                    asmCode.Add(op, AsmReg.Reg.Eax, AsmReg.Reg.Ebx);
                    asmCode.Add(AsmCmd.Cmd.Push, AsmReg.Reg.Eax);
                    return;

                case AsmCmd.Cmd.Imul:
                case AsmCmd.Cmd.Idiv:
                    asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Ebx);
                    asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Eax);
                    if (op == AsmCmd.Cmd.Idiv)
                    {
                        asmCode.Add(AsmCmd.Cmd.Cdq);
                    }
                    asmCode.Add(op, AsmReg.Reg.Ebx);
                    asmCode.Add(
                        AsmCmd.Cmd.Push,
                        val == Tokenizer.TokenSubType.Mod
                                ? AsmReg.Reg.Edx
                                : AsmReg.Reg.Eax);
                    return;

                case AsmCmd.Cmd.Shl:
                case AsmCmd.Cmd.Shr:
                    asmCode.Add(AsmCmd.Cmd.Mov, AsmReg.Reg.Ecx, AsmReg.Reg.Ebx);
                    asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Ecx);
                    asmCode.Add(AsmCmd.Cmd.Pop, AsmReg.Reg.Eax);
                    asmCode.Add(op, AsmReg.Reg.Eax, AsmReg.Reg.Cl);
                    asmCode.Add(AsmCmd.Cmd.Mov, AsmReg.Reg.Ebx, AsmReg.Reg.Ecx);
                    asmCode.Add(AsmCmd.Cmd.Push, AsmReg.Reg.Eax);
                    return;
                }
            }
            else if (Type == TypeSymbol.RealTypeSymbol)
            {
                var op = AsmCmd.TokenBinRealOps[val];
                asmCode.Add(
                    AsmCmd.Cmd.Movsd,
                    AsmReg.Reg.Xmm1,
                    new AsmOffset(0, 8, AsmReg.Reg.Esp));
                asmCode.Add(AsmCmd.Cmd.Add, AsmReg.Reg.Esp, 8);
                asmCode.Add(
                    AsmCmd.Cmd.Movsd,
                    AsmReg.Reg.Xmm0,
                    new AsmOffset(0, 8, AsmReg.Reg.Esp));
                asmCode.Add(op, AsmReg.Reg.Xmm0, AsmReg.Reg.Xmm1);
                asmCode.Add(
                    AsmCmd.Cmd.Movsd,
                    new AsmOffset(0, 8, AsmReg.Reg.Esp),
                    AsmReg.Reg.Xmm0);
                return;
            }
        }