Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
arunpatro committed Jul 13, 2024
1 parent c989c9b commit 9053d0b
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 40 deletions.
56 changes: 49 additions & 7 deletions _docs/how.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,57 @@
title: How does Declo work?
---

## How does Declo work?
The goal of declo is to manipulate Python objects with JavaScript syntax. We can do using three strategies:

**Strategy 1:**
Convert `js src => py src`. This can be kinda hard because of regex parsing etc, it will involve creating a custom grammar parser. This can be good at the start, but can quickly get complex, as and when we add more features.
## 1. Source to Source
Convert `js src => py src`. This can be kinda hard because of regex parsing etc, it will involve creating a custom grammar parser. This can be good at the start, but can quickly get complex, as and when we add more features. A simple way is:
```python
def arrow_func(js_code = "x => x + 1"):
parts = js_code.replace(" ", "").split("=>")

if len(parts) != 2:
raise ValueError("Invalid arrow_func expression format")

**Strategy 2:**
Convert `js ast => py ast`. It is easier to work with structured data. Coding the rules for the equivalence is relatively easier.
param, body = parts
py_code = f"lambda {param}: {body}"
code_obj = compile(py_code, "<string>", "eval")

**Strategy 3:**
Convert `js src => py ast`. End to End convertion would be the best, but is the most complex which requires a mix of S1 and S2.
return eval(code_obj)
```



## 2. AST to AST
Convert `js ast => py ast`. It is easier to work with structured data. Coding the rules for the equivalence is relatively easier. We provide this api in `declo.ast.ast_js2py`. This can get a little verbose too:
```python
def ast_js2py(js_node: Union[Program, ExpressionStatement, ArrowFunctionExpression, BinaryExpression, Identifier, Literal]) -> ast.AST:
if isinstance(js_node, Program):
return ast.Module(body=[ast_js2py(stmt) for stmt in js_node.body], type_ignores=[])
elif isinstance(js_node, ExpressionStatement):
return ast.Expr(value=ast_js2py(js_node.expression))
elif isinstance(js_node, ArrowFunctionExpression):
return ast.Lambda(
args=ast.arguments(
posonlyargs=[],
args=[ast.arg(arg=param.name, annotation=None, type_comment=None) for param in js_node.params],
vararg=None,
kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]
),
body=ast_js2py(js_node.body)
)
elif isinstance(js_node, BinaryExpression):
return ast.BinOp(
left=ast_js2py(js_node.left),
op=ast.Add() if js_node.operator == "+" else None, # Extend this for other operators
right=ast_js2py(js_node.right)
)
elif isinstance(js_node, Identifier):
return ast.Name(id=js_node.name, ctx=ast.Load())
elif isinstance(js_node, Literal):
return ast.Constant(value=js_node.value, kind=None)
else:
raise ValueError(f"Unsupported JS AST node type: {js_node.__class__.__name__}")
```

## 3. SRC to AST
Convert `js src => py ast`. End to End convertion would be the best, but is the most complex which requires a mix of S1 and S2. We could do this by patching the python grammar `Python.asdl` to support the new syntax. See: ... We don't have to recompile python to run this code, we just reuse the python pgen parser with our new `JsPython.asdl` to directly create the python objects.
2 changes: 1 addition & 1 deletion _docs/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Intro
title: Introduction
---

# declo
Expand Down
6 changes: 3 additions & 3 deletions docs/404.html
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@


<span class="md-ellipsis">
declo
Introduction
</span>


Expand All @@ -242,7 +242,7 @@


<span class="md-ellipsis">
How
How does Declo work?
</span>


Expand Down Expand Up @@ -318,7 +318,7 @@ <h1>404 - Not found</h1>
</div>


<script id="__config" type="application/json">{"base": "/declo/", "features": [], "search": "/declo/assets/javascripts/workers/search.b8dbb3d2.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}}</script>
<script id="__config" type="application/json">{"base": "/declo/", "features": ["content.code.copy", "navigation.expand", "navigation.sections", "announce.dismiss"], "search": "/declo/assets/javascripts/workers/search.b8dbb3d2.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}}</script>


<script src="/declo/assets/javascripts/bundle.fe8b6f2b.min.js"></script>
Expand Down
Loading

0 comments on commit 9053d0b

Please sign in to comment.