From 36b1fad7fed4749f3d5824eea40331574dfd5961 Mon Sep 17 00:00:00 2001 From: Antoine Viallon Date: Fri, 12 May 2023 01:37:54 +0200 Subject: [PATCH] parser+nodes+tokenizer: add Blocks --- compiler/__main__.py | 10 +++++++++- compiler/nodes.py | 13 +++++++++++++ compiler/parser.py | 10 ++++++++-- compiler/tokenizer.py | 2 ++ 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/compiler/__main__.py b/compiler/__main__.py index 646ad90..4049dc0 100644 --- a/compiler/__main__.py +++ b/compiler/__main__.py @@ -18,8 +18,15 @@ def main(): args = parser.parse_args() data = """ + { + byte = 42; + } 2 + 8 - 1 * (byte = 3 + 5) / (byte = 255) + byte; + byte = byte + byte; + { + a = byte; + } """ if not args.mock: data = sys.stdin.read().strip() @@ -39,7 +46,6 @@ def main(): context = semantic.Context("root") ast.semantic_analysis(context) - print(context) intermediate_representation = ast.intermediate_representation() @@ -55,6 +61,8 @@ def main(): messages += [f"{repr(ir_item)}\n"] print("\n".join(messages)) + + print("\n---\n", repr(context)) except CompilationError as e: e.location.source = data print(f"{e}\n{e.location.show_in_source()}", file=sys.stderr) diff --git a/compiler/nodes.py b/compiler/nodes.py index 37cec2c..ddf2aac 100644 --- a/compiler/nodes.py +++ b/compiler/nodes.py @@ -270,6 +270,19 @@ class Statement(Node): return result +class Block(Statement): + def __init__(self, name: str, *nodes: Node): + super().__init__(*nodes) + self.name = name + + def semantic_analysis(self, context: semantic.Context | None): + child_context = semantic.Context(name=self.name, parent=context) + if context is not None: + context.add_context(child_context) + logger.debug(f"Created new context: {child_context}") + super().semantic_analysis(child_context) + + class Identifier(Literal): def __init__(self, location: SourceLocation, name: str): super().__init__(location, name) diff --git a/compiler/parser.py b/compiler/parser.py index 9f027b0..411ea27 100644 --- a/compiler/parser.py +++ b/compiler/parser.py @@ -5,7 +5,7 @@ from beartype.typing import List, Dict, Callable from .errors import CompilationError, UnexpectedTokenError from .logger import Logger, Tracer, LogLevel from .nodes import Float, Sum, Value, Product, Node, Division, Sub, Integer, Expression, Identifier, Assignment, \ - Variable, Statement, PseudoNode + Variable, Statement, PseudoNode, Block from .tokenizer import Tokens, Token logger = Logger(__name__) @@ -161,9 +161,15 @@ class Parser: elif mandatory: raise UnexpectedTokenError(expr, wanted="expression") + def block(self, name: str) -> Block: + nodes: list[Statement] = [] + while stmt := self.statement(mandatory=False): + nodes += [stmt] + return Block(name, *nodes) + @tracer.trace_method def root(self) -> Node: - return self.statement(mandatory=True) + return self.block(name="root") def parse(self) -> Node: try: diff --git a/compiler/tokenizer.py b/compiler/tokenizer.py index 14d5fee..1c0727c 100644 --- a/compiler/tokenizer.py +++ b/compiler/tokenizer.py @@ -33,6 +33,8 @@ class Tokens(enum.Enum): Op_Divide = re.compile(r"/") Parens_Left = re.compile(r"\(") Parens_Right = re.compile(r"\)") + Brace_Left = re.compile(r"\{") + Brace_Right = re.compile(r"}") Identifier = re.compile(r"[a-zA-Z_][a-zA-Z_0-9]*") Equal = re.compile(r"=") Semicolon = re.compile(r";")