Monday, August 13, 2012

CargoCult in a Nutshell

Here's my working syntax for CargoCult.

assumptions

numerical expressions are per C standards.


variable declarations:

my [<type>] <id> [= <initialization expression>];

Array variables start with the sigil '@'.  They're indexed with square brackets, as in C.


function declarations:

fn <returntype> <name> parm1, parm2, ...

<body>
endfn


function calls:

[<return value> =] <function name([<parameters>])>;


function parameters are comma-separated, and typed or untyped.  If typed, the type precedes the identifier, e.g. callMyFunction( String foo, int bar );


for loops (currently only increment, by 1):

for |<indexname>| <start>..<end>

<body>
endfor


if statements:

if ( <expression> )
<body>
endif


return statements:

return <expression>;


Wednesday, August 8, 2012

CargoCult as an Intermediate Language

I face the onerous task of converting my commodore image reading code from AS3 into Perl and Objective-C.

Rather than port code twice to two platforms, I'd rather use CargoCult as the specification, and use real languages as targets.

I don't have to get 100% code conversion: I just need to get 80% of the way there to make this worthwhile.

That means CargoCult is a high-level Intermediate Language of sorts.  It's C-like, but uses syntactic sugar in a way that makes it relatively easy to write generators to transform it to other languages.  My goal is to be able to make line-by-line translators without having to do any real analysis of the code.

Here's a sample of CargoCult 1.0.

fn int buildZones totalSectors, startTrack, @zones

   for |index| 0..@zones.length
  
      my track = 1 + GLOBAL.totalTracks + startTrack;
      my sectorCount = @zones[index][1];
      my endTrack = 1 + GLOBAL.totalTracks + @zones[index][0];
     
      GLOBAL.totalTracks += @zones[index][0];
     
      for |jdex| track..endTrack
     
         GLOBAL.@trackOffset[ jdex ] = totalSectors * 0x100;
         GLOBAL.@sectorOffset[ jdex ] = totalSectors;
         GLOBAL.@sectorsInTrack[ jdex ] = sectorCount;
        
         totalSectors += sectorCount;
     
      endfor
     
   endfor
  
   return totalSectors;
  
endfn


I've successfully translated this into fully functional Perl, ActionScript3, and Objective-C.  It took 80 lines of code for each, but after that the translator was able to translate another CargoCult function, as well.

What I want to do next is build up a set of translations for each target language, for each transformation needed (line preprocessing, library call handing, subroutine handling, loop handling, and line postprocessing).