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); }
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); } } }
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); }
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); }
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); }
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); }
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 } }
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); } }
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); }
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)); } } }
public override void Generate(AsmCode asmCode, SymTable symTable) { Childs[0].Generate(asmCode, symTable); }
// TODO: Remove python code, consolidate switch statement, add more error types, add error tests. // TODO: Remove doubling code in convert fucntions // TODO: Not ASCII symbols? // TODO: Token value boxing. private static void Main(string[] args) { Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-US"); var options = new Options(); if (!CommandLine.Parser.Default.ParseArguments(args, options)) { return; } try { using (var reader = new StreamReader(options.InputFile)) using (var writer = new StreamWriter(options.OutputFile)) { switch (options.Mode) { case "tokenize": writer.WriteLine( $"{"Line",-5}|{"Pos",-5}|{"Type",-12}|{"Subtype",-25}|{"Value",-35}|{"Source",-50}"); writer.WriteLine(new string('-', 142)); try { foreach (var t in new Tokenizer(reader)) { if (t.Type == Tokenizer.TokenType.EndOfFile) { break; } writer.Write( "{0, -5}|{1, -5}|{2, -12}|{3, -25}|{4, -35}|{5, -50}", t.Line, t.Position, t.Type, t.SubType, t.Value.ToString().Replace("\n", "\\n").Replace("\r", "\\r") .Replace("\t", "\\t"), t.SourceString); writer.WriteLine(); } } catch (Tokenizer.TokenizerException e) { writer.WriteLine($"{e.Message} at {e.Line}:{e.Position}"); } break; case "parse": try { using (var tokenizer = new Tokenizer(reader)) using (var tokenStream = tokenizer.GetEnumerator()) using (var parser = new Parser(tokenStream)) { var p = parser.Parse(); TreePrinter.PrintProgram(writer, p); } } catch (Tokenizer.TokenizerException e) { writer.WriteLine($"{e.Message} at {e.Line}:{e.Position}"); } catch (Parser.ParserException e) { writer.WriteLine($"{e.Message} at {e.Line}:{e.Position}"); } break; case "generate": try { using (var tokenizer = new Tokenizer(reader)) using (var tokenStream = tokenizer.GetEnumerator()) using (var parser = new Parser(tokenStream)) { var p = parser.Parse(); if (options.Optimize) { Optimizer.Optimize(p); } var asm = new AsmCode(p); writer.WriteLine(asm); } } catch (Tokenizer.TokenizerException e) { writer.WriteLine($"{e.Message} at {e.Line}:{e.Position}"); } catch (Parser.ParserException e) { writer.WriteLine($"{e.Message} at {e.Line}:{e.Position}"); } break; default: Console.WriteLine($"Mode {options.Mode} not found."); break; } } } catch (FileNotFoundException e) { Console.WriteLine($"{e.FileName} not found"); } }
public override void GenerateLValue(AsmCode asmCode, SymTable symTable) { throw new NotImplementedException(); }
public override void Generate(AsmCode asmCode, SymTable symTable) { asmCode.Add(AsmCmd.Cmd.Jmp, asmCode.LoopStack.Peek().StartLabel); }
public abstract void Generate(AsmCode code);
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; } }
public override void Generate(AsmCode asmCode, SymTable symTable) { GenerateLValue(asmCode, symTable); base.Generate(asmCode, symTable); }
public override void Generate(AsmCode code) { throw new NotImplementedException(); }
public abstract void GenerateLValue(AsmCode asmCode, SymTable symTable);