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/expr.py | |
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/expr.py')
-rw-r--r-- | compilador/astree/expr.py | 151 |
1 files changed, 123 insertions, 28 deletions
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) |