mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 00:34:20 +03:00
Урок 11. Одномерные массивы
This commit is contained in:
parent
207f91a228
commit
c678d5d5e1
11
program.own
11
program.own
@ -48,4 +48,13 @@ def sum(a,b) {
|
||||
name(1,"text")
|
||||
print sum(10, 15)
|
||||
|
||||
print a
|
||||
print a + "\n"
|
||||
|
||||
arr = [1, "text", sum(10, 15), [], ["text", [90, [7 + 6, [50]]]]]
|
||||
print arr + "\n"
|
||||
arr[0] = arr[0] + 1000 + arr[2]
|
||||
print arr + "\n"
|
||||
arr4 = arr[4]
|
||||
print arr4 + "\n"
|
||||
arr41 = arr4[1]
|
||||
print arr41 + "\n"
|
48
src/com/annimon/ownlang/lib/ArrayValue.java
Normal file
48
src/com/annimon/ownlang/lib/ArrayValue.java
Normal file
@ -0,0 +1,48 @@
|
||||
package com.annimon.ownlang.lib;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public final class ArrayValue implements Value {
|
||||
|
||||
private final Value[] elements;
|
||||
|
||||
public ArrayValue(int size) {
|
||||
this.elements = new Value[size];
|
||||
}
|
||||
|
||||
public ArrayValue(Value[] elements) {
|
||||
this.elements = new Value[elements.length];
|
||||
System.arraycopy(elements, 0, this.elements, 0, elements.length);
|
||||
}
|
||||
|
||||
public ArrayValue(ArrayValue array) {
|
||||
this(array.elements);
|
||||
}
|
||||
|
||||
public Value get(int index) {
|
||||
return elements[index];
|
||||
}
|
||||
|
||||
public void set(int index, Value value) {
|
||||
elements[index] = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double asNumber() {
|
||||
throw new RuntimeException("Cannot cast array to number");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asString() {
|
||||
return Arrays.toString(elements);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return asString();
|
||||
}
|
||||
}
|
@ -31,6 +31,9 @@ public final class Functions {
|
||||
}
|
||||
return NumberValue.ZERO;
|
||||
});
|
||||
functions.put("newarray", args -> {
|
||||
return new ArrayValue(args);
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean isExists(String key) {
|
||||
|
@ -11,7 +11,7 @@ import java.util.Map;
|
||||
*/
|
||||
public final class Lexer {
|
||||
|
||||
private static final String OPERATOR_CHARS = "+-*/(){}=<>!&|,";
|
||||
private static final String OPERATOR_CHARS = "+-*/()[]{}=<>!&|,";
|
||||
|
||||
private static final Map<String, TokenType> OPERATORS;
|
||||
static {
|
||||
@ -22,6 +22,8 @@ public final class Lexer {
|
||||
OPERATORS.put("/", TokenType.SLASH);
|
||||
OPERATORS.put("(", TokenType.LPAREN);
|
||||
OPERATORS.put(")", TokenType.RPAREN);
|
||||
OPERATORS.put("[", TokenType.LBRACKET);
|
||||
OPERATORS.put("]", TokenType.RBRACKET);
|
||||
OPERATORS.put("{", TokenType.LBRACE);
|
||||
OPERATORS.put("}", TokenType.RBRACE);
|
||||
OPERATORS.put("=", TokenType.EQ);
|
||||
|
@ -80,12 +80,19 @@ public final class Parser {
|
||||
|
||||
private Statement assignmentStatement() {
|
||||
// WORD EQ
|
||||
final Token current = get(0);
|
||||
if (match(TokenType.WORD) && lookMatch(0, TokenType.EQ)) {
|
||||
final String variable = current.getText();
|
||||
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.EQ)) {
|
||||
final String variable = consume(TokenType.WORD).getText();
|
||||
consume(TokenType.EQ);
|
||||
return new AssignmentStatement(variable, expression());
|
||||
}
|
||||
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.LBRACKET)) {
|
||||
final String variable = consume(TokenType.WORD).getText();
|
||||
consume(TokenType.LBRACKET);
|
||||
final Expression index = expression();
|
||||
consume(TokenType.RBRACKET);
|
||||
consume(TokenType.EQ);
|
||||
return new ArrayAssignmentStatement(variable, index, expression());
|
||||
}
|
||||
throw new RuntimeException("Unknown statement");
|
||||
}
|
||||
|
||||
@ -147,6 +154,24 @@ public final class Parser {
|
||||
return function;
|
||||
}
|
||||
|
||||
private Expression array() {
|
||||
consume(TokenType.LBRACKET);
|
||||
final List<Expression> elements = new ArrayList<>();
|
||||
while (!match(TokenType.RBRACKET)) {
|
||||
elements.add(expression());
|
||||
match(TokenType.COMMA);
|
||||
}
|
||||
return new ArrayExpression(elements);
|
||||
}
|
||||
|
||||
private Expression element() {
|
||||
final String variable = consume(TokenType.WORD).getText();
|
||||
consume(TokenType.LBRACKET);
|
||||
final Expression index = expression();
|
||||
consume(TokenType.RBRACKET);
|
||||
return new ArrayAccessExpression(variable, index);
|
||||
}
|
||||
|
||||
private Expression expression() {
|
||||
return logicalOr();
|
||||
}
|
||||
@ -275,6 +300,12 @@ public final class Parser {
|
||||
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.LPAREN)) {
|
||||
return function();
|
||||
}
|
||||
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.LBRACKET)) {
|
||||
return element();
|
||||
}
|
||||
if (lookMatch(0, TokenType.LBRACKET)) {
|
||||
return array();
|
||||
}
|
||||
if (match(TokenType.WORD)) {
|
||||
return new VariableExpression(current.getText());
|
||||
}
|
||||
|
@ -43,6 +43,8 @@ public enum TokenType {
|
||||
|
||||
LPAREN, // (
|
||||
RPAREN, // )
|
||||
LBRACKET, // [
|
||||
RBRACKET, // ]
|
||||
LBRACE, // {
|
||||
RBRACE, // }
|
||||
COMMA, // ,
|
||||
|
@ -0,0 +1,36 @@
|
||||
package com.annimon.ownlang.parser.ast;
|
||||
|
||||
import com.annimon.ownlang.lib.ArrayValue;
|
||||
import com.annimon.ownlang.lib.Value;
|
||||
import com.annimon.ownlang.lib.Variables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public final class ArrayAccessExpression implements Expression {
|
||||
|
||||
private final String variable;
|
||||
private final Expression index;
|
||||
|
||||
public ArrayAccessExpression(String variable, Expression index) {
|
||||
this.variable = variable;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value eval() {
|
||||
final Value var = Variables.get(variable);
|
||||
if (var instanceof ArrayValue) {
|
||||
final ArrayValue array = (ArrayValue) var;
|
||||
return array.get((int) index.eval().asNumber());
|
||||
} else {
|
||||
throw new RuntimeException("Array expected");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s[%s]", variable, index);
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.annimon.ownlang.parser.ast;
|
||||
|
||||
import com.annimon.ownlang.lib.ArrayValue;
|
||||
import com.annimon.ownlang.lib.Value;
|
||||
import com.annimon.ownlang.lib.Variables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public final class ArrayAssignmentStatement implements Statement {
|
||||
|
||||
private final String variable;
|
||||
private final Expression index;
|
||||
private final Expression expression;
|
||||
|
||||
public ArrayAssignmentStatement(String variable, Expression index, Expression expression) {
|
||||
this.variable = variable;
|
||||
this.index = index;
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
final Value var = Variables.get(variable);
|
||||
if (var instanceof ArrayValue) {
|
||||
final ArrayValue array = (ArrayValue) var;
|
||||
array.set((int) index.eval().asNumber(), expression.eval());
|
||||
} else {
|
||||
throw new RuntimeException("Array expected");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s[%s] = %s", variable, index, expression);
|
||||
}
|
||||
}
|
33
src/com/annimon/ownlang/parser/ast/ArrayExpression.java
Normal file
33
src/com/annimon/ownlang/parser/ast/ArrayExpression.java
Normal file
@ -0,0 +1,33 @@
|
||||
package com.annimon.ownlang.parser.ast;
|
||||
|
||||
import com.annimon.ownlang.lib.ArrayValue;
|
||||
import com.annimon.ownlang.lib.Value;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public final class ArrayExpression implements Expression {
|
||||
|
||||
private final List<Expression> elements;
|
||||
|
||||
public ArrayExpression(List<Expression> arguments) {
|
||||
this.elements = arguments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value eval() {
|
||||
final int size = elements.size();
|
||||
final ArrayValue array = new ArrayValue(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
array.set(i, elements.get(i).eval());
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return elements.toString();
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package com.annimon.ownlang.parser.ast;
|
||||
|
||||
import com.annimon.ownlang.lib.ArrayValue;
|
||||
import com.annimon.ownlang.lib.NumberValue;
|
||||
import com.annimon.ownlang.lib.StringValue;
|
||||
import com.annimon.ownlang.lib.Value;
|
||||
@ -23,7 +24,7 @@ public final class BinaryExpression implements Expression {
|
||||
public Value eval() {
|
||||
final Value value1 = expr1.eval();
|
||||
final Value value2 = expr2.eval();
|
||||
if (value1 instanceof StringValue) {
|
||||
if ( (value1 instanceof StringValue) || (value1 instanceof ArrayValue) ) {
|
||||
final String string1 = value1.asString();
|
||||
switch (operation) {
|
||||
case '*': {
|
||||
|
Loading…
Reference in New Issue
Block a user