diff options
author | Iván Ávalos <avalos@disroot.org> | 2022-11-25 21:29:55 -0600 |
---|---|---|
committer | Iván Ávalos <avalos@disroot.org> | 2022-11-25 21:29:55 -0600 |
commit | 6b27930ef9c3eaede8d0c283ffa8376c40145f80 (patch) | |
tree | e2f2f8a25defb68283910edea33768054f435bc9 /compilador/astree | |
parent | 4b2fad150a292f882cee408d7f9746715225f7cb (diff) | |
download | javanol-6b27930ef9c3eaede8d0c283ffa8376c40145f80.tar.gz javanol-6b27930ef9c3eaede8d0c283ffa8376c40145f80.tar.bz2 javanol-6b27930ef9c3eaede8d0c283ffa8376c40145f80.zip |
¡Otra vez hay renderizador de AST!
Diffstat (limited to 'compilador/astree')
-rw-r--r-- | compilador/astree/decl.py | 31 | ||||
-rw-r--r-- | compilador/astree/expr.py | 151 | ||||
-rw-r--r-- | compilador/astree/ident.py | 1 | ||||
-rw-r--r-- | compilador/astree/type.py | 32 | ||||
-rw-r--r-- | compilador/astree/unit.py | 14 |
5 files changed, 195 insertions, 34 deletions
diff --git a/compilador/astree/decl.py b/compilador/astree/decl.py index 1e6de1d..99f5f75 100644 --- a/compilador/astree/decl.py +++ b/compilador/astree/decl.py @@ -1,6 +1,9 @@ +import uuid +import graphviz as gv from dataclasses import dataclass -from typing import Optional +from typing import Optional, cast +from astree.graphable import Graphable from astree.type import Type from astree.ident import Ident from astree.expr import Expr @@ -9,19 +12,41 @@ from astree.expr import Expr # # entero a = 0; @dataclass -class DeclGlobal: +class DeclGlobal(Graphable): ident: Ident _type: Type init: Expr + def graph(self, dot: gv.Digraph, parent: str = None, edge: str = None) -> None: + name = uuid.uuid1().hex + dot.node(name, 'DeclGlobal') + dot.edge(parent, name, label = edge) + name_ident = uuid.uuid1().hex + dot.node(name_ident, self.ident) + dot.edge(name, name_ident, label = 'ident') + if isinstance(self.init, Graphable): + self.init.graph(dot, name, 'init') + # A function declaration. # # funcion vacio main() { ... } @dataclass -class DeclFunc: +class DeclFunc(Graphable): ident: Ident prototype: Type body: Optional[Expr] + def graph(self, dot: gv.Digraph, parent: str = None, edge: str = None) -> None: + name = uuid.uuid1().hex + dot.node(name, 'DeclFunc') + dot.edge(parent, name, label = edge) + name_ident = uuid.uuid1().hex + dot.node(name_ident, self.ident) + dot.edge(name, name_ident, label = 'ident') + if isinstance(self.prototype, Graphable): + self.prototype.graph(dot, name, 'prototype') + if self.body and isinstance(self.body, Graphable): + self.body.graph(dot, name, 'body') + # A Javañol declaration Decl = DeclGlobal | DeclFunc diff --git a/compilador/astree/expr.py b/compilador/astree/expr.py index 527e606..b696d51 100644 --- a/compilador/astree/expr.py +++ b/compilador/astree/expr.py @@ -1,7 +1,10 @@ +import uuid +import graphviz as gv from dataclasses import dataclass from enum import Enum, auto from typing import List, Optional +from astree.graphable import Graphable from astree.type import Type from astree.ident import Ident @@ -10,7 +13,14 @@ Expr = None # An identifier access expression. # # a -AccessIdentifier = Ident +@dataclass +class AccessIdentifier(Graphable): + ident: Ident + + def graph(self, dot: gv.Digraph, parent: str = None, edge: str = None) -> None: + name = uuid.uuid1().hex + dot.node(name, self.ident) + dot.edge(parent, name, label = edge) # An access expression. AccessExpr = AccessIdentifier @@ -19,10 +29,18 @@ AccessExpr = AccessIdentifier # # a = 10 @dataclass -class AssignExpr: - _object: Expr +class AssignExpr(Graphable): + _object: AccessExpr value: Expr + def graph(self, dot: gv.Digraph, parent: str = None, edge: str = None) -> None: + name = uuid.uuid1().hex + dot.node(name, 'AssignExpr') + dot.edge(parent, name, label = edge) + self._object.graph(dot, name, 'object') + if isinstance(self.value, Graphable): + self.value.graph(dot, name, 'value') + # A binary arithmetic operator. class BinarithmOp(Enum): BAND = '&' @@ -44,26 +62,51 @@ class BinarithmOp(Enum): # # a * b @dataclass -class BinarithmExpr: +class BinarithmExpr(Graphable): op: BinarithmOp lvalue: Expr rvalue: Expr + def graph(self, dot: gv.Digraph, parent: str = None, edge: str = None) -> None: + name = uuid.uuid1().hex + dot.node(name, 'BinarithmExpr') + dot.edge(parent, name, label = edge) + name_op = uuid.uuid1().hex + dot.node(name_op, self.op.value) + dot.edge(name, name_op, 'op') + if isinstance(self.lvalue, Graphable): + self.lvalue.graph(dot, name, 'lvalue') + if isinstance(self.rvalue, Graphable): + self.rvalue.graph(dot, name, 'rvalue') + # A break expression. # # detener @dataclass -class BreakExpr: - pass +class BreakExpr(Graphable): + def graph(self, dot: gv.Digraph, parent: str = None, edge: str = None) -> None: + name = uuid.uuid1().hex + dot.node(name, 'BreakExpr') + dot.edge(parent, name, label = edge) # A function call expression. # # foo(bar) @dataclass -class CallExpr: +class CallExpr(Graphable): lvalue: Expr args: List[Expr] + def graph(self, dot: gv.Digraph, parent: str = None, edge: str = None) -> None: + name = uuid.uuid1().hex + dot.node(name, 'CallExpr') + dot.edge(parent, name, label = edge) + if isinstance(self.lvalue, Graphable): + self.lvalue.graph(dot, name, 'lvalue') + for a in self.args: + if isinstance(a, Graphable): + a.graph(dot, name, 'arg') + # A compound expression. # # { @@ -72,53 +115,84 @@ class CallExpr: # // ... # } @dataclass -class CompoundExpr: +class CompoundExpr(Graphable): exprs: List[Expr] + def graph(self, dot: gv.Digraph, parent: str = None, edge: str = None) -> None: + name = uuid.uuid1().hex + dot.node(name, 'CompoundExpr') + dot.edge(parent, name, label = edge) + for e in self.exprs: + if isinstance(e, Graphable): + e.graph(dot, name, 'expr') + # A continue expression. # # continuar @dataclass -class ContinueExpr: - pass +class ContinueExpr(Graphable): + def graph(self, dot: gv.Digraph, parent: str = None, edge: str = None) -> None: + name = uuid.uuid1().hex + dot.node(name, 'ContinueExpr') + dot.edge(parent, name, label = edge) # A scalar value. -Value = bool | str | int | type(None) +@dataclass +class Value(Graphable): + value: bool | str | int + + def graph(self, dot: gv.Digraph, parent: str = None, edge: str = None) -> None: + name = uuid.uuid1().hex + dot.node(name, str(self.value)) + dot.edge(parent, name, label = edge) # An integer constant. @dataclass -class NumberConstant: +class NumberConstant(Graphable): value: int + def graph(self, dot: gv.Digraph, parent: str = None, edge: str = None) -> None: + name = uuid.uuid1().hex + dot.node(name, str(self.value)) + dot.edge(parent, name, label = edge) + # A constant expression. ConstantExpr = Value | NumberConstant -# A for loop. -# -# porcada (entero a = 0; a < b; a++) {} -@dataclass -class ForExpr: - bindings: Optional[Expr] - cond: Expr - afterthought: Optional[Expr] - body: Expr - # An if or if..else expression. # # si (a) { } sino { } @dataclass -class IfExpr: +class IfExpr(Graphable): cond: Expr tbranch: Expr fbranch: Optional[Expr] + def graph(self, dot: gv.Digraph, parent: str = None, edge: str = None) -> None: + name = uuid.uuid1().hex + dot.node(name, 'IfExpr') + dot.edge(parent, name, label = edge) + if isinstance(self.cond, Graphable): + self.cond.graph(dot, name, 'cond') + if isinstance(self.tbranch, Graphable): + self.tbranch.graph(dot, name, 'tbranch') + if self.fbranch and isinstance(self.fbranch, Graphable): + self.fbranch.graph(dot, name, 'fbranch') + # A print statement. # # imprimir a @dataclass -class PrintExpr: +class PrintExpr(Graphable): expr: Expr + def graph(self, dot: gv.Digraph, parent: str = None, edge: str = None) -> None: + name = uuid.uuid1().hex + dot.node(name, 'PrintExpr') + dot.edge(parent, name, label = edge) + if isinstance(self.expr, Graphable): + self.expr.graph(dot, name, 'expr') + # A read statement. # # leer a @@ -126,6 +200,12 @@ class PrintExpr: class ReadExpr: expr: AccessExpr + def graph(self, dot: gv.Digraph, parent: str = None, edge: str = None) -> None: + name = uuid.uuid1().hex + dot.node(name, 'ReadExpr') + dot.edge(parent, name, label = edge) + self.expr.graph(dot, name, 'expr') + # A return statement. # # retorna a @@ -133,16 +213,31 @@ class ReadExpr: class ReturnExpr: expr: Optional[Expr] + def graph(self, dot: gv.Digraph, parent: str = None, edge: str = None) -> None: + name = uuid.uuid1().hex + dot.node(name, 'ReturnExpr') + dot.edge(parent, name, label = edge) + if self.expr and isinstance(self.expr, Graphable): + self.expr.graph(dot, name, 'expr') + # A while expression. # # mientras (cond) { } @dataclass -class WhileExpr: +class WhileExpr(Graphable): cond: Expr body: Expr + def graph(self, dot: gv.Digraph, parent: str = None, edge: str = None) -> None: + name = uuid.uuid1().hex + dot.node(name, 'WhileExpr') + dot.edge(parent, name, label = edge) + if isinstance(self.cond, Graphable): + self.cond.graph(dot, name, 'cond') + if isinstance(self.body, Graphable): + self.body.graph(dot, name, 'body') + # A Javañol expression. Expr = (AccessExpr | AssignExpr | BinarithmExpr | BreakExpr | - CallExpr | ConstantExpr | ContinueExpr | ForExpr | - IfExpr | CompoundExpr | PrintExpr | ReadExpr | - ReturnExpr) + CallExpr | ConstantExpr | ContinueExpr | IfExpr | + CompoundExpr | PrintExpr | ReadExpr | ReturnExpr) diff --git a/compilador/astree/ident.py b/compilador/astree/ident.py index 936b745..ecc7edf 100644 --- a/compilador/astree/ident.py +++ b/compilador/astree/ident.py @@ -1,3 +1,4 @@ from typing import List +from dataclasses import dataclass Ident = str diff --git a/compilador/astree/type.py b/compilador/astree/type.py index 5389702..b254b91 100644 --- a/compilador/astree/type.py +++ b/compilador/astree/type.py @@ -1,7 +1,11 @@ +import uuid +import graphviz as gv +from pprint import pformat from dataclasses import dataclass from typing import List from enum import Enum +from astree.graphable import Graphable from tabla import Token Type = None @@ -14,16 +18,40 @@ class BuiltinType(Enum): INT = Token.INT VOID = Token.VOID + def __str__(self): + return self.value.value + # A parameter to a function type. @dataclass -class FuncParam: +class FuncParam(Graphable): name: str _type: Type + def graph(self, dot: gv.Digraph, parent: str = None, edge: str = None) -> None: + name = uuid.uuid1().hex + dot.node(name, 'FuncParam') + dot.edge(parent, name, label = edge) + name_name = uuid.uuid1().hex + dot.node(name_name, self.name) + dot.edge(name, name_name, 'name') + name_type = uuid.uuid1().hex + dot.node(name_type, str(self._type)) + dot.edge(name, name_type, 'type') + # funcion vacio ... (a: int, b: int ...) @dataclass -class FuncType: +class FuncType(Graphable): result: Type params: List[FuncParam] + def graph(self, dot: gv.Digraph, parent: str = None, edge: str = None) -> None: + name = uuid.uuid1().hex + dot.node(name, 'FuncType') + dot.edge(parent, name, label = edge) + name_result = uuid.uuid1().hex + dot.node(name_result, str(self.result)) + dot.edge(name, name_result, 'result') + for p in self.params: + p.graph(dot, name, 'param') + Type = BuiltinType diff --git a/compilador/astree/unit.py b/compilador/astree/unit.py index 8ffdf19..c089214 100644 --- a/compilador/astree/unit.py +++ b/compilador/astree/unit.py @@ -1,9 +1,21 @@ +import uuid +import graphviz as gv from dataclasses import dataclass from typing import List +from astree.graphable import Graphable from astree.decl import Decl # A single compilation unit, representing all of the members of a namespace. @dataclass -class Unit: +class Unit(Graphable): decls: List[Decl] + + def graph(self, dot: gv.Digraph, parent: str = None, edge: str = None) -> None: + name = uuid.uuid1().hex + dot.node(name, 'Unit') + if parent: + dot.edge(name, parent, label = edge) + for d in self.decls: + if isinstance(d, Graphable): + d.graph(dot, name, 'decl') |