소스 검색

ready to compile multiple oberon modules to nodejs modules

Vladislav Folts 11 년 전
부모
커밋
e2bbb8b0a8
5개의 변경된 파일101개의 추가작업 그리고 29개의 파일을 삭제
  1. 19 5
      src/nodejs.js
  2. 56 14
      src/oc.js
  3. 24 0
      src/oc_nodejs.js
  4. 1 1
      test/run_nodejs.cmd
  5. 1 9
      test/test_compile.js

+ 19 - 5
src/nodejs.js

@@ -5,6 +5,9 @@ var Code = require("code.js");
 var Context = require("context.js");
 var oc = require("oc.js");
 
+var fs = require("fs");
+var path = require("path");
+
 var ModuleGenerator = Rtl.Class.extend({
     init: function Nodejs$ModuleGenerator(name, imports){
         this.__name = name;
@@ -45,13 +48,24 @@ var RtlCodeUsingWatcher = Rtl.Code.extend({
     reset: function(){this.__used = false;}
 });
 
-function compile(text, handleErrors, handleCompiledModule){
+function writeCompiledModule(name, code, outDir){
+    var filePath = path.join(outDir, name + ".js");
+    fs.writeFileSync(filePath, code);
+    }
+
+function compile(sources, handleErrors, outDir){
     var rtlCodeWatcher = new RtlCodeUsingWatcher();
     var rtl = new Rtl.RTL(rtlCodeWatcher);
     var moduleCode = function(name, imports){return new ModuleGenerator(name, imports);};
 
-    oc.compileWithContext(
-            text,
+    oc.compileModules(
+            sources,
+            function(name){
+                var fileName = name;
+                if (!path.extname(fileName).length)
+                    fileName += ".ob";
+                return fs.readFileSync(fileName, "utf8");
+            },
             function(moduleResolver){return new Context.Context(
                 new Code.Generator(),
                 moduleCode,
@@ -64,13 +78,13 @@ function compile(text, handleErrors, handleCompiledModule){
                          + ".js\")." + rtl.name() + ";\n" + code;
                     rtlCodeWatcher.reset();
                 }
-                handleCompiledModule(name, code);
+                writeCompiledModule(name, code, outDir);
             });
 
     var rtlCode = rtl.generate();
     if (rtlCode){
         rtlCode += "\nexports." + rtl.name() + " = " + rtl.name() + ";";
-        handleCompiledModule(rtl.name(), rtlCode);
+        writeCompiledModule(rtl.name(), rtlCode, outDir);
     }
 }
 

+ 56 - 14
src/oc.js

@@ -45,39 +45,81 @@ function compileModule(stream, context, handleErrors){
             scope.exports());
 }
 
-function compileWithContext(text, contextFactory, handleErrors, handleCompiledModule){
+function compileModulesFromText(
+        text,
+        contextFactory,
+        resolveModule,
+        handleCompiledModule,
+        handleErrors){
     var stream = new Stream(text);
-    var modules = {};
-    function resolveModule(name){return modules[name];}
-
     do {
         var context = contextFactory(resolveModule);
         var module = compileModule(stream, context, handleErrors);
         if (!module)
             return;
-        var symbol = module.symbol();
-        var moduleName = symbol.id();
-        modules[moduleName] = symbol.info();
-        handleCompiledModule(moduleName, module.code());
+        handleCompiledModule(module);
         Lexer.skipSpaces(stream);
-    } 
+    }
     while (!stream.eof());
 }
 
+var ModuleResolver = Class.extend({
+    init: function Oc$ModuleResolver(compile, handleCompiledModule, moduleReader){
+        this.__modules = {};
+        this.__compile = compile;
+        this.__moduleReader = moduleReader;
+        this.__handleCompiledModule = handleCompiledModule;
+    },
+    compile: function(text){
+        this.__compile(text, this.__resolveModule.bind(this), this.__handleModule.bind(this));
+    },
+    __resolveModule: function(name){
+        if (this.__moduleReader && !this.__modules[name])
+            this.compile(this.__moduleReader(name));
+        return this.__modules[name];
+    },
+    __handleModule: function(module){
+        var symbol = module.symbol();
+        var moduleName = symbol.id();
+        this.__modules[moduleName] = symbol.info();
+        this.__handleCompiledModule(moduleName, module.code());
+    }
+});
+
+function makeResolver(contextFactory, handleCompiledModule, handleErrors, moduleReader){
+    return new ModuleResolver(
+        function(text, resolveModule, handleModule){
+            compileModulesFromText(text,
+                                   contextFactory,
+                                   resolveModule,
+                                   handleModule,
+                                   handleErrors);
+        },
+        handleCompiledModule,
+        moduleReader
+        );
+}
+
+function compileModules(names, moduleReader, contextFactory, handleErrors, handleCompiledModule){
+    var resolver = makeResolver(contextFactory, handleCompiledModule, handleErrors, moduleReader);
+    names.forEach(function(name){ resolver.compile(moduleReader(name)); });
+}
+
 function compile(text, handleErrors){
     var result = "";
     var rtl = new RTL();
     var moduleCode = function(name, imports){return new Code.ModuleGenerator(name, imports);};
-    compileWithContext(
-            text,
+    var resolver = makeResolver(
             function(moduleResolver){
                 return new Context.Context(new Code.Generator(),
                                            moduleCode,
                                            rtl,
                                            moduleResolver);
             },
-            handleErrors,
-            function(name, code){result += code;});
+            function(name, code){result += code;},
+            handleErrors
+            );
+    resolver.compile(text);
 
     var rtlCode = rtl.generate();
     if (rtlCode)
@@ -87,4 +129,4 @@ function compile(text, handleErrors){
 
 exports.compileModule = compileModule;
 exports.compile = compile;
-exports.compileWithContext = compileWithContext;
+exports.compileModules = compileModules;

+ 24 - 0
src/oc_nodejs.js

@@ -0,0 +1,24 @@
+"use strict";
+
+var nodejs = require("nodejs.js");
+
+function main(){
+    if (process.argv.length <= 3){
+        console.info("Usage: <oc_nodejs> <output dir> <input oberon module file(s)>");
+        return -1;
+    }
+
+    var outDir = process.argv[2];
+    var sources = process.argv.slice(3);
+    var errors = "";
+    nodejs.compile(sources, function(e){errors += e;}, outDir);
+    if (errors.length){
+        console.error(errors);
+        return -2;
+    }
+
+    console.info("OK!");
+    return 0;
+}
+
+process.exit(main());

+ 1 - 1
test/run_nodejs.cmd

@@ -1,2 +1,2 @@
-SET NODE_PATH=.;
+SET NODE_PATH=.;%~dp1
 "C:\Program Files\nodejs\node.exe" %*

+ 1 - 9
test/test_compile.js

@@ -28,8 +28,6 @@ function compile(src){
 }
 
 function compileNodejs(src, dirs){
-    var text = fs.readFileSync(src, "utf8");
-    
     var subdir = path.basename(src);
     subdir = subdir.substr(0, subdir.length - path.extname(subdir).length);
 
@@ -37,13 +35,7 @@ function compileNodejs(src, dirs){
     fs.mkdirSync(outDir);
 
     var errors = "";
-    nodejs.compile(text,
-                   function(e){errors += e;},
-                   function(name, code){
-                        var filePath = path.join(outDir, name + ".js");
-                        fs.writeFileSync(filePath, code);
-                     }
-                    );
+    nodejs.compile([src], function(e){errors += e;}, outDir);
     if (errors)
         throw new Test.TestError(errors);