Fix argument insertion
This commit is contained in:
@@ -41,13 +41,20 @@ class MaMa:
|
|||||||
|
|
||||||
# Decodes string MaMa instructions to function callables
|
# Decodes string MaMa instructions to function callables
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def decode(micro: str) -> Tuple[str, Optional[List[int]]]:
|
def decode(micro: str) -> Tuple[str, Optional[List[Any]]]:
|
||||||
if "(" in micro:
|
if "(" in micro:
|
||||||
name, rest = micro.split("(", 1)
|
name, rest = micro.split("(", 1)
|
||||||
args_str = rest[:-1]
|
args_str = rest[:-1].strip()
|
||||||
if args_str.strip() == "":
|
if args_str == "":
|
||||||
return name, []
|
return name, []
|
||||||
args = [int(a.strip()) for a in args_str.split(",")]
|
args = []
|
||||||
|
for a in args_str.split(","):
|
||||||
|
a = a.strip()
|
||||||
|
try:
|
||||||
|
a = int(a)
|
||||||
|
except ValueError:
|
||||||
|
pass # keep symbolic argument (e.g., 'n')
|
||||||
|
args.append(a)
|
||||||
return name, args
|
return name, args
|
||||||
return micro, None
|
return micro, None
|
||||||
|
|
||||||
|
|||||||
@@ -26,17 +26,29 @@ class MaMaMa(MaMa):
|
|||||||
|
|
||||||
# Flatten macros recursively
|
# Flatten macros recursively
|
||||||
def __flatten_macro(self) -> None:
|
def __flatten_macro(self) -> None:
|
||||||
def expand(prog: Dict[int, str], stack: List[str]) -> List[Tuple[str, List[str]]]:
|
def expand(prog: Dict[int, str], stack: List[str], env: Dict[str, Any]) -> List[Tuple[str, List[str]]]:
|
||||||
out: List[Tuple[str, List[str]]] = []
|
out: List[Tuple[str, List[str]]] = []
|
||||||
for _, micro in sorted(prog.items()):
|
for _, micro in sorted(prog.items()):
|
||||||
name, args = self.decode(micro)
|
name, args = self.decode(micro)
|
||||||
|
|
||||||
|
# substitute arguments if defined in env
|
||||||
|
if args:
|
||||||
|
args = [env.get(str(a), a) for a in args]
|
||||||
|
micro = f"{name}({','.join(map(str, args))})"
|
||||||
|
|
||||||
if name in self.macros:
|
if name in self.macros:
|
||||||
out.extend(expand(self.macros[name]["prog"], stack + [name]))
|
macro = self.macros[name]
|
||||||
|
params = macro.get("args") or []
|
||||||
|
new_env = env.copy()
|
||||||
|
if args and params:
|
||||||
|
for p, v in zip(params, args):
|
||||||
|
new_env[p] = v
|
||||||
|
out.extend(expand(macro["prog"], stack + [name], new_env))
|
||||||
else:
|
else:
|
||||||
out.append((micro, list(stack)))
|
out.append((micro, list(stack)))
|
||||||
return out
|
return out
|
||||||
|
|
||||||
expanded = expand(self.prog, [])
|
expanded = expand(self.prog, [], {})
|
||||||
self.prog = {i: call for i, (call, _) in enumerate(expanded)}
|
self.prog = {i: call for i, (call, _) in enumerate(expanded)}
|
||||||
self._macro_trace = {i: macros for i, (_, macros) in enumerate(expanded)}
|
self._macro_trace = {i: macros for i, (_, macros) in enumerate(expanded)}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ if __name__ == "__main__":
|
|||||||
8: 'leq(14)',
|
8: 'leq(14)',
|
||||||
9: 'ldo(-1)',
|
9: 'ldo(-1)',
|
||||||
10: 'ldo(-1)',
|
10: 'ldo(-1)',
|
||||||
11: 'subs',
|
11: 'sub',
|
||||||
12: 'sto(-2)',
|
12: 'sto(-2)',
|
||||||
13: 'ujp(6)',
|
13: 'ujp(6)',
|
||||||
14: 'ldo(-1)',
|
14: 'ldo(-1)',
|
||||||
@@ -27,11 +27,12 @@ if __name__ == "__main__":
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Create and execute MaMa instance
|
# Create and execute MaMa instance
|
||||||
machine = MaMaMa(prog, [4, 6])
|
machine = MaMaMa(['equal0(3)', 'stop', 'push(10)', 'stop'], [4, 6, 0])
|
||||||
|
|
||||||
machine.add_macro('subs', {
|
machine.add_macro('equal0', [
|
||||||
0: "sub",
|
'push(0)',
|
||||||
})
|
'equal(n)'
|
||||||
|
], ["n"])
|
||||||
|
|
||||||
# Visualize finished execution using journal
|
# Visualize finished execution using journal
|
||||||
gui = MaMaGUI(machine)
|
gui = MaMaGUI(machine)
|
||||||
|
|||||||
Reference in New Issue
Block a user