aboutsummaryrefslogtreecommitdiff
path: root/compilador/astree/expr.py
diff options
context:
space:
mode:
Diffstat (limited to 'compilador/astree/expr.py')
-rw-r--r--compilador/astree/expr.py151
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)