Commits

Andrew Godwin committed 68ba452

Docstrings, nice indentation, and for loops.

  • Participants
  • Parent commits 15645a6

Comments (0)

Files changed (7)

kugelblitz/compiler.py

     dest_filename = os.path.splitext(filename)[0] + ".js"
     with open(dest_filename, "w") as dest:
         with open(filename, "r") as src:
-            dest.write(translate_string(src.read()))
+            dest.write(translate_string(src.read(), "VC.core"))
 
 def main():
     # Read in the filenames from the commandline

kugelblitz/translator/__init__.py

 from kugelblitz.translator.expressions import ExprTranslator, BinOpTranslator, BoolOpTranslator, UnaryOpTranslator, CompareTranslator, SubscriptTranslator
 from kugelblitz.translator.values import NumTranslator, ListTranslator, NameTranslator, DictTranslator, StrTranslator
 from kugelblitz.translator.assignment import AssignTranslator, AugAssignTranslator
-from kugelblitz.translator.control import IfTranslator, IfExprTranslator, RaiseTranslator, ReturnTranslator, CallTranslator
+from kugelblitz.translator.control import IfTranslator, IfExprTranslator, RaiseTranslator, ReturnTranslator, CallTranslator, ForTranslator
 
 def wrap_old_translator(func):
     class WrappedTranslator(BaseTranslator):
             
             ast.Print: None,
             
-            ast.For: None,
+            ast.For: ForTranslator,
             ast.While: None,
             ast.If: IfTranslator,
             ast.With: None,
         "right": node.attr,
     }
 
-def translate_string(string):
-    return get_translator(ast.parse(string+"\n")).translate()
+def translate_string(string, module_name=None):
+    return get_translator(
+        node = ast.parse(string+"\n"),
+        module_name = module_name,
+    ).translate()

kugelblitz/translator/assignment.py

 class AssignTranslator(BaseTranslator):
     
     def translate_single_assign(self, target, value):
+        context = {
+            'target': self.sib_translate(target),
+            'value': self.sib_translate(value),
+            'module_name': self.module_name,
+        }
         if isinstance(target, ast.Name):
-            return "var %(target)s = %(value)s" % {
-                'target': self.sib_translate(target),
-                'value': self.sib_translate(value),
-            }
+            if self.module_name:
+                return "%(module_name)s.%(target)s = %(value)s" % context
+            else:
+                return "var %(target)s = %(value)s" % context
         else:
-            return "%(target)s = %(value)s" % {
-                'target': self.sib_translate(target),
-                'value': self.sib_translate(value),
-            }
+            return "%(target)s = %(value)s" % context
 
     def translate(self):
         statements = []

kugelblitz/translator/base.py

     
     """
     Base translator class. Instantiated for each node.
+    
+    indent_level says how far indented this node is. All nodes output without
+    prefixing themselves with indent characters; only if they have a newline
+    do they need to add them.
+    
+    module_name specifies the module prefix to append to all items in this
+    node, if it contains any; it's lost as soon as you use sub_translate
+    (since it's only needed for top-level things in modules)
     """
     
     INDENT_STRING = "    "
     
-    def __init__(self, node, indent_level=0):
+    def __init__(self, node, indent_level=0, module_name=None):
         self.node = node
         self.indent_level = indent_level
+        self.module_name = module_name
     
     @property
     def indent(self):
         return self.get_translator(
             node,
             indent_level = self.indent_level + 1,
+            module_name = None,
         ).translate()
     
     def sib_translate(self, node):
         return self.get_translator(
             node,
             indent_level = self.indent_level,
+            module_name = self.module_name,
         ).translate()

kugelblitz/translator/control.py

             "func": func,
             "args_def": args_def,
         }
+
+class ForTranslator(BodyTranslator):
+    """
+    Translates for loops.
+    """
+    
+    def translate(self):
+        return "for (var _i = 0; _i < %(iter)s.length; _i++) {\n%(indent_child)svar %(target)s = %(iter)s[_i];\n%(indent_child)s%(body)s\n%(indent)s}" % {
+            "iter": self.sib_translate(self.node.iter),
+            "target": self.sib_translate(self.node.target),
+            "indent": self.indent,
+            "indent_child": self.indent_child,
+            "body": self.translate_body(self.node.body),
+        }

kugelblitz/translator/expressions.py

 class ExprTranslator(BaseTranslator):
     
     def translate(self):
-        return self.sub_translate(self.node.value)
+        return self.sib_translate(self.node.value)
     
 
 class BoolOpTranslator(BaseTranslator):
     
     def translate(self):
         return "(%(left)s %(op)s %(right)s)" % {
-            'left': self.sub_translate(self.node.values[0]),
+            'left': self.sib_translate(self.node.values[0]),
             'op': self.ops[self.node.op.__class__],
-            'right': self.sub_translate(self.node.values[1]),
+            'right': self.sib_translate(self.node.values[1]),
         }
     
 
     def translate(self):
         return "%(op)s%(operand)s" % {
             'op': self.ops[self.node.op.__class__],
-            'operand': self.sub_translate(self.node.operand),
+            'operand': self.sib_translate(self.node.operand),
         }
 
 
         # The ** operator isn't in JavaScript.
         if isinstance(self.node.op, ast.Pow):
             return "Math.pow(%s, %s)" % (
-                self.sub_translate(self.node.left),
-                self.sub_translate(self.node.right),
+                self.sib_translate(self.node.left),
+                self.sib_translate(self.node.right),
             )
         else:
             return "(%(left)s %(op)s %(right)s)" % {
-                'left': self.sub_translate(self.node.left),
+                'left': self.sib_translate(self.node.left),
                 'op': self.ops[self.node.op.__class__],
-                'right': self.sub_translate(self.node.right),
+                'right': self.sib_translate(self.node.right),
             }
 
 
         assert len(self.node.ops) == 1, "Cannot have multiple comparison"
         assert len(self.node.comparators) == 1, "Cannot have multiple comparison"
         return "%(left)s %(op)s %(comparator)s" % {
-            "left": self.sub_translate(self.node.left),
+            "left": self.sib_translate(self.node.left),
             "op": self.ops[self.node.ops[0].__class__],
-            "comparator": self.sub_translate(self.node.comparators[0]),
+            "comparator": self.sib_translate(self.node.comparators[0]),
         }
 
     
     def translate(self):
         if isinstance(self.node.slice, ast.Index):
             return "%(value)s[%(index)s]" % {
-                "value": self.sub_translate(self.node.value),
-                "index": self.sub_translate(self.node.slice.value),
+                "value": self.sib_translate(self.node.value),
+                "index": self.sib_translate(self.node.slice.value),
             }
         elif isinstance(self.node.slice, ast.Slice):
             # Translate the endpoints

kugelblitz/translator/toplevel.py

             "indent": self.indent,
             "indent_child": self.indent_child,
             "docstring": docstring,
+            'module_name': self.module_name,
         }
-        if docstring:
-            return "%(docstring)s\n%(indent)svar %(name)s = function (%(args_def)s) {\n%(indent_child)s%(body_def)s\n%(indent)s}" % context
+        if self.module_name:
+            if docstring:
+                return "%(docstring)s\n%(indent)s%(module_name)s.%(name)s = function (%(args_def)s) {\n%(indent_child)s%(body_def)s\n%(indent)s}" % context
+            else:
+                return "%(module_name)s.%(name)s = function (%(args_def)s) {\n%(body_def)s\n%(indent)s}" % context
         else:
-            return "var %(name)s = function (%(args_def)s) {\n%(body_def)s\n%(indent)s}" % context
+            if docstring:
+                return "%(docstring)s\n%(indent)svar %(name)s = function (%(args_def)s) {\n%(indent_child)s%(body_def)s\n%(indent)s}" % context
+            else:
+                return "var %(name)s = function (%(args_def)s) {\n%(body_def)s\n%(indent)s}" % context
 
 
 class LambdaTranslator(BodyTranslator):