Skip to content

Commit d27c99b

Browse files
committed
fix: replace standalone functioncalls to expression nodes
1 parent 46dbf42 commit d27c99b

3 files changed

Lines changed: 52 additions & 21 deletions

File tree

evaluation_function/analyzer/interpreter.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,9 @@ def execute_statement(self, node: ASTNode):
119119
elif isinstance(node, ConditionalNode):
120120
self.execute_conditional(node)
121121

122-
elif isinstance(node, FunctionNode):
123-
# Already registered in run()
124-
pass
122+
# elif isinstance(node, FunctionNode):
123+
# # Already registered in run()
124+
# pass
125125

126126
elif isinstance(node, BlockNode):
127127
self.execute_block(node)

evaluation_function/parser/parser.py

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,27 @@ def _parse_fallback(self, code: str) -> ProgramNode:
277277
statements.append(ReturnNode(value=value))
278278
i += 1
279279
continue
280-
280+
# Detect standalone function calls
281+
func_call_match = re.match(r'^([A-Za-z_]\w*)\s*\((.*)\)\s*$', stripped)
282+
if func_call_match:
283+
func_name = func_call_match.group(1)
284+
args_str = func_call_match.group(2)
285+
286+
# Optional: ensure it's not a keyword accidentally matched
287+
if func_name.lower() not in {"if", "for", "while", "return", "print", "function"}:
288+
args = self._parse_argument_list(args_str)
289+
290+
call_node = FunctionCallNode(
291+
function_name=func_name,
292+
arguments=args
293+
)
294+
295+
statements.append(
296+
ExpressionStatementNode(expression=call_node)
297+
)
298+
299+
i += 1
300+
continue
281301
# Skip unknown lines
282302
i += 1
283303

@@ -650,7 +670,27 @@ def _parse_block_fallback(self, lines: List[str], indent_unit: int) -> BlockNode
650670
statements.append(AssignmentNode(target=target, value=value))
651671
i += 1
652672
continue
653-
673+
# Detect standalone function calls
674+
func_call_match = re.match(r'^([A-Za-z_]\w*)\s*\((.*)\)\s*$', stripped)
675+
if func_call_match:
676+
func_name = func_call_match.group(1)
677+
args_str = func_call_match.group(2)
678+
679+
# Optional: ensure it's not a keyword accidentally matched
680+
if func_name.lower() not in {"if", "for", "while", "return", "print", "function"}:
681+
args = self._parse_argument_list(args_str)
682+
683+
call_node = FunctionCallNode(
684+
function_name=func_name,
685+
arguments=args
686+
)
687+
688+
statements.append(
689+
ExpressionStatementNode(expression=call_node)
690+
)
691+
692+
i += 1
693+
continue
654694
# Unknown statement - skip
655695
i += 1
656696

evaluation_function/tests/test_scope.py

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,7 @@
55
import pytest
66

77
from ..analyzer.interpreter import Interpreter
8-
from ..schemas.ast_nodes import (
9-
ProgramNode,
10-
FunctionNode,
11-
BlockNode,
12-
AssignmentNode,
13-
VariableNode,
14-
LiteralNode,
15-
BinaryOpNode,
16-
OperatorType,
17-
FunctionCallNode,
18-
ReturnNode,
19-
)
8+
from ..schemas.ast_nodes import *
209

2110

2211
def test_global_modification():
@@ -138,16 +127,18 @@ def test_mixed_scoping():
138127
target=VariableNode(name="b"),
139128
value=LiteralNode(value=2),
140129
),
141-
FunctionCallNode(
142-
function_name="func",
143-
arguments=[VariableNode(name="a")],
130+
ExpressionStatementNode(
131+
expression = FunctionCallNode(
132+
function_name="func",
133+
arguments=[VariableNode(name="a")],
134+
)
144135
),
145136
]),
146137
)
147138

148139
interp = Interpreter()
149140
result = interp.run(program)
150-
print(result)
141+
151142

152143
assert result["variables"]["a"] == 1
153144
assert result["variables"]["b"] == 200

0 commit comments

Comments
 (0)