Skip to content

Commit 6fa86b9

Browse files
committed
Fix #7 using a name resolver on call arguments
1 parent 3c5f87e commit 6fa86b9

File tree

3 files changed

+26
-15
lines changed

3 files changed

+26
-15
lines changed

OWScript/AST.py

+5
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,11 @@ def __init__(self, name, player=None):
468468
super().__init__(name)
469469
self.player = player or Constant(name='Event Player')
470470

471+
class VarType:
472+
# Compares whether a value is a GlobalVar or PlayerVar
473+
def __eq__(self, other):
474+
return other in (GlobalVar, PlayerVar)
475+
471476
class If(AST):
472477
def __init__(self, cond, true_block, false_block=None):
473478
self.cond = cond

OWScript/Transpiler.py

+17-7
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ def resolve_skips(self):
128128
self.curblock[skip] = self.curblock[skip].format(jump)
129129

130130
def resolve_import(self, node, scope):
131-
# TODO - Resolves imports recursively
132131
children = self.visit(node, scope).children
133132
nodes = []
134133
for child in children:
@@ -142,6 +141,16 @@ def resolve_import(self, node, scope):
142141
nodes.append(child)
143142
return nodes
144143

144+
def resolve_name(self, node, scope):
145+
if type(node) == VarType():
146+
node = scope.get(node.name)
147+
if type(node) == Variable:
148+
return node.value
149+
elif type(node) == BinaryOp:
150+
node.left = self.resolve_name(node.left, scope)
151+
node.right = self.resolve_name(node.right, scope)
152+
return node
153+
145154
def visitScript(self, node, scope):
146155
code = r'rule("Generated by https://github.com/adapap/OWScript") { Event { Ongoing - Global; } Actions { Set Global Variable At Index(A, 0, Round To Integer(Add(Distance Between(Nearest Walkable Position(Vector(-500.000, 0, 0)), Nearest Walkable Position(Vector(500, 0, 0))), Distance Between(Nearest Walkable Position(Vector(0, 0, -500.000)), Nearest Walkable Position(Vector(0, 0, 500)))), Down)); }}' + '\n'
147156
while len(node.children) > 0:
@@ -232,7 +241,7 @@ def visitOWID(self, node, scope):
232241
continue
233242
elif arg == Variable:
234243
try:
235-
assert type(child) in (GlobalVar, PlayerVar)
244+
assert type(child) == VarType()
236245
if child.name not in self.varconsts:
237246
constgen = self.global_varconst if type(child) == GlobalVar else self.player_varconst
238247
try:
@@ -351,7 +360,7 @@ def visitFor(self, node, scope):
351360
code = ''
352361
pointer = node.pointer
353362
iterable = node.iterable
354-
if type(iterable) in (GlobalVar, PlayerVar) and type(scope.get(iterable.name).value) == Array:
363+
if type(iterable) == VarType() and type(scope.get(iterable.name).value) == Array:
355364
lines = []
356365
array = scope.get(iterable.name).value
357366
for elem in scope.get(iterable.name).value.elements:
@@ -506,7 +515,7 @@ def visitArray(self, node, scope):
506515
return code
507516

508517
def visitItem(self, node, scope):
509-
if type(node.index) == Number and type(node.parent) in (GlobalVar, PlayerVar):
518+
if type(node.index) == Number and type(node.parent) == VarType():
510519
try:
511520
index = int(node.index.value)
512521
var = scope.get(node.parent.name)
@@ -549,7 +558,7 @@ def visitCall(self, node, scope):
549558
if type(parent) == Attribute:
550559
if type(base_node) == Variable:
551560
method = getattr(base_node.value, parent.name)
552-
elif type(base_node) in (GlobalVar, PlayerVar):
561+
elif type(base_node) == VarType():
553562
method = getattr(scope.get(base_node.name).value, parent.name)
554563
else:
555564
method = getattr(base_node, parent.name)
@@ -562,7 +571,7 @@ def visitCall(self, node, scope):
562571
if result:
563572
lines.append(self.visit(result, scope))
564573
return ';\n'.join(lines)
565-
elif type(parent) in (GlobalVar, PlayerVar):
574+
elif type(parent) == VarType():
566575
func_name = parent.name[5:]
567576
else:
568577
print('DEBUG - Call Origin:', type(parent))
@@ -576,8 +585,9 @@ def visitCall(self, node, scope):
576585
except AssertionError:
577586
raise Errors.InvalidParameter('\'{}\' expected {} arguments, received {}'.format(func_name, len(func.params), len(node.args)), pos=node._pos)
578587
# Resolve variables in call
588+
args = [self.resolve_name(arg, scope) for arg in node.args]
579589
scope = Scope(name=func_name, parent=scope)
580-
scope.namespace.update(dict(zip(map(lambda p: p.name, func.params), node.args)))
590+
scope.namespace.update(dict(zip(map(lambda p: p.name, func.params), args)))
581591
for child in func.children:
582592
try:
583593
lines.append(self.visit(child, scope=scope))

README.md

+4-8
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ Setup
1010
- `-m | --min` Optional: minifies the output by stripping whitespace
1111
- `-s | --save [FILE]` Optional: saves to the target output file instead of stdout
1212
- `-c | --copy` Optional: copies code to clipboard (must have *pyperclip* installed: `pip install pyperclip`)
13-
- `--enable-imports` Optional: Enables the experimental import functionality.
1413

1514
## Syntax Highlighting
1615
In the `Syntax/` folder, you can find the raw Iro code which I used to generate a Sublime Text file with modifications. You can directly import the `OWScript.sublime-syntax` file by putting it in your ST3 `User` folder.
@@ -293,12 +292,9 @@ scores.append(123) // Method
293292
## Imports
294293
OWScript allows bigger scripts and scripts that use common funcitonality to be broken up into modules and imported into a base file. All the "imported" files are directly copied into the base script to be transpiled to workshop code.
295294

296-
To use this experimental feature, add the `--enable-imports` flag to the command and it will search your script for imports. This is recursive and allows for importing modules within modules. The modules you're importing **must** have the `.owpy` file ending to be properly imported or it will not be able to find the the module.
295+
You can import a file by using the `#import 'filepath'`. If the file is in a folder, put the relative path to the file as shown in the examples below:
297296

298-
You can import a file by using the `#import 'filename'`
299-
300-
### Example
301-
File: `lib/functions.owpy`
297+
**Imported File** `lib/functions.owpy`
302298
```
303299
%CreateEffect(pos, type, color)
304300
Create Effect
@@ -310,7 +306,7 @@ File: `lib/functions.owpy`
310306
Reevaluation: Visible To
311307
```
312308

313-
File `src/setup.owpy`
309+
**Imported File** `src/setup.owpy`
314310
```
315311
Rule "Setup Effects"
316312
Event
@@ -319,7 +315,7 @@ Rule "Setup Effects"
319315
CreateEffect(<0,0,0>, Ring, Red)
320316
```
321317

322-
File: `src/game.owpy`
318+
**Base File** `src/game.owpy`
323319
```
324320
#import 'lib/functions'
325321
#import 'src/setup'

0 commit comments

Comments
 (0)