Skip to content

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrey Antukh committed Nov 25, 2013
0 parents commit 8e77c75
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
*.py[c|o]
*.sql
*.bz2
*~
*.log
*.json
*.wsgi
*.egg-info
build*
dist*
*.swp
4 changes: 4 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CobraScript
===========

Simple experiment of translate basic python ast to javascript.
123 changes: 123 additions & 0 deletions cs.py
Original file line number Diff line number Diff line change
@@ -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]))
5 changes: 5 additions & 0 deletions samples/sample1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-


def fobar():
return 2 + 2
5 changes: 5 additions & 0 deletions samples/sample2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-

2 + 1


0 comments on commit 8e77c75

Please sign in to comment.