Skip to content

Commit 1e665d8

Browse files
committed
Stricter enforcement of branching at the end of a basic block. Add modifier to blocks so they can be labelled as functions
1 parent 6ab0e1a commit 1e665d8

File tree

9 files changed

+246
-77
lines changed

9 files changed

+246
-77
lines changed

assembler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ def resolve_ref(self, type, value):
255255
def callinsn(self, dest):
256256
if isinstance(dest, VisibleFunction):
257257
return Invoke(dest, None, None)
258-
return Call(dest)
258+
return Branch(dest)
259259

260260
def get_src_dest(self, src, dest):
261261
src, dest = self.resolve_ref(*src), self.resolve_ref(*dest)

cmd_ir/core.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@ def end(self):
475475
assert not self.finished
476476
for block in self.blocks:
477477
block.end()
478+
print("%s is closed: %s" % (self, self.is_closed()))
478479
self._finished = True
479480

480481
def get_func_table(self):
@@ -523,6 +524,7 @@ def variables_finalized(self):
523524
stackvars = self.add_entry_exit()
524525
self.configure_parameters(bool(stackvars))
525526
if self.is_closed():
527+
self._entryblock.force = True
526528
for insn in self._exitblock.insns:
527529
self._entryblock.add(insn)
528530
self._exitblock.insns = []
@@ -533,7 +535,7 @@ def variables_finalized(self):
533535

534536
def add_entry_exit(self):
535537
from .variables import LocalVariable, NbtOffsetVariable
536-
from .instructions import PushNewStackFrame, PopStack, Call
538+
from .instructions import PushNewStackFrame, PopStack, Branch
537539
# sorted from head to tail of stack
538540
vars = sorted([var.var for var in self.scope.values() \
539541
if isinstance(var, LocalVariable) \
@@ -549,7 +551,7 @@ def add_entry_exit(self):
549551
in vars[::-1])))
550552
self._exitblock.add(PopStack())
551553
# Always branch to real entry point
552-
self._entryblock.add(Call(self.blocks[0]))
554+
self._entryblock.add(Branch(self.blocks[0]))
553555
return vars
554556

555557
def add_advancement_revoke(self, event):
@@ -574,6 +576,8 @@ def __init__(self, name, func):
574576
self._func = func
575577
self.needs_success_tracker = False
576578
self.defined = False
579+
self.is_function = False
580+
self.force = False
577581
self._use = 0
578582

579583
def usage(self):
@@ -585,6 +589,9 @@ def reset(self):
585589
def use_count(self):
586590
return self._use
587591

592+
def set_is_function(self):
593+
self.is_function = True
594+
588595
@property
589596
def global_name(self):
590597
return self._func._name + '/' + self._name
@@ -597,14 +604,19 @@ def end(self):
597604

598605
def is_terminated(self):
599606
assert self.defined
607+
if self.is_function:
608+
return True
600609
if not self.insns:
601610
return False
602611
return self.insns[-1].terminator()
603612

604613
def add(self, insn):
605-
from .instructions import Return, Call
614+
if not self.force and self.insns and self.insns[-1].terminator():
615+
assert False, "Block %s is terminated by %s. Tried adding %s" % (
616+
self, self.insns[-1], insn)
617+
from .instructions import Return, Branch
606618
if isinstance(insn, Return):
607-
return super().add(Call(self._func._exitblock))
619+
return super().add(Branch(self._func._exitblock))
608620
return super().add(insn)
609621

610622
def writeout(self, temp_gen):

cmd_ir/core_types.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,15 +185,20 @@ class BlockType(Resolvable, NativeType):
185185

186186
def __init__(self, block_id):
187187
self.block_id = block_id
188+
self.nbt = None
188189
self.props = {}
189190

190191
def add_prop(self, prop, value):
191192
self.props[prop] = value
192193

194+
def set_nbt(self, nbt):
195+
self.nbt = nbt
196+
193197
def resolve(self, scope):
194198
props = ','.join(['%s=%s' % (key, self.props[key]) \
195199
for key in sorted(self.props.keys())])
196-
return '%s%s' % (self.block_id, '[%s]' % props if props else '')
200+
nbt = self.nbt.resolve(scope) if self.nbt is not None else ''
201+
return '%s%s%s' % (self.block_id, '[%s]' % props if props else '', nbt)
197202

198203
class ItemType(Resolvable, NativeType):
199204

@@ -209,5 +214,5 @@ def resolve(self, scope):
209214
if self.nbt_props:
210215
from .nbt import NBTCompound
211216
nbt = NBTCompound(self.nbt_props.items())
212-
props = '[%s]' % nbt.resolve(scope)
217+
props = nbt.resolve(scope)
213218
return '%s%s' % (self.item_id, props)

cmd_ir/grammar.lark

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ function: "function" FUNC_NAME "{" function_body "}"
1010

1111
function_body: preamble? block*
1212

13-
block: LABEL NEWLINE instruction*
13+
block: block_modifier? LABEL NEWLINE instruction*
14+
15+
block_modifier: "[" WORD "]"
1416

1517
instruction: ( assign_insn | normal_insn ) NEWLINE
1618

@@ -44,6 +46,7 @@ ASSIGN_OP: "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "><" | "<" | ">"
4446
%import common.SIGNED_FLOAT
4547
%import common.WS
4648
%import common.NEWLINE
49+
%import common.WORD
4750

4851
%ignore WS
4952
COMMENT: "#" /[^\n]/*

0 commit comments

Comments
 (0)