aboutsummaryrefslogtreecommitdiff
path: root/compilador/astree
diff options
context:
space:
mode:
authorIván Ávalos <avalos@disroot.org>2022-11-25 21:29:55 -0600
committerIván Ávalos <avalos@disroot.org>2022-11-25 21:29:55 -0600
commit6b27930ef9c3eaede8d0c283ffa8376c40145f80 (patch)
treee2f2f8a25defb68283910edea33768054f435bc9 /compilador/astree
parent4b2fad150a292f882cee408d7f9746715225f7cb (diff)
downloadjavanol-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.py31
-rw-r--r--compilador/astree/expr.py151
-rw-r--r--compilador/astree/ident.py1
-rw-r--r--compilador/astree/type.py32
-rw-r--r--compilador/astree/unit.py14
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')