transpile_c.rs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. use super::{ir, optimize};
  2. use ir::Instruction;
  3. use ir::ConstVisitor;
  4. struct Transpiler {
  5. pub code: String
  6. }
  7. pub fn transpile_c(instrs: &Vec<ir::Instruction>) -> String {
  8. let mut transpiler = Transpiler::default();
  9. transpiler.visit_instructions(instrs);
  10. transpiler.finalize();
  11. return transpiler.code;
  12. }
  13. impl Default for Transpiler {
  14. fn default() -> Self {
  15. let mut transpiler = Transpiler{ code: "".to_string() };
  16. transpiler.code += r#"#include <stdio.h>
  17. #include <stdlib.h>
  18. int main() {
  19. unsigned char* buffer = calloc(2000000000, 1);
  20. buffer += 1000000000;
  21. "#;
  22. transpiler
  23. }
  24. }
  25. impl Transpiler {
  26. pub fn finalize(&mut self) {
  27. self.code += "}\n";
  28. }
  29. }
  30. impl ir::ConstVisitor for Transpiler {
  31. type Ret = ();
  32. fn visit_nop(&mut self, nop: &Instruction) {
  33. self.code += "\n";
  34. }
  35. fn visit_add(&mut self, add: &'_ Instruction) {
  36. if let Instruction::Add{ offset, value } = add {
  37. self.code += &format!("buffer[{}] += {};\n", offset, value);
  38. }
  39. }
  40. fn visit_set(&mut self, set: &'_ Instruction) {
  41. if let Instruction::Set{ offset, value } = set {
  42. self.code += &format!("buffer[{}] = {};\n", offset, value);
  43. }
  44. }
  45. fn visit_linear_loop(&mut self, l: &Instruction) {
  46. if let Instruction::LinearLoop(factors) = l {
  47. for (&offset, &factor) in factors {
  48. if offset == 0 {
  49. continue;
  50. }
  51. if factor == 0 {
  52. }
  53. else if factor == 1 {
  54. self.code += &format!("buffer[{}] += buffer[0];\n", offset);
  55. }
  56. else if factor == -1 {
  57. self.code += &format!("buffer[{}] -= buffer[0];\n", offset);
  58. }
  59. else {
  60. self.code += &format!("buffer[{}] += {} * buffer[0];\n", offset, factor);
  61. }
  62. }
  63. self.code += "buffer[0] = 0;\n";
  64. }
  65. }
  66. fn visit_move_ptr(&mut self, mp: &'_ Instruction) {
  67. if let Instruction::MovePtr(offset) = mp {
  68. self.code += &format!("buffer += {};\n", offset);
  69. }
  70. }
  71. fn visit_loop(&mut self, l: &Instruction) {
  72. if let Instruction::Loop(insts) = l {
  73. self.code += "while(buffer[0]) {\n";
  74. self.visit_instructions(insts);
  75. self.code += "}\n";
  76. }
  77. }
  78. fn visit_read(&mut self, r: &Instruction) {
  79. if let Instruction::Read(offset) = r {
  80. self.code += &format!("buffer[{}] = getchar();\n", offset);
  81. }
  82. }
  83. fn visit_write(&mut self, w: &Instruction) {
  84. if let Instruction::Write(offset) = w {
  85. self.code += &format!("putchar(buffer[{}]);\n", offset);
  86. }
  87. }
  88. }