Skip to content
Browse files

Implemented compile mode of operation and created an example with uti…

…lities

Added example-utilities
Added compiler.ometajs
Implemented the compiler mode of execution
Updated README with compile example
  • Loading branch information...
1 parent 0909427 commit af476d6031d14bfb52d35d9f91d55f5364b0173e @tristanls committed Jun 26, 2011
Showing with 140 additions and 7 deletions.
  1. +13 −4 README.md
  2. +43 −0 examples/compiler.ometajs
  3. +19 −1 node_modules/example-utilities.js
  4. +65 −2 node_modules/ometajsnode/ometajsnode.js
View
17 README.md
@@ -18,18 +18,17 @@ To learn more:
About
----
-The goal of this project is to provide a tool-chain tool for easily working with OMetaJS. `ometajsnode` allows one to specify grammar file, interpreter file, ( in future also compiler files/modules ), and program files via command line, and offers a number of options of execution such as parse mode, interpreter mode, and compile mode.
+The goal of this project is to provide a tool-chain tool for easily working with OMetaJS. `ometajsnode` allows one to specify grammar, interpreter, and compiler files, utility modules, and program files via command line, and offers a number of options of linking them together into an execution chain such as parse mode, interpreter mode, and compile mode.
Work in progress
----
-Incorporating compiler / code emitting code is going to get worked on soon.
I'm not sure if packaging works with `npm` yet, but I'll get there.
`stdin` input is not working yet.
Usage
----
-Currently, parsing and interpreting works. See below walkthrough.
+Currently, parsing, interpreting, and "compiling" works. See below walkthrough.
see usage via `./ometajsnode -h` or `./ometajsnode --help`
@@ -71,9 +70,19 @@ We have little bit more going on here:
* `-i` in addition to `-g` which specified the grammar file, we add an interpreter file that will work with the output of parsing according to grammar file
* because we specified both a grammar and an interpreter, we need to provide both `--parser-root` and `--interpreter-root`
+#### Parser to intermediate representation, then intermediate representation to "assembly" code example:
+
+from the `bin` directory:
+
+`./ometajsnode -C -g ../examples/grammar_to_ir.ometajs --parser-root expr -c ../examples/compiler.ometajs --compiler-root comp -o output.file -u example-utilities ../examples/program.file --debug`
+
+* `-C` indicates compile mode. I'm not yet sure this is named correctly, perhaps a more appropriate name would be emit mode. Nevertheless, in this example it uses `compiler.ometajs` to emit assembly-like code to a file
+* `-c ../examples/compiler.ometajs` specifies the OMetaJS compiler file
+* `-u example-utilities` specifies a comma separated list of utility modules (here only one) that `compiler.ometajs` uses in order to help it to generate "assembly". `ometajsnode` will attempt to `require('module name')` and will make it available to any `*.ometajs` files via `__Utilities[ <utilityName> ]`. `utilityName` must be exported by the module: `exports.utilityName = 'some name';
+
Feedback
----
-I welcome your input and feedback.
+I am not quite convinced that the 'parse', 'interpret', 'compile' mode breakdown makes sense, I'm open to suggestions on how to better organize execution modes. And of course, I welcome any other input or feedback.
Cheers!
View
43 examples/compiler.ometajs
@@ -0,0 +1,43 @@
+ometa Compiler {
+ comp = [ 'num' anything:x ] -> ( function() {
+ __u = __Utilities[ 'utilities' ];
+ r = __u.getUniqueResult();
+ __u.resultStack.push( r );
+ return '%result'+r+' = i32 ' + x.toString() + '\n'; } )()
+ | [ 'add' comp:x comp:y ] -> ( function() {
+ __u = __Utilities[ 'utilities' ];
+ r2 = __u.resultStack.pop();
+ r1 = __u.resultStack.pop();
+ r = __u.getUniqueResult();
+ __u.resultStack.push( r );
+ i1 = __u.getUniqueIdent();
+ i2 = __u.getUniqueIdent();
+ return '' + x + '%'+i1+' = %result'+r1+'\n' + y + '%'+i2+' = %result'+r2+'\n' + '%result'+r+' = add i32 %'+i1+', %'+i2+'\n'; } )()
+ | [ 'sub' comp:x comp:y ] -> ( function() {
+ __u = __Utilities[ 'utilities' ];
+ r2 = __u.resultStack.pop();
+ r1 = __u.resultStack.pop();
+ r = __u.getUniqueResult();
+ __u.resultStack.push( r );
+ i1 = __u.getUniqueIdent();
+ i2 = __u.getUniqueIdent();
+ return '' + x + '%'+i1+' = %result'+r1+'\n' + y + '%'+i2+' = %result'+r2+'\n' + '%result'+r+' = sub i32 %'+i1+', %'+i2+'\n'; } )()
+ | [ 'mul' comp:x comp:y ] -> ( function() {
+ __u = __Utilities[ 'utilities' ];
+ r2 = __u.resultStack.pop();
+ r1 = __u.resultStack.pop();
+ r = __u.getUniqueResult();
+ __u.resultStack.push( r );
+ i1 = __u.getUniqueIdent();
+ i2 = __u.getUniqueIdent();
+ return '' + x + '%'+i1+' = %result'+r1+'\n' + y + '%'+i2+' = %result'+r2+'\n' + '%result'+r+' = mul i32 %'+i1+', %'+i2+'\n'; } )()
+ | [ 'div' comp:x comp:y ] -> ( function() {
+ __u = __Utilities[ 'utilities' ];
+ r2 = __u.resultStack.pop();
+ r1 = __u.resultStack.pop();
+ r = __u.getUniqueResult();
+ __u.resultStack.push( r );
+ i1 = __u.getUniqueIdent();
+ i2 = __u.getUniqueIdent();
+ return '' + x + '%'+i1+' = %result'+r1+'\n' + y + '%'+i2+' = %result'+r2+'\n' + '%result'+r+' = sdiv i32 %'+i1+', %'+i2+'\n'; } )()
+};
View
20 node_modules/example-utilities.js
@@ -1,2 +1,20 @@
exports.version = "1.0.0";
-exports.utilityName = 'utilities';
+exports.utilityName = 'utilities';
+
+exports.getUniqueIdent = ( function() {
+ var i = -1;
+ return function() {
+ i++;
+ return 'ident' + i;
+ };
+})();
+
+exports.getUniqueResult = ( function() {
+ var i = -1;
+ return function() {
+ i++;
+ return '' + i;
+ };
+})();
+
+exports.resultStack = [];
View
67 node_modules/ometajsnode/ometajsnode.js
@@ -109,8 +109,6 @@ var grammarFileReadComplete = function( err, grammarString ) {
module.rootParserExpression, module.rootInterpreterExpression );
} else if ( module.mode == 'compile' ) {
- logly.error( 'compile mode not yet implemented' );
- process.exit( 1 );
startCompiling( parserString, module.outputFileName,
module.compilerFileName, module.inputFileNames,
@@ -122,6 +120,46 @@ var startCompiling = function( parserString, outputFileName,
compilerFileName, inputFileNames, rootParserExpression,
rootCompilerExpression ) {
+ fs.readFile( compilerFileName, 'utf8', function( err, compilerString ) {
+ if ( err ) {
+ logly.error( err.message );
+ process.exit( 1 );
+ }
+
+ logly.verbose( "completed reading compiler file" );
+ logly.debug( "compiler file:\n" + compilerString );
+
+ logly.verbose( "building compiler..." );
+
+ // FIXME: this looks awfully a lot like interpreting...
+ // i think there is a difference with more complex examples
+ // and optimizations, but keep a lookout for refactoring
+ // opportunities
+
+ var compilerTree = ometa.BSOMetaJSParser.matchAll(
+ compilerString,
+ "topLevel",
+ undefined,
+ function( m, i ) {
+ throw objectThatDelegatesTo( fail, { errorPos: i } );
+ });
+
+ compilerString = ometa.BSOMetaJSTranslator.match(
+ compilerTree,
+ "trans",
+ undefined,
+ translationError );
+
+
+ logly.verbose( "compiler build complete" );
+
+ // parse input files and call the callback with parse results
+ parse( parserString, undefined, inputFileNames, rootParserExpression,
+ function( results ) {
+ compile( compilerString, outputFileName, rootCompilerExpression,
+ results );
+ });
+ });
};
var startInterpreting = function( parserString, outputFileName,
@@ -172,7 +210,32 @@ var startInterpreting = function( parserString, outputFileName,
rootInterpreterExpression, results );
});
});
+ };
+};
+
+var compile = function( compilerString, outputFileName, rootCompilerExpression,
+ rawInput ) {
+ // no matter what the compiler grammar is called, we alias it as __ometajsnode__Compiler
+ compilerString = "__ometajsnode__Compiler=" + compilerString;
+ eval( compilerString );
+
+ logly.debug( 'compiler:\n' + compilerString );
+
+ var results = [];
+
+ logly.verbose( "compiling..." );
+ for ( var i = 0; i < rawInput.length; i++ ) {
+
+ var result = __ometajsnode__Compiler.match( rawInput[ i ],
+ rootCompilerExpression );
+
+ logly.debug( "compilation result:\n" + result.toString() );
+
+ results.push( result );
}
+ logly.verbose( "completed compiling");
+
+ handleResultsAfterProcessing( 0, results );
};
var interpret = function( interpreterString, outputFileName, inputFileNames,

0 comments on commit af476d6

Please sign in to comment.
Something went wrong with that request. Please try again.