Advertisement
snake5

asmix preprocessor SGScript code

Aug 4th, 2014
382
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. include "string", "io", "re", "os", "fmt";
  2.  
  3. IN = argv[1];
  4. OUT = "asmpp." $ IN;
  5. TMP_ASM = "__tmp.asm";
  6. TMP_ASM_OUT = "__tmp.o";
  7.  
  8. RTYPES =
  9. {
  10.     "i32" = [ 0x94939291, 4, "int32_t" ]
  11. };
  12.  
  13. data = io_file_read( IN );
  14.  
  15. ranges = re_match_all( data, "#<\\$.*?\\$>#s", RE_RETURN_BOTH );
  16. ranges.reverse();
  17.  
  18. function str2cbin( str )
  19. {
  20.     if( typeid(str) != VT_STRING )
  21.         ERROR( "str2cbin: not a string" );
  22.    
  23.     out = [];
  24.     len = str.length;
  25.     for( i = 0; i < len; ++i )
  26.     {
  27.         cc = string_charcode( str, i );
  28.         if( cc > 127 ) cc -= 256;
  29.         out.push( cc );
  30.     }
  31.     return string_implode( out, "," );
  32. }
  33.  
  34. foreach( i, range : ranges )
  35. {
  36.     asm = string_cut( range[0][0], 2, -3 );
  37.    
  38.     //
  39.     // prepare post-replacements
  40.     //
  41.     replist = [];
  42.     reps = re_match_all( asm, "#:([a-zA-Z0-9]+)\\((.*?)\\)#s", RE_RETURN_BOTH );
  43.     reps.reverse();
  44.    
  45.     foreach( rep : reps )
  46.     {
  47.         type = rep[1][0];
  48.         src = rep[2][0];
  49.        
  50.         if( isset( RTYPES, type ) ){ val = RTYPES[type][0]; }
  51.         else
  52.             ERROR( "replacement type " $ type $ " was not recognized" );
  53.        
  54.         asm = string_part( asm, 0, rep[0][1] ) $ val $ string_part( asm, rep[0][2] );
  55.        
  56.         // 0: type, 1: source in C, 2: test value, 3: test value as bytes
  57.         replist.unshift([ type, src, val, fmt_pack("l",val) ]);
  58.     }
  59.    
  60.     //
  61.     // assemble
  62.     //
  63.     io_file_write( TMP_ASM, asm );
  64.     os_command( "as -o " $ TMP_ASM_OUT $ " -mnaked-reg -msyntax=intel -mmnemonic=intel " $ TMP_ASM );
  65.     gen = io_file_read( TMP_ASM_OUT );
  66.     gen_asm = string_part( gen, string_find( gen, ".bss" ) + 40 );
  67.     gen_asm = string_part( gen_asm, 0, string_find( gen_asm, ".file" ) );
  68.    
  69.     // strip NOPs
  70.     gen_asm = string_trim( gen_asm, "\x90" );
  71.    
  72.     gckey = "__asm" $ i;
  73.    
  74.     bcrw = "";
  75.     foreach( rep : replist )
  76.     {
  77.         xdata = RTYPES[ rep[0] ];
  78.         numbytes = xdata[1];
  79.         pos = string_find_rev( gen_asm, rep[3] );
  80.         gen_asm = string_part( gen_asm, 0, pos ) $ string_repeat( "\x00", numbytes ) $ string_part( gen_asm, pos + numbytes );
  81.        
  82.         bcrw $= fmt_text( " *({c}*)({c}+{c}) = {c}; ", xdata[2], gckey, pos, rep[1] );
  83.     }
  84.    
  85.     printvar( gen_asm );
  86.    
  87.     gen_code = "{char " $ gckey $ "[] = {" $ str2cbin( gen_asm )
  88.         $ "};" $ bcrw $ "APPEND_CODE(" $ gckey $ "," $ gen_asm.length $ ");}";
  89.     data = string_part( data, 0, range[0][1] ) $ gen_code $ string_part( data, range[0][2] );
  90. }
  91.  
  92. io_file_write( OUT, data );
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement