-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
myrma
committed
Jun 13, 2016
1 parent
0e2a39b
commit 5cff447
Showing
15 changed files
with
903 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,6 @@ | ||
acid | ||
==== | ||
|
||
Ce module est la racine de notre compilateur. Il définit des opérations et des | ||
types pour les différentes étapes du processus: | ||
|
||
- *Tokenizing*: il s'agit du découpage du code en une liste de lexèmes. | ||
- *Parsing*: cela consiste à regrouper nos lexèmes en un AST. | ||
|
||
Rappel: | ||
|
||
**Un lexème** est un bout de chaine de caractère auquel on associe un type. Ici | ||
Je représente mes lexèmes par la classe `Token`, et leur types par l'énumération | ||
`TokenType`. | ||
|
||
**Un AST** (de l'anglais *Abstract Syntax Tree*, arbre de syntaxe abstraite) | ||
est la représentation du programme avant sa compilation ou son exécution. | ||
On appelle ça un arbre car on représente souvent le résultat sous cette forme | ||
(troisième étape): | ||
|
||
``` | ||
parenthèse, plus, + | ||
┌───────┐ parenthèse, étoile, ┌────────┐ / \ | ||
(+ (* 3 2) 7) ───┤ lexer ├─▶ nombre(3), nombre(2), ───┤ parser ├──▶ * 7 | ||
└───────┘ parenthèse, nombre(7), └────────┘ / \ | ||
parenthèse 3 2 | ||
CODE LEXEMES AST | ||
``` | ||
`acid` est le module racine de notre projet. Il est composé de deux sous-modules | ||
`parser` et ̀`compiler`. Chacun de ces sous-modules est chargé d'une étape | ||
spécifique, de la lecture de notre code Acid brut à son exécution. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
acid.compiler | ||
============= | ||
|
||
Ce module s'occupe de traduire notre AST Acid en AST Python grâce au module `ast` | ||
de la librairie standard de Python. Ainsi, grâce à notre AST Python obtenu, nous | ||
pouvons "compiler" notre code Acid en objet compréhensible par l'interpréteur | ||
Python via la fonction *built-in* `compile`. | ||
|
||
Notre classe `Compiler` est chargée de compiler notre code Acid brut en un objet | ||
de code Python, et éventuellement de le stocker dans un fichier binaire en ROM. | ||
|
||
Ainsi, nous pouvons exécuter plus tard un code Acid sans passer par les étapes | ||
du *lexing*, du *parsing*, et de la traduction en AST Python. | ||
|
||
Note: ce n'est pas de la compilation en code machine, mais plutôt en *bytecode* | ||
de la machine virtuelle de Python. Nous ne pouvons pas transformer notre code | ||
en exécutable (ni sous Windows, ni sous Linux/OS X) avec cette technique. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#!/usr/bin/env python3.4 | ||
# coding: utf-8 | ||
|
||
from acid.compiler.compiler import * | ||
from acid.compiler.translations import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
#!/usr/bin/env python3.4 | ||
# coding: utf-8 | ||
|
||
""" | ||
This module defines a compiler class which can compile and dump an Acid code | ||
to a Python code object. | ||
Contributors: myrma | ||
""" | ||
|
||
import os | ||
import ast | ||
import marshal | ||
|
||
from acid.parser import Parser | ||
from acid.prelude import default_env | ||
|
||
|
||
class Compiler: | ||
""" | ||
Compiles an Acid AST to a Python AST. | ||
""" | ||
|
||
translations = {} | ||
|
||
def __init__(self, ast, path=None): | ||
self.path = path | ||
self.ast = ast | ||
|
||
@classmethod | ||
def from_file(cls, path): | ||
""" | ||
Loads the Acid AST from a given path. | ||
""" | ||
|
||
parser = Parser.from_file(path) | ||
ast = parser.run() | ||
return cls(ast, path) | ||
|
||
@classmethod | ||
def execute_compiled_file(cls, path, prelude=default_env): | ||
""" | ||
Executes a Python code object stored in a file. | ||
""" | ||
|
||
with open(path, 'rb') as compiled_file: | ||
code = marshal.load(compiled_file) | ||
|
||
exec(code, prelude) | ||
|
||
@classmethod | ||
def register(cls, *node_types): | ||
""" | ||
Registers a translation from an Acid AST node to a Python AST node. | ||
""" | ||
|
||
def _decorator_wrapper(translation): | ||
for node_type in node_types: | ||
cls.translations[node_type] = translation | ||
|
||
return translation | ||
|
||
return _decorator_wrapper | ||
|
||
def translate(self, node): | ||
""" | ||
Translates an Acid AST node into a Python AST node. | ||
""" | ||
|
||
py_ast = self.translations[type(node)](self, node) | ||
return ast.fix_missing_locations(py_ast) | ||
|
||
def compile(self): | ||
""" | ||
Compiles the Acid AST to a Python code object. | ||
""" | ||
|
||
py_ast = self.translate(self.ast) | ||
|
||
code = compile(py_ast, self.path or '<string>', mode='exec') | ||
return code | ||
|
||
def dump(self, target=None): | ||
""" | ||
Dumps the Python code object to a given path. | ||
""" | ||
|
||
if target is None and self.path is None: | ||
raise ValueError('Unspecified target path') | ||
|
||
code = self.compile() | ||
target = target or os.path.basename(self.path).split('.')[0] + '.acidc' | ||
|
||
with open(target, 'wb') as dump_file: | ||
marshal.dump(code, dump_file) | ||
|
||
def execute(self, prelude=default_env): | ||
""" | ||
Executes the resulting Python code object. | ||
""" | ||
|
||
code = self.compile() | ||
exec(code, prelude) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#!/usr/bin/env python3.4 | ||
# coding: utf-8 | ||
|
||
""" | ||
This module defines some conversions between Acid's and Python's AST nodes. | ||
Contributors: myrma | ||
""" | ||
|
||
import ast as python_ast | ||
|
||
from acid.compiler.compiler import Compiler | ||
from acid.parser.ast import * | ||
|
||
|
||
@Compiler.register(Program) | ||
def translate_program(compiler, program): | ||
instrs = map(compiler.translate, program.instructions) | ||
module = python_ast.Module(body=list(instrs)) | ||
return module | ||
|
||
|
||
@Compiler.register(Declaration) | ||
def translate_declaration(compiler, declaration): | ||
assign = python_ast.Assign() | ||
assign.targets = [ | ||
python_ast.Name(id=declaration.name, ctx=python_ast.Store()) | ||
] | ||
assign.value = compiler.translate(declaration.value) | ||
return assign | ||
|
||
|
||
@Compiler.register(TopLevelExpr) | ||
def translate_toplevel_expr(compiler, expr): | ||
return python_ast.Expr(compiler.translate(expr.expr)) | ||
|
||
|
||
@Compiler.register(Call) | ||
def translate_call(compiler, call): | ||
return python_ast.Call( | ||
func=compiler.translate(call.func), | ||
args=list(map(compiler.translate, call.args)), | ||
keywords=[] | ||
) | ||
|
||
|
||
@Compiler.register(Lambda) | ||
def translate_lambda(compiler, lambda_): | ||
return python_ast.Lambda( | ||
args=python_ast.arguments( | ||
args=list(map(lambda n: python_ast.arg(arg=n, annotation=None), lambda_.params)), | ||
vararg=None, | ||
kwonlyargs=[], | ||
kw_defaults=[], | ||
kwarg=None, | ||
defaults=[] | ||
), | ||
body=compiler.translate(lambda_.body) | ||
) | ||
|
||
|
||
@Compiler.register(Variable) | ||
def translate_variable(compiler, var): | ||
return python_ast.Name(var.name, python_ast.Load()) | ||
|
||
|
||
@Compiler.register(IntLiteral, FloatLiteral) | ||
def translate_num(compiler, num): | ||
return python_ast.Num(num.value) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
acid.parser | ||
=========== | ||
|
||
Ce module est la racine de notre parser. Il définit des opérations et des | ||
types pour les différentes étapes du processus: | ||
|
||
- *Tokenizing*: il s'agit du découpage du code en une liste de lexèmes. | ||
- *Parsing*: cela consiste à regrouper nos lexèmes en un AST. | ||
|
||
Rappel: | ||
|
||
**Un lexème** est un bout de chaine de caractère auquel on associe un type. Ici | ||
Je représente mes lexèmes par la classe `Token`, et leur types par l'énumération | ||
`TokenType`. | ||
|
||
**Un AST** (de l'anglais *Abstract Syntax Tree*, arbre de syntaxe abstraite) | ||
est la représentation du programme avant sa compilation ou son exécution. | ||
On appelle ça un arbre car on représente souvent le résultat sous cette forme | ||
(troisième étape): | ||
|
||
``` | ||
parenthèse, plus, + | ||
┌───────┐ parenthèse, étoile, ┌────────┐ / \ | ||
(+ (* 3 2) 7) ───┤ lexer ├─▶ nombre(3), nombre(2), ───┤ parser ├──▶ * 7 | ||
└───────┘ parenthèse, nombre(7), └────────┘ / \ | ||
parenthèse 3 2 | ||
CODE LEXEMES AST | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#!/usr/bin/env python3.4 | ||
# coding: utf-8 | ||
|
||
from acid.parser.parser import * | ||
from acid.parser.ast import * | ||
from acid.parser.rules import * | ||
from acid.parser.lexer import * | ||
from acid.parser.types import * |
Oops, something went wrong.