Skip to content

Commit 1fac43b

Browse files
committed
Вызов функции из объекта или массива
1 parent b194a7b commit 1fac43b

File tree

3 files changed

+48
-32
lines changed

3 files changed

+48
-32
lines changed

src/com/annimon/ownlang/parser/Parser.java

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ private Statement statement() {
8585
return functionDefine();
8686
}
8787
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.LPAREN)) {
88-
return new FunctionStatement(function());
88+
return new FunctionStatement(function(qualifiedName()));
8989
}
9090
return assignmentStatement();
9191
}
@@ -191,11 +191,10 @@ private FunctionDefineStatement functionDefine() {
191191
return new FunctionDefineStatement(name, argNames, body);
192192
}
193193

194-
private FunctionalExpression function() {
194+
private FunctionalExpression function(Expression qualifiedNameExpr) {
195195
// function(arg1, arg2, ...)
196-
final String name = consume(TokenType.WORD).getText();
197196
consume(TokenType.LPAREN);
198-
final FunctionalExpression function = new FunctionalExpression(name);
197+
final FunctionalExpression function = new FunctionalExpression(qualifiedNameExpr);
199198
while (!match(TokenType.RPAREN)) {
200199
function.addArgument(expression());
201200
match(TokenType.COMMA);
@@ -542,26 +541,39 @@ private Expression primary() {
542541
}
543542

544543
private Expression variable() {
545-
final Token current = get(0);
546-
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.LBRACKET)) {
547-
return element();
548-
}
549544
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.LPAREN)) {
550-
return function();
545+
return function(new ValueExpression(consume(TokenType.WORD).getText()));
551546
}
552-
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.DOT)) {
553-
return object();
547+
final Expression qualifiedNameExpr = qualifiedName();
548+
if (qualifiedNameExpr != null) {
549+
// variable(args) || arr["key"](args) || obj.key(args)
550+
if (lookMatch(0, TokenType.LPAREN)) {
551+
return function(qualifiedNameExpr);
552+
}
553+
return qualifiedNameExpr;
554554
}
555+
555556
if (lookMatch(0, TokenType.LBRACKET)) {
556557
return array();
557558
}
558559
if (lookMatch(0, TokenType.LBRACE)) {
559560
return map();
560561
}
562+
return value();
563+
}
564+
565+
private Expression qualifiedName() {
566+
final Token current = get(0);
567+
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.LBRACKET)) {
568+
return element();
569+
}
570+
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.DOT)) {
571+
return object();
572+
}
561573
if (match(TokenType.WORD)) {
562574
return new VariableExpression(current.getText());
563575
}
564-
return value();
576+
return null;
565577
}
566578

567579
private Expression value() {
Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
package com.annimon.ownlang.parser.ast;
22

3-
import com.annimon.ownlang.lib.Function;
4-
import com.annimon.ownlang.lib.FunctionValue;
5-
import com.annimon.ownlang.lib.Functions;
6-
import com.annimon.ownlang.lib.Types;
7-
import com.annimon.ownlang.lib.Value;
8-
import com.annimon.ownlang.lib.Variables;
3+
import com.annimon.ownlang.exceptions.VariableDoesNotExistsException;
4+
import com.annimon.ownlang.lib.*;
95
import java.util.ArrayList;
106
import java.util.List;
117

@@ -15,19 +11,14 @@
1511
*/
1612
public final class FunctionalExpression implements Expression {
1713

18-
public final String name;
14+
public final Expression functionExpr;
1915
public final List<Expression> arguments;
2016

21-
public FunctionalExpression(String name) {
22-
this.name = name;
17+
public FunctionalExpression(Expression functionExpr) {
18+
this.functionExpr = functionExpr;
2319
arguments = new ArrayList<>();
2420
}
2521

26-
public FunctionalExpression(String name, List<Expression> arguments) {
27-
this.name = name;
28-
this.arguments = arguments;
29-
}
30-
3122
public void addArgument(Expression arg) {
3223
arguments.add(arg);
3324
}
@@ -39,18 +30,30 @@ public Value eval() {
3930
for (int i = 0; i < size; i++) {
4031
values[i] = arguments.get(i).eval();
4132
}
42-
return getFunction(name).execute(values);
33+
return consumeFunction(functionExpr).execute(values);
34+
}
35+
36+
private Function consumeFunction(Expression expr) {
37+
try {
38+
final Value value = expr.eval();
39+
if (value.type() == Types.FUNCTION) {
40+
return ((FunctionValue) value).getValue();
41+
}
42+
return getFunction(value.asString());
43+
} catch (VariableDoesNotExistsException ex) {
44+
return getFunction(ex.getVariable());
45+
}
4346
}
4447

4548
private Function getFunction(String key) {
4649
if (Functions.isExists(key)) return Functions.get(key);
4750
if (Variables.isExists(key)) {
48-
final Value value = Variables.get(key);
49-
if (value.type() == Types.FUNCTION) {
50-
return ((FunctionValue)value).getValue();
51+
final Value variable = Variables.get(key);
52+
if (variable.type() == Types.FUNCTION) {
53+
return ((FunctionValue)variable).getValue();
5154
}
5255
}
53-
throw new RuntimeException("Unknown function " + key);
56+
throw new UnknownFunctionException(key);
5457
}
5558

5659
@Override
@@ -60,6 +63,6 @@ public void accept(Visitor visitor) {
6063

6164
@Override
6265
public String toString() {
63-
return name + "(" + arguments.toString() + ")";
66+
return functionExpr + "(" + arguments.toString() + ")";
6467
}
6568
}

src/com/annimon/ownlang/parser/visitors/AbstractVisitor.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ public void visit(FunctionStatement s) {
104104

105105
@Override
106106
public void visit(FunctionalExpression s) {
107+
s.functionExpr.accept(this);
107108
for (Expression argument : s.arguments) {
108109
argument.accept(this);
109110
}

0 commit comments

Comments
 (0)