mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 00:34:20 +03:00
Урок 9. Функции
This commit is contained in:
parent
3a4ea7b3b1
commit
7756e36179
@ -21,7 +21,7 @@ if (40 < 50 || 50 > 60) {
|
||||
i = 0
|
||||
print "while"
|
||||
while (i < 10) {
|
||||
print "i = " + i + "\n"
|
||||
print "i = " + i + sin(i) + "\n"
|
||||
i = i + 1
|
||||
}
|
||||
print "for"
|
||||
@ -30,3 +30,6 @@ if (40 < 50 || 50 > 60) {
|
||||
}
|
||||
}
|
||||
else print "false"
|
||||
|
||||
print "sin(PI) = " + sin(PI/2)
|
||||
echo(1,2,3,"4","5","text",sin(0),cos(0),sin(PI),cos(PI),PI)
|
10
src/com/annimon/ownlang/lib/Function.java
Normal file
10
src/com/annimon/ownlang/lib/Function.java
Normal file
@ -0,0 +1,10 @@
|
||||
package com.annimon.ownlang.lib;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public interface Function {
|
||||
|
||||
Value execute(Value... args);
|
||||
}
|
49
src/com/annimon/ownlang/lib/Functions.java
Normal file
49
src/com/annimon/ownlang/lib/Functions.java
Normal file
@ -0,0 +1,49 @@
|
||||
package com.annimon.ownlang.lib;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public final class Functions {
|
||||
|
||||
private static final NumberValue ZERO = new NumberValue(0);
|
||||
private static final Map<String, Function> functions;
|
||||
|
||||
static {
|
||||
functions = new HashMap<>();
|
||||
functions.put("sin", new Function() {
|
||||
|
||||
@Override
|
||||
public Value execute(Value... args) {
|
||||
if (args.length != 1) throw new RuntimeException("One arg expected");
|
||||
return new NumberValue(Math.sin(args[0].asNumber()));
|
||||
}
|
||||
});
|
||||
functions.put("cos", (Function) (Value... args) -> {
|
||||
if (args.length != 1) throw new RuntimeException("One arg expected");
|
||||
return new NumberValue(Math.cos(args[0].asNumber()));
|
||||
});
|
||||
functions.put("echo", args -> {
|
||||
for (Value arg : args) {
|
||||
System.out.println(arg.asString());
|
||||
}
|
||||
return ZERO;
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean isExists(String key) {
|
||||
return functions.containsKey(key);
|
||||
}
|
||||
|
||||
public static Function get(String key) {
|
||||
if (!isExists(key)) throw new RuntimeException("Unknown function " + key);
|
||||
return functions.get(key);
|
||||
}
|
||||
|
||||
public static void set(String key, Function function) {
|
||||
functions.put(key, function);
|
||||
}
|
||||
}
|
@ -65,6 +65,9 @@ public final class Parser {
|
||||
if (match(TokenType.FOR)) {
|
||||
return forStatement();
|
||||
}
|
||||
if (get(0).getType() == TokenType.WORD && get(1).getType() == TokenType.LPAREN) {
|
||||
return new FunctionStatement(function());
|
||||
}
|
||||
return assignmentStatement();
|
||||
}
|
||||
|
||||
@ -114,6 +117,16 @@ public final class Parser {
|
||||
return new ForStatement(initialization, termination, increment, statement);
|
||||
}
|
||||
|
||||
private FunctionalExpression function() {
|
||||
final String name = consume(TokenType.WORD).getText();
|
||||
consume(TokenType.LPAREN);
|
||||
final FunctionalExpression function = new FunctionalExpression(name);
|
||||
while (!match(TokenType.RPAREN)) {
|
||||
function.addArgument(expression());
|
||||
match(TokenType.COMMA);
|
||||
}
|
||||
return function;
|
||||
}
|
||||
|
||||
private Expression expression() {
|
||||
return logicalOr();
|
||||
@ -241,6 +254,9 @@ public final class Parser {
|
||||
if (match(TokenType.HEX_NUMBER)) {
|
||||
return new ValueExpression(Long.parseLong(current.getText(), 16));
|
||||
}
|
||||
if (get(0).getType() == TokenType.WORD && get(1).getType() == TokenType.LPAREN) {
|
||||
return function();
|
||||
}
|
||||
if (match(TokenType.WORD)) {
|
||||
return new VariableExpression(current.getText());
|
||||
}
|
||||
|
24
src/com/annimon/ownlang/parser/ast/FunctionStatement.java
Normal file
24
src/com/annimon/ownlang/parser/ast/FunctionStatement.java
Normal file
@ -0,0 +1,24 @@
|
||||
package com.annimon.ownlang.parser.ast;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public final class FunctionStatement implements Statement {
|
||||
|
||||
private final FunctionalExpression function;
|
||||
|
||||
public FunctionStatement(FunctionalExpression function) {
|
||||
this.function = function;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
function.eval();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return function.toString();
|
||||
}
|
||||
}
|
45
src/com/annimon/ownlang/parser/ast/FunctionalExpression.java
Normal file
45
src/com/annimon/ownlang/parser/ast/FunctionalExpression.java
Normal file
@ -0,0 +1,45 @@
|
||||
package com.annimon.ownlang.parser.ast;
|
||||
|
||||
import com.annimon.ownlang.lib.Functions;
|
||||
import com.annimon.ownlang.lib.Value;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public final class FunctionalExpression implements Expression {
|
||||
|
||||
private final String name;
|
||||
private final List<Expression> arguments;
|
||||
|
||||
public FunctionalExpression(String name) {
|
||||
this.name = name;
|
||||
arguments = new ArrayList<>();
|
||||
}
|
||||
|
||||
public FunctionalExpression(String name, List<Expression> arguments) {
|
||||
this.name = name;
|
||||
this.arguments = arguments;
|
||||
}
|
||||
|
||||
public void addArgument(Expression arg) {
|
||||
arguments.add(arg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value eval() {
|
||||
final int size = arguments.size();
|
||||
final Value[] values = new Value[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
values[i] = arguments.get(i).eval();
|
||||
}
|
||||
return Functions.get(name).execute(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + "(" + arguments.toString() + ")";
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user