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>;
Showing posts with label CargoCult. Show all posts
Showing posts with label CargoCult. Show all posts
Monday, August 13, 2012
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).
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).
Thursday, February 23, 2012
CargoCult, part one
This is a post about my dream language, which I've named CargoCult. It's a mashup of Perl, Objective-C, JavaScript, Shell, and other things.
It does NOT eschew the use of shifted characters -- it just requires that they be important, with a value greater than the extra effort of typing shift + something.
Object Notation
CargoCult is a dynamic object language. This means you have type-able structures, potentially dynamic, which have attributes and methods.
Core language features -- arrays, hashes, variables -- are objects. For example, the implicit array type is an object, so you can do things like this:
return [d1, d2, d3].sort.reverse.pop;
Hashes and arrays use the grouping notation of braces. An array is a comma-separated list of scalars. A hash is a comma-separated list of assignments.
my array = 1, 2, 3, 'four'; # also [ 1, 2, 3, 'four' ]
my hash = [year = 2012, month = two, day = 23];
Hash and array accesses are object calls.
my value = hash.year;
my other_value = array.0;
my other_value = array.0;
Method Calling with Parameters
When we write methods in any language, we typically name formal parameters. For example:
string myFunction( foo, bar )
{
foo + ': ' + bar;
}
foo and bar are formal parameters, i.e. the names used in the method.
When calling a method, parameters are passed in by name. In other words, the parameters are more or less a hash.
my str = myObj myFunction .foo 'hello' .bar 'world';
When you have to nest the call, use the backslash to indicate a method call (rather than a new array), and then braces for grouping.
my str = myObj myFunction .foo \[myObj myFunction .foo 'hello' .bar 'world'] .bar '!';
Subscribe to:
Posts (Atom)