Преглед изворни кода

Make possible to localize compiler messages

To produce localized (ru) html:
    build.py recompile --locale=ru
    build.py html --do-not-unpack-compiled
Vladislav Folts пре 5 година
родитељ
комит
50b9eb5dc3
6 измењених фајлова са 80 додато и 28 уклоњено
  1. BIN
      bin/compiled.zip
  2. 33 26
      build.py
  3. 3 2
      src/eberon/EberonContextType.ob
  4. 32 0
      src/ob/Format.ob
  5. 6 0
      src/ob/en/Message.ob
  6. 6 0
      src/ob/ru/Message.ob

+ 33 - 26
build.py

@@ -124,7 +124,20 @@ def run_tests(bin, unit_test=None, code_test=None):
         run_node(args, js_search_dirs, cwd=os.path.join(root, 'test'))
     print('<-tests')
 
-def recompile(bin, cwd):
+def _run_compiler(compiler_dir, sources, js_search_dirs, locale, out_dir, cwd, timing=False):
+    include = ['src/ob', 'src/eberon', 'src/oberon']
+    include += [os.path.join(i, locale) for i in include]
+    args = [os.path.join(compiler_dir, 'oc_nodejs.js'), 
+            '--include=' + ';'.join([os.path.join(root, i) for i in include]), 
+            '--out-dir=%s' % out_dir, 
+            '--import-dir=js'
+           ]
+    if timing:
+        args.append('--timing=true') 
+    args += sources
+    run_node(args, js_search_dirs, cwd=cwd)
+
+def recompile(bin, cwd, locale):
     print('recompile oberon sources using "%s"...' % bin)
     sources = ['ContextAssignment.ob', 
                'EberonSymbols.ob', 
@@ -140,27 +153,14 @@ def recompile(bin, cwd):
     out = os.path.join(result, 'js')
     os.mkdir(out)
 
-    run_node(['oc_nodejs.js', 
-              '--include=' + ';'.join([os.path.join(root, subdir) for subdir in ['src/ob', 'src/eberon', 'src/oberon']]), 
-              '--out-dir=%s' % out, 
-              '--import-dir=js',
-              '--timing=true'] 
-              + sources,
-             [bin,cwd],#make_js_search_dirs(bin),
-             cwd=cwd)
+    subdirs = ['src/ob', 'src/eberon', 'src/oberon']
+    subdirs += [os.path.join(d, locale) for d in subdirs]
+    _run_compiler(cwd, sources, [bin, cwd], locale, out_dir=out, cwd=cwd, timing=True)
     return result
 
-def compile_using_snapshot(src):
+def compile_using_snapshot(src, locale):
     out = os.path.join(root, 'bin', 'js')
-    compiler = os.path.join(snapshot_root, 'oc_nodejs.js')
-    js_search_dirs = [snapshot_root]
-    run_node([  compiler, 
-                '--include=src/ob;src/eberon;src/oberon', 
-                '--out-dir=%s' % out, 
-                '--import-dir=js', 
-                src],
-             js_search_dirs,
-             cwd=root)
+    _run_compiler(snapshot_root, [src], [snapshot_root], locale, out, cwd=root)
 
 def build_html(options):
     version = None
@@ -203,8 +203,8 @@ def build_html(options):
         with open(build_version_path, 'w') as f:
             f.write(version)
 
-def recompile_with_replace(bin, cwd, skip_tests = False, out_bin = None):
-    recompiled = recompile(bin, cwd)
+def recompile_with_replace(bin, cwd, locale, skip_tests=False, out_bin=None):
+    recompiled = recompile(bin, cwd, locale)
     if not skip_tests:
         run_tests(recompiled)
     
@@ -218,7 +218,7 @@ def recompile_with_replace(bin, cwd, skip_tests = False, out_bin = None):
 def pre_commit_check(options):
     bin = os.path.join(root, 'bin')
     run_tests(bin)
-    recompile_with_replace(bin, os.path.join(root, 'src'))
+    recompile_with_replace(bin, os.path.join(root, 'src'), options.locale)
     
     print('packaging compiled js to %s...' % package.root)
     package.pack()
@@ -232,7 +232,7 @@ class compile_target(object):
         parser.add_option('--file', help='file to compile')
 
     def __init__(self, options):
-        compile_using_snapshot(options.file)
+        compile_using_snapshot(options.file, options.locale)
 
 class recompile_target(object):
     name = 'recompile'
@@ -243,7 +243,12 @@ class recompile_target(object):
         pass
 
     def __init__(self, options):
-        recompile_with_replace(snapshot_root, snapshot_root, True, os.path.join(root, 'bin'))
+        recompile_with_replace(
+            snapshot_root,
+            snapshot_root,
+            options.locale,
+            skip_tests=True,
+            out_bin=os.path.join(root, 'bin'))
 
 class self_recompile_target(object):
     name = 'self-recompile'
@@ -252,10 +257,11 @@ class self_recompile_target(object):
     @staticmethod
     def setup_options(parser):
         parser.add_option('--skip-tests', help='do not run test after recompile')
+        pass
 
     def __init__(self, options):
         bin = os.path.join(root, 'bin')
-        recompile_with_replace(bin, os.path.join(root, 'src'), options.skip_tests)
+        recompile_with_replace(bin, os.path.join(root, 'src'), options.locale, options.skip_tests)
 
 class html_target(object):
     name = 'html'
@@ -263,7 +269,7 @@ class html_target(object):
 
     @staticmethod
     def setup_options(parser):
-        parser.add_option('--out', help='output directory, default: "_out"', default='_out')
+        parser.add_option('--out', help='output directory, default: "%default"', default='_out')
         parser.add_option('--set-version', action="store_true", help='include version in built html')
         parser.add_option('--do-not-unpack-compiled', action="store_true", help='do not unpack already compiled "binaries", use current')
 
@@ -324,6 +330,7 @@ if __name__ == '__main__':
         description=description,
         usage='%prog [options] <target>'
         )
+    parser.add_option('--locale', help='use specified localization subfolder, default is "%default"', default='en')
     for t in targets:
         group = optparse.OptionGroup(parser, 'target "%s"' % t.name, t.description)
         t.setup_options(group)

+ 3 - 2
src/eberon/EberonContextType.ob

@@ -4,6 +4,7 @@ IMPORT
     Context, ContextHierarchy, ContextProcedure, ContextType, 
     EberonContext, EberonDynamicArray, EberonMap, EberonRecord, EberonTypes,
     Errors, ExpressionTree,
+    Format, Message,
     Object, Procedure, R := Record, ScopeBase, Types;
 CONST
     dynamicArrayLength = -1;
@@ -82,7 +83,7 @@ END;
 PROCEDURE checkMethodExport(record: Record; method: Context.PIdentdefInfo; hint: STRING);
 BEGIN
     IF ~record.declaration.id.exported() & method.exported() THEN
-        Errors.raise(hint + " '" + method.id() + "' cannot be exported because record itself is not exported");
+        Errors.raise(Format.format2(Message.methodExport, hint, method.id()));
     END;
 END;
 
@@ -92,7 +93,7 @@ VAR
 BEGIN
     IF msg IS MethodDeclMsg THEN 
         IF SELF.declaration.id = NIL THEN
-            Errors.raise("cannot declare methods for anonymous records (POINTER TO RECORD)");
+            Errors.raise(Message.methodAnonRec);
         END;
         methodType <- msg.type;
         boundType <- SELF.type(EberonRecord.PRecord);

+ 32 - 0
src/ob/Format.ob

@@ -0,0 +1,32 @@
+MODULE Format;
+IMPORT JS;
+
+PROCEDURE format(f: STRING; args: ARRAY OF JS.var): STRING;
+VAR result: STRING;
+BEGIN
+    JS.do("result = f.replace(/{(\d+)}/g, function(match, number){return args[number];});");
+    RETURN result;
+END;
+
+PROCEDURE format1*(f: STRING; a1: JS.var): STRING;
+VAR result: STRING;
+BEGIN
+    JS.do("result = format(f, [a1]);");
+    RETURN result;
+END;
+
+PROCEDURE format2*(f: STRING; a1, a2: JS.var): STRING;
+VAR result: STRING;
+BEGIN
+    JS.do("result = format(f, [a1, a2]);");
+    RETURN result;
+END;
+
+PROCEDURE format3*(f: STRING; a1, a2, a3: JS.var): STRING;
+VAR result: STRING;
+BEGIN
+    JS.do("result = format(f, [a1, a2, a3]);");
+    RETURN result;
+END;
+
+END Format.

+ 6 - 0
src/ob/en/Message.ob

@@ -0,0 +1,6 @@
+MODULE Message;
+CONST
+    methodAnonRec* = "cannot declare methods for anonymous records (POINTER TO RECORD)";
+    methodExport* = "{0} '{1}' cannot be exported because record itself is not exported";
+
+END Message.

+ 6 - 0
src/ob/ru/Message.ob

@@ -0,0 +1,6 @@
+MODULE Message;
+CONST
+    methodAnonRec* = "объявление методов для анонимных записей невозможно (POINTER TO RECORD)";
+    methodExport* = "{0} '{1}' не может быть экспротитрован, потому что сама запись не экспортирована";
+
+END Message.