Source code for prodigy.pgcl.compiler

# pylint: disable=line-too-long  # style as taken over from probably
"""
-----------------
Compiler Frontend
-----------------

This module provides an API that combines parsing and type-checking all at once.
It is just a thin wrapper around the parser, type-checker, and constant substitution.

Refer to :mod:`prodigy.pgcl.parser` and :mod:`prodigy.pgcl.check` for the parser and type-checker respectively.
Variable/constant substituion is implemented in :mod:`prodigy.pgcl.substitute`.
"""

from typing import Dict, List, Union

from prodigy.pgcl import substitute
from prodigy.pgcl.util.ref import Mut

from .ast import Expr, Program, Var, VarDecl
from .check import (CheckFail, check_expectation, check_expression,
                    check_program, sample_predefined_functions)
from .parser import parse_expectation, parse_expr, parse_pgcl


[docs] def compile_pgcl( code: str, *, substitute_constants=True, predefined_functions: Dict[Var, List[VarDecl]] = sample_predefined_functions ) -> Union[Program, CheckFail]: """ Parse and type-check a pGCL program. .. doctest:: >>> compile_pgcl("nat x; nat y; x := y") Program(variables={'x': NatType(bounds=None), 'y': NatType(bounds=None)}, constants={}, parameters={}, functions={}, instructions=[AsgnInstr(lhs='x', rhs=VarExpr('y'))]) >>> compile_pgcl("x := y") CheckFail(location=..., message='x is not a variable.') Args: code: substitute_constants: Whether constant substitution is done on the program, defaults to `True`. """ program = parse_pgcl(code) if substitute_constants: substitute.substitute_constants(program) check_result = check_program(program, predefined_functions) if check_result is not None: return check_result return program
[docs] def compile_expr( program: Program, code: str, *, substitute_constants=True, predefined_functions: Dict[Var, List[VarDecl]] = sample_predefined_functions ) -> Union[Expr, CheckFail]: """ Parse and type-check an expression. Args: program: code: substitute_constants: Whether constant substitution is done on the expression, defaults to `True`. """ expr = parse_expr(code) check_result = check_expression(program, expr, predefined_functions) if check_result is not None: return check_result if substitute_constants: expr_ref = Mut.alloc(expr) substitute.substitute_constants_expr(program, expr_ref) return expr_ref.val return expr
[docs] def compile_expectation( program: Program, code: str, *, substitute_constants=True, predefined_functions: Dict[Var, List[VarDecl]] = sample_predefined_functions ) -> Union[Expr, CheckFail]: """ Parse and type-check an expectation. Args: program: code: substitute_constants: Whether constant substitution is done on the expectation, defaults to `True`. """ expr = parse_expectation(code) check_result = check_expectation(program, expr, predefined_functions) if check_result is not None: return check_result if substitute_constants: expr_ref = Mut.alloc(expr) substitute.substitute_constants_expr(program, expr_ref) return expr_ref.val return expr