1
0
mirror of https://github.com/aNNiMON/HotaruFX.git synced 2024-09-19 14:14:21 +03:00

Add property accessor

This commit is contained in:
Victor 2017-08-30 20:00:50 +03:00
parent 40100d8aaa
commit 9d57a38823
6 changed files with 40 additions and 4 deletions

View File

@ -14,7 +14,7 @@ public class HotaruLexer extends Lexer {
}
private static final String TEXT_CHARS = "'\"";
private static final String OPERATOR_CHARS = "(){}:=+-.,";
private static final String OPERATOR_CHARS = "(){}:=+-.,@";
private static final Map<String, HotaruTokenId> OPERATORS;
static {
@ -29,6 +29,7 @@ public class HotaruLexer extends Lexer {
OPERATORS.put("-", HotaruTokenId.MINUS);
OPERATORS.put(".", HotaruTokenId.DOT);
OPERATORS.put(",", HotaruTokenId.COMMA);
OPERATORS.put("@", HotaruTokenId.AT);
}
public HotaruLexer(String input) {

View File

@ -20,6 +20,7 @@ public enum HotaruTokenId {
COLON(Category.OPERATOR),
COMMA(Category.OPERATOR),
DOT(Category.OPERATOR),
AT(Category.OPERATOR),
SINGLE_LINE_COMMENT(Category.COMMENT),
MULTI_LINE_COMMENT(Category.COMMENT),

View File

@ -16,7 +16,7 @@ public class HotaruParser extends Parser {
val parser = new HotaruParser(tokens);
val program = parser.parse();
if (parser.getParseErrors().hasErrors()) {
throw new ParseException();
throw new ParseException(parser.getParseErrors().toString());
}
return program;
}
@ -58,9 +58,14 @@ public class HotaruParser extends Parser {
if (lookMatch(0, HotaruTokenId.LPAREN)) {
return functionChain(expr);
}
return objectAccess(expr);
}
private Node objectAccess(Node expr) {
if (lookMatch(0, HotaruTokenId.DOT)) {
final List<Node> indices = variableSuffix();
if (indices == null || indices.isEmpty()) return expr;
val indices = variableSuffix();
if (indices == null || indices.isEmpty())
return expr;
if (lookMatch(0, HotaruTokenId.LPAREN)) {
// next function call
@ -159,6 +164,12 @@ public class HotaruParser extends Parser {
if (lookMatch(0, HotaruTokenId.LPAREN)) {
return functionChain(qualifiedNameExpr);
}
// node@prop || map.node@prop
if (match(HotaruTokenId.AT)) {
val propName = consume(HotaruTokenId.WORD).getText();
val expr = new PropertyNode(qualifiedNameExpr, propName);
return objectAccess(expr);
}
return qualifiedNameExpr;
}

View File

@ -0,0 +1,16 @@
package com.annimon.hotarufx.parser.ast;
import com.annimon.hotarufx.parser.visitors.ResultVisitor;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class PropertyNode extends ASTNode {
public final Node node;
public final String property;
@Override
public <R, T> R accept(ResultVisitor<R, T> visitor, T input) {
return visitor.visit(this, input);
}
}

View File

@ -61,6 +61,11 @@ public class InterpreterVisitor implements ResultVisitor<Value, Context> {
return new MapValue(map);
}
@Override
public Value visit(PropertyNode node, Context context) {
return node.node.accept(this, context);
}
@Override
public Value visit(UnaryNode node, Context context) {
switch (node.operator) {

View File

@ -6,6 +6,7 @@ import com.annimon.hotarufx.parser.ast.AssignNode;
import com.annimon.hotarufx.parser.ast.BlockNode;
import com.annimon.hotarufx.parser.ast.FunctionNode;
import com.annimon.hotarufx.parser.ast.MapNode;
import com.annimon.hotarufx.parser.ast.PropertyNode;
import com.annimon.hotarufx.parser.ast.UnaryNode;
import com.annimon.hotarufx.parser.ast.ValueNode;
import com.annimon.hotarufx.parser.ast.VariableNode;
@ -17,6 +18,7 @@ public interface ResultVisitor<R, T> {
R visit(BlockNode node, T t);
R visit(FunctionNode node, T t);
R visit(MapNode node, T t);
R visit(PropertyNode node, T t);
R visit(UnaryNode node, T t);
R visit(ValueNode node, T t);
R visit(VariableNode node, T t);