From 8e77c7546dc8ee9dd53c88622fda990f97846220 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 25 Nov 2013 23:50:17 +0100 Subject: [PATCH] Initial commit. --- .gitignore | 11 ++++ README.rst | 4 ++ cs.py | 123 +++++++++++++++++++++++++++++++++++++++++++++ samples/sample1.py | 5 ++ samples/sample2.py | 5 ++ 5 files changed, 148 insertions(+) create mode 100644 .gitignore create mode 100644 README.rst create mode 100755 cs.py create mode 100644 samples/sample1.py create mode 100644 samples/sample2.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bacbc0d --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +*.py[c|o] +*.sql +*.bz2 +*~ +*.log +*.json +*.wsgi +*.egg-info +build* +dist* +*.swp diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..0025bd2 --- /dev/null +++ b/README.rst @@ -0,0 +1,4 @@ +CobraScript +=========== + +Simple experiment of translate basic python ast to javascript. diff --git a/cs.py b/cs.py new file mode 100755 index 0000000..822ce20 --- /dev/null +++ b/cs.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import abc +import ast +import io +import sys +import pprint + +# TODO: introduce argparse for commandline + +nodes = {} + +def _resolve_node(node): + return nodes[node.__class__.__name__] + +def _resolve_node_instance(node): + return _resolve_node(node)(node) + + +class NodeMeta(type): + def __new__(clst, name, bases, attrs): + cls = super().__new__(clst, name, bases, attrs) + nodes[name] = cls + return cls + + +class Node(metaclass=NodeMeta): + """ + Base class for all compiller Nodes + """ + def __init__(self, ast_node, child=None): + self.ast_node = ast_node + + def iter_nodes(self): + for node in ast.iter_child_nodes(self.ast_node): + yield _resolve_node_instance(node) + + def get_code(self, indent=0): + raise NotImplementedError() + + +class Module(Node): + def get_code(self, indent=0): + code = "\n\n".join(n.get_code(indent=indent+4) for n in self.iter_nodes()) + return "".join([";function(this) {\n", code, "}.call(this);"]) + + +class Expr(Node): + def get_code(self, indent=0): + code = " ".join(x.get_code() for x in self.iter_nodes()) + return "{indent}{code};\n".format(indent=" "*indent, + code=code) + +class Num(Node): + def get_code(self, indent=0): + return str(self.ast_node.n) + + +class Add(Node): + def get_code(self, indent=0): + return "+" + + +class BinOp(Node): + def get_code(self, indent=0): + left = _resolve_node_instance(self.ast_node.left) + op = _resolve_node_instance(self.ast_node.op) + right = _resolve_node_instance(self.ast_node.right) + + return "{left} {op} {right}".format(left=left.get_code(), + right=right.get_code(), + op=op.get_code()) + +class Return(Node): + def get_code(self, indent=0): + code = " ".join(x.get_code() for x in self.iter_nodes()) + return "{indent}return {code};\n".format(indent=" "*indent, + code=code) + +class FunctionDef(Node): + def iter_nodes(self): + for node in self.ast_node.body: + yield _resolve_node_instance(node) + + def get_code(self, indent=0): + code = ["{0}var {1} = function ()".format(" "*indent, self.ast_node.name)] + code.append(" {\n") + + for node in self.iter_nodes(): + code.append(node.get_code(indent=indent+4)) + code.append("\n") + + code.append(" "*indent) + code.append("};\n") + return "".join(code) + + +class Compiller(object): + def __init__(self, tree): + self.tree = tree + + def compile(self): + module = Module(self.tree) + return module.get_code() + + +def main(filename): + with io.open(filename, "rt") as f: + tree = ast.parse(f.read()) + + print(ast.dump(tree)) + print("*"*200) + + cmp = Compiller(tree) + r = cmp.compile() + print(r) + +if __name__ == "__main__": + if len(sys.argv) != 2: + raise RuntimeException("Invalid parameters") + + sys.exit(main(sys.argv[1])) diff --git a/samples/sample1.py b/samples/sample1.py new file mode 100644 index 0000000..3ab763a --- /dev/null +++ b/samples/sample1.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + + +def fobar(): + return 2 + 2 diff --git a/samples/sample2.py b/samples/sample2.py new file mode 100644 index 0000000..74bd5aa --- /dev/null +++ b/samples/sample2.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + +2 + 1 + +