mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
GH-111485: Separate out parsing, analysis and code-gen phases of tier 1 code generator (GH-112299)
This commit is contained in:
parent
3d712a9f4c
commit
b449415b2f
15 changed files with 1675 additions and 526 deletions
81
Tools/cases_generator/stack.py
Normal file
81
Tools/cases_generator/stack.py
Normal file
|
@ -0,0 +1,81 @@
|
|||
import sys
|
||||
from analyzer import StackItem
|
||||
from dataclasses import dataclass
|
||||
from formatting import maybe_parenthesize
|
||||
|
||||
|
||||
def var_size(var: StackItem) -> str:
|
||||
if var.condition:
|
||||
# Special case simplification
|
||||
if var.condition == "oparg & 1" and var.size == "1":
|
||||
return f"({var.condition})"
|
||||
else:
|
||||
return f"(({var.condition}) ? {var.size} : 0)"
|
||||
else:
|
||||
return var.size
|
||||
|
||||
|
||||
class StackOffset:
|
||||
"The stack offset of the virtual base of the stack from the physical stack pointer"
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.popped: list[str] = []
|
||||
self.pushed: list[str] = []
|
||||
|
||||
def pop(self, item: StackItem) -> None:
|
||||
self.popped.append(var_size(item))
|
||||
|
||||
def push(self, item: StackItem) -> None:
|
||||
self.pushed.append(var_size(item))
|
||||
|
||||
def simplify(self) -> None:
|
||||
"Remove matching values from both the popped and pushed list"
|
||||
if not self.popped or not self.pushed:
|
||||
return
|
||||
# Sort the list so the lexically largest element is last.
|
||||
popped = sorted(self.popped)
|
||||
pushed = sorted(self.pushed)
|
||||
self.popped = []
|
||||
self.pushed = []
|
||||
while popped and pushed:
|
||||
pop = popped.pop()
|
||||
push = pushed.pop()
|
||||
if pop == push:
|
||||
pass
|
||||
elif pop > push:
|
||||
# if pop > push, there can be no element in pushed matching pop.
|
||||
self.popped.append(pop)
|
||||
pushed.append(push)
|
||||
else:
|
||||
self.pushed.append(push)
|
||||
popped.append(pop)
|
||||
self.popped.extend(popped)
|
||||
self.pushed.extend(pushed)
|
||||
|
||||
def to_c(self) -> str:
|
||||
self.simplify()
|
||||
int_offset = 0
|
||||
symbol_offset = ""
|
||||
for item in self.popped:
|
||||
try:
|
||||
int_offset -= int(item)
|
||||
except ValueError:
|
||||
symbol_offset += f" - {maybe_parenthesize(item)}"
|
||||
for item in self.pushed:
|
||||
try:
|
||||
int_offset += int(item)
|
||||
except ValueError:
|
||||
symbol_offset += f" + {maybe_parenthesize(item)}"
|
||||
if symbol_offset and not int_offset:
|
||||
res = symbol_offset
|
||||
else:
|
||||
res = f"{int_offset}{symbol_offset}"
|
||||
if res.startswith(" + "):
|
||||
res = res[3:]
|
||||
if res.startswith(" - "):
|
||||
res = "-" + res[3:]
|
||||
return res
|
||||
|
||||
def clear(self) -> None:
|
||||
self.popped = []
|
||||
self.pushed = []
|
Loading…
Add table
Add a link
Reference in a new issue