Guest User

Untitled

a guest
May 4th, 2018
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.10 KB | None | 0 0
  1. import os
  2. import sys
  3. import subprocess
  4.  
  5. def get_temp_path(source_path):
  6. return os.path.splitext(source_path)[0] + '.rs'
  7.  
  8. def ident_line(original, new):
  9. new = new.strip()
  10. i = 0
  11. while i < len(original) and original[i] == ' ':
  12. i = i + 1
  13. return ' ' * i + new
  14.  
  15. statics = set()
  16.  
  17. def is_ident_char(ch):
  18. return ch in '1234567890_qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'
  19.  
  20. def translate_line(line):
  21. original = line
  22. line = line.strip()
  23. if line.startswith('struct '):
  24. return '#[derive(Debug, Copy, Clone)]\n' + line
  25. line = (line
  26. .replace('int ', 'usize ')
  27. .replace(' int', ' usize')
  28. .replace('int;', 'usize;')
  29. .replace('let ', 'let mut ')
  30. .replace('type', 'type_')
  31. .replace('struct', 'struct_')
  32. .replace('static ', 'static mut ')
  33. .replace('fn ', 'unsafe fn ')
  34. .replace('main()', 'main_()'))
  35. if '//' in line:
  36. for i in range(len(line)):
  37. if line[i:i+2] == '//':
  38. line = line[:i].strip()
  39. break
  40. for name in statics:
  41. if name not in line:
  42. continue
  43. replaced = '(*' + name + '.as_mut().unwrap())'
  44. i = 0
  45. while i <= len(line) - len(name):
  46. if i > 0 and is_ident_char(line[i - 1]):
  47. i = i + 1
  48. continue
  49. if i + len(name) < len(line) and is_ident_char(line[i + len(name)]):
  50. i = i + 1
  51. continue
  52. if line[i:i + len(name)] == name:
  53. line = line[:i] + replaced + line[i + len(name):]
  54. i = i + len(replaced)
  55. continue
  56. i = i + 1
  57. if line.startswith('static '):
  58. parts = line.split()
  59. name = parts[2][:-1]
  60. typ = ' '.join(parts[3:])[:-1]
  61. statics.add(name)
  62. line = 'static mut ' + name + ': Option<' + typ + '> = None;'
  63. elif line.startswith('let ') and '=' not in line:
  64. line = line[:-1] + ' = unsafe { std::mem::zeroed() };'
  65. elif line.startswith('if '):
  66. line = 'if (' + line[3:-2] + ') as usize != 0 {'
  67. elif line.startswith('unsafe fn') and '()' not in line:
  68. line = line.replace('(', '(mut ').replace(', ', ', mut ') # ))
  69.  
  70. return ident_line(original, line)
  71.  
  72. def translate(source):
  73. prelude = '''
  74.  
  75. fn __syscall_exit(code: usize) {
  76. println!("Exit code: {}", code);
  77. std::process::exit(0);
  78. }
  79.  
  80. unsafe fn __syscall_read() -> usize {
  81. let mut buf = [0];
  82. let amount_read = FILE_READER.as_mut().unwrap().read(&mut buf).expect("failed read");
  83. if amount_read == 0 {
  84. 256
  85. } else {
  86. usize::from(buf[0])
  87. }
  88. }
  89.  
  90. unsafe fn __syscall_write(byte: usize) {
  91. let buf = [byte as u8];
  92. let writer = FILE_WRITER.as_mut().unwrap();
  93. writer.write_all(&buf).expect("failed to write");
  94. writer.flush().expect("failed to flush");
  95. }
  96.  
  97. use std::fs;
  98. use std::io::prelude::*;
  99.  
  100. static mut FILE_READER: Option<fs::File> = None;
  101. static mut FILE_WRITER: Option<fs::File> = None;
  102.  
  103. fn main() {
  104. unsafe {
  105. FILE_READER = Some(fs::File::open("test.txt").expect("failed to open source file"));
  106. FILE_WRITER = Some(fs::File::create("out.bin").expect("failed to create output file"));
  107. init_statics();
  108. main_();
  109. }
  110. }
  111.  
  112. unsafe fn init_statics() {
  113. '''
  114. disable_lints = '#![allow(unused_mut, unused_unsafe, unused_parens, bad_style, dead_code, unused_variables)]\n'
  115. result = []
  116. for line in source.splitlines():
  117. result.append(translate_line(line))
  118. main_code = '\n'.join(result)
  119. for name in statics:
  120. prelude += ' {} = Some(std::mem::zeroed());\n'.format(name)
  121. prelude += '}\n'
  122. return disable_lints + main_code + prelude
  123.  
  124. def compile(source_path):
  125. temp_path = get_temp_path(source_path)
  126. with open(source_path) as f:
  127. source = f.read()
  128. source = translate(source)
  129. with open(temp_path, 'w') as f:
  130. f.write(source)
  131. print('calling rustc')
  132. subprocess.run(['rustc', '-O', temp_path])
  133.  
  134. if __name__ == '__main__':
  135. args = sys.argv
  136. if len(args) != 2:
  137. print('usage: python {} <file>'.format(args[0]))
  138. else:
  139. compile(args[1])
Add Comment
Please, Sign In to add comment