Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/brettlangdon/gython

Python 3 interpreter in Go
https://github.com/brettlangdon/gython

Last synced: about 1 month ago
JSON representation

Python 3 interpreter in Go

Awesome Lists containing this project

README

        

Gython
======

This project is currently a for-fun work in progress.

The main goals of this project are to learn about programming languages by trying to rewrite [CPython][] 3.5.0 in [Go][].

[CPython]:https://github.com/python/cpython
[Go]:https://github.com/golang/go/

## Progress
### Scanner
So far I have a mostly working scanner/tokenizer. The main goal was to be able to generate similar output as running `python3 -m tokenize --exact `.
Currently there are a few small differences between the output format, but the tokens being produced are the same.

### Grammar Parser
Next up is going to be writing the parser to be able to validate the source code grammar; which will match the form provided from:
```python
import parser
import pprint
import symbol
import token

def resolve_symbol_names(part):
if not isinstance(part, list):
return part

if not len(part):
return part

symbol_id = part[0]
if symbol_id in symbol.sym_name:
symbol_name = symbol.sym_name[symbol_id]
return [symbol_name] + [resolve_symbol_names(p) for p in part[1:]]
elif symbol_id in token.tok_name:
token_name = token.tok_name[symbol_id]
return [token_name] + part[1:]
return part

def main(filename):
with open(filename, 'r') as fp:
contents = fp.read()
st = parser.suite(contents)
ast = resolve_symbol_names(st.tolist())
pprint.pprint(ast)

if __name__ == '__main__':
import sys
main(sys.argv[1])
```

```bash
python3 grammar.py
```

```bash
$ echo "print('hello world')" > test.py
$ python3 parse.py test.py
['file_input',
['stmt',
['simple_stmt',
['small_stmt',
['expr_stmt',
['testlist_star_expr',
['test',
['or_test',
['and_test',
['not_test',
['comparison',
['expr',
['xor_expr',
['and_expr',
['shift_expr',
['arith_expr',
['term',
['factor',
['power',
['atom_expr',
['atom', ['NAME', 'print']],
['trailer',
['LPAR', '('],
['arglist',
['argument',
['test',
['or_test',
['and_test',
['not_test',
['comparison',
['expr',
['xor_expr',
['and_expr',
['shift_expr',
['arith_expr',
['term',
['factor',
['power',
['atom_expr',
['atom',
['STRING',
"'hello world'"]]]]]]]]]]]]]]]]]],
['RPAR', ')']]]]]]]]]]]]]]]]]]],
['NEWLINE', '']]],
['NEWLINE', ''],
['ENDMARKER', '']]
```

### AST Parsing
AST parsing will take the validated source grammar and convert it into a valid language AST.

The goal is to get a similar AST output as the following:

```python
import ast

def main(filename):
with open(filename, 'r') as fp:
contents = fp.read()
module = ast.parse(contents)
print(ast.dump(module))

if __name__ == '__main__':
import sys
main(sys.argv[1])
```

```bash
$ echo "print('hello world')" > test.py
$ python3 parser.py test.py
Module(body=[Expr(value=Call(func=Name(id='print', ctx=Load()), args=[Str(s='hello world')], keywords=[]))])
```

### Compiler
The purpose of the compiler is to convert an AST into the appropriate Python bytecode.

The goal is to be able to produce a similar output as running:

```bash
$ echo "print('hello world')" > test.py
$ python3 -m dis test.py
1 0 LOAD_CONST 0 (5)
3 STORE_NAME 0 (num)
6 LOAD_CONST 1 (None)
9 RETURN_VALUE
```

### Interpreter
The interpreter will be up after the compiler and will be able to execute on Python bytecode.