Skip to content

Commit b648e8e

Browse files
committed
Some minor fixes
1 parent cfd4640 commit b648e8e

File tree

6 files changed

+70
-23
lines changed

6 files changed

+70
-23
lines changed

commands.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ def at_entity_pos(self, select_arg):
231231
return self.add('positioned', 'as', ensure_selector(select_arg))
232232

233233
def align(self, axes):
234-
assert [axis for axis in axes if axis in 'xyz']
234+
assert ''.join(axis for axis in axes if axis in 'xyz') == axes
235235
return self.add('align', axes)
236236

237237
def facing(self, pos):
@@ -340,7 +340,7 @@ def arg_to_json(self, arg, scope):
340340
return {'text': arg}
341341
if isinstance(arg, Ref):
342342
return {'score':
343-
{'name': EntityTag.resolve(scope),
343+
{'name': arg.selector(None).resolve(scope),
344344
'objective': arg.resolve(scope)}}
345345
else:
346346
raise RuntimeError('Unknown argument type %r' % type(arg))

compiler/compiler.py

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,7 @@ def visit_pragma(self, pragma):
625625
'event_condition': self.visit_pragma_event_condition,
626626
'update_this_entity_data': self.visit_pragma_update_this_entity,
627627
'select_entities': self.visit_pragma_select_entities,
628+
'select_entities_not_matching': self.visit_pragma_select_not_match,
628629
'if_this_entity': self.visit_pragma_if_this_entity,
629630
'at_this_entity': self.visit_pragma_at_this_entity,
630631
'exec_align': self.visit_pragma_exec_align,
@@ -665,9 +666,7 @@ def _execute_chain_helper(self, exec_type, args):
665666
self.after_next_statement(lambda: self.emit(IR.ExecEnd(label)))
666667

667668
def visit_pragma_select_entities(self, selector):
668-
assert 'select_entities' not in self.pragmas
669669
selector, sel_inv = self.parse_selector_match(selector)
670-
self.pragmas['select_entities'] = True
671670
sel_dict = selector if selector else sel_inv
672671
label = self.unique_label('exec_sel')
673672
inv = 'N' if not selector else ''
@@ -679,12 +678,18 @@ def visit_pragma_select_entities(self, selector):
679678
self.emit(IR.ExecSel(label_inv, 'ASN', 'e', sel_inv.items()))
680679

681680
def run_after():
682-
del self.pragmas['select_entities']
683681
if label_inv:
684682
self.emit(IR.ExecEnd(label_inv))
685683
self.emit(IR.ExecEnd(label))
686684
self.after_next_statement(run_after)
687685

686+
def visit_pragma_select_not_match(self, selector):
687+
selector, sel_inv = self.parse_selector_match(selector)
688+
assert not sel_inv, "TODO"
689+
label = self.unique_label('exec_sel_not')
690+
self.emit(IR.ExecSel(label, 'ASN', 'e', selector.items()))
691+
self.after_next_statement(lambda: self.emit(IR.ExecEnd(label)))
692+
688693
def visit_pragma_if_this_entity(self, selector):
689694
selector, sel_inv = self.parse_selector_match(selector)
690695
assert not sel_inv, "TODO"
@@ -783,13 +788,14 @@ def stringify_nbt(self, node):
783788
for k,v in node.items())
784789
if type(node) == list:
785790
return '[%s]' % ','.join(map(self.stringify_nbt, node))
786-
if type(node) == str:
787-
return '"%s"' % node
788-
if type(node) == int:
789-
return str(node)
790-
if type(node) == float:
791-
return '%ff' % node
792-
assert False
791+
if type(node) == tuple:
792+
val_type, value = node
793+
if val_type == 'string':
794+
return '"%s"' % value
795+
if val_type in ['int', 'float', 'byte']:
796+
return value
797+
assert False, val_type
798+
assert False, type(node)
793799

794800
def read_nbt_specification(self, parent, path, value):
795801
path = path.split('.')
@@ -810,21 +816,34 @@ def read_nbt_specification(self, parent, path, value):
810816
else:
811817
assert type(parent[node]) == list
812818
parent = parent[node]
813-
if value.isdigit():
814-
value = int(value)
815-
elif value[0].isdigit():
816-
# check for floating points
817-
if value.count('.') == 1 and value.endswith('f'):
819+
val_type = 'string'
820+
# check for numbers
821+
looks_like_num = value[0].isdigit() or value[0] == '-'
822+
if looks_like_num:
823+
if value.endswith('b'):
824+
try:
825+
int(value[:-1])
826+
val_type = 'byte'
827+
except ValueError:
828+
pass
829+
elif value.endswith('f'):
830+
try:
831+
float(value[:-1])
832+
val_type = 'float'
833+
except ValueError:
834+
pass
835+
else:
818836
try:
819-
value = float(value[:-1])
837+
int(value)
838+
val_type = 'int'
820839
except ValueError:
821840
pass
822841
if path[-1].isdigit():
823842
pos = int(path[-1])
824843
while len(parent) < pos + 1:
825844
parent.append({})
826845
path[-1] = pos
827-
parent[path[-1]] = value
846+
parent[path[-1]] = (val_type, value)
828847

829848
### Declarations
830849

compiler/include/entity.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
#define select_entities(...) _Pragma("select_entities __VA_ARGS__")
1212

13+
#define select_entities_not_matching(...) _Pragma("select_entities_not_matching __VA_ARGS__")
14+
1315
#define select_players(...) _Pragma("select_entities match:type=player, __VA_ARGS__")
1416

1517
#define sel_match(key, value) match:key=value
@@ -35,4 +37,6 @@
3537
void add_tag_this_entity(const char *tag);
3638
void remove_tag_this_entity(const char *tag);
3739

40+
void set_scoreboard_tracking(entity_local variable, const char *criterion);
41+
3842
#endif /* __ENTITY_H */

compiler/lib/entity.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from ..ir import IR
2+
from ..nodes import IdentifierExpr
23

34
def add_tag(visitor, expr):
45
assert len(expr.args) == 1, "add_tag_this_entity takes 1 argument"
@@ -16,8 +17,22 @@ def remove_tag(visitor, expr):
1617
cmd = 'tag @s remove ' + tag
1718
visitor.emit(IR.Asm((('CMD ' + cmd, None, None),)))
1819

20+
def set_tracking(visitor, expr):
21+
assert len(expr.args) == 2
22+
assert isinstance(expr.args[0], IdentifierExpr)
23+
var = visitor.visit_expression(expr.args[0])
24+
criterion = visitor.visit_expression(expr.args[1])
25+
assert var.type is visitor.type('entity_local')
26+
assert isinstance(criterion, IR.LiteralString), ""
27+
var_name = '$entity_local:%s$' % expr.args[0].val
28+
rem_old = 'scoreboard objectives remove %s' % var_name
29+
add_new = 'scoreboard objectives add %s %s' % (var_name, criterion.val)
30+
visitor.emit(IR.Asm((('CMD ' + rem_old, None, None),)))
31+
visitor.emit(IR.Asm((('CMD ' + add_new, None, None),)))
32+
1933
def exports():
2034
return {
2135
'add_tag_this_entity': add_tag,
2236
'remove_tag_this_entity': remove_tag,
37+
'set_scoreboard_tracking': set_tracking,
2338
}

examples/mclib.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,8 @@
2828
*/
2929
#define ASM_swap(a, b) __asm__("XCHG >?, >?", a, b)
3030

31+
#define EVENT_CONDITION(cond) _Pragma("event_condition cond")
32+
33+
#define EVENT(event, cond, name) _Pragma("event_handler event") cond void name()
34+
3135
#endif /* __MCLIB_H */

session.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,14 +189,19 @@ def add_command_blocks(self, lines):
189189
print()
190190

191191
def add_event_handler(self, event_name, conditions, handler):
192-
if event_name == 'minecraft:tick':
192+
tag_events = {
193+
'minecraft:tick': ('minecraft', 'tick'),
194+
'minecraft:load': ('minecraft', 'load')
195+
}
196+
if event_name in tag_events:
193197
assert not conditions
194-
self.writer.write_tag('functions', 'tick', [
198+
namespace, tag_name = tag_events[event_name]
199+
self.writer.write_tag('functions', tag_name, [
195200
self.scope.function_name(handler)
196-
], namespace='minecraft')
201+
], namespace=namespace)
197202
if self.print_debug:
198203
print('Tag')
199-
print('Tick handler:', handler)
204+
print('%s: %s' % (tag_name, handler))
200205
print()
201206
return
202207
# TODO refactor

0 commit comments

Comments
 (0)