relaxes maps and lists notation

This commit is contained in:
gnembon committed 2020-06-21 02:07:24 -03:00
1 parent f09744b04e
commit bb3ecb8a94
3 files changed
+61 -9

No files matched your search

+1
View File
@@ -18,6 +18,7 @@ public class Context
public static final int SIGNATURE = 7; public static final int SIGNATURE = 7;
public static final int LOCALIZATION = 8; public static final int LOCALIZATION = 8;
public static final int LVALUE = 9; public static final int LVALUE = 9;
public static final int MAPDEF = 10;
public final Map<String, LazyValue> variables = new HashMap<>(); public final Map<String, LazyValue> variables = new HashMap<>();
+16 -4
View File
@@ -492,6 +492,11 @@ public class Expression
//assigns const procedure to the lhs, returning its previous value //assigns const procedure to the lhs, returning its previous value
addLazyBinaryOperatorWithDelegation("->", precedence.get("def->"), false, (c, type, e, t, lv1, lv2) -> addLazyBinaryOperatorWithDelegation("->", precedence.get("def->"), false, (c, type, e, t, lv1, lv2) ->
{ {
if (type == Context.MAPDEF)
{
Value result = ListValue.of(lv1.evalValue(c), lv2.evalValue(c));
return (cc, tt) -> result;
}
Value v1 = lv1.evalValue(c, Context.SIGNATURE); Value v1 = lv1.evalValue(c, Context.SIGNATURE);
if (!(v1 instanceof FunctionSignatureValue)) if (!(v1 instanceof FunctionSignatureValue))
throw new InternalExpressionException("'->' operator requires a function signature on the LHS"); throw new InternalExpressionException("'->' operator requires a function signature on the LHS");
@@ -1335,11 +1340,18 @@ public class Expression
return LazyListValue.range(from, to, step); return LazyListValue.range(from, to, step);
}); });
addFunction("m", lv -> addLazyFunction("m", -1, (c, t, llv) ->
{ {
List<Value> lv = new ArrayList<>();
for (LazyValue lazyParam : llv) {
lv.add(lazyParam.evalValue(c, Context.MAPDEF)); // none type default by design
}
Value ret;
if (lv.size() == 1 && lv.get(0) instanceof LazyListValue) if (lv.size() == 1 && lv.get(0) instanceof LazyListValue)
return new MapValue(((LazyListValue) lv.get(0)).unroll()); ret = new MapValue(((LazyListValue) lv.get(0)).unroll());
return new MapValue(lv); else
ret = new MapValue(lv);
return (cc, tt) -> ret;
}); });
addUnaryFunction("keys", v -> { addUnaryFunction("keys", v -> {
@@ -2062,7 +2074,7 @@ public class Expression
Tokenizer tokenizer = new Tokenizer(c, this, expression, allowComments, allowNewlineSubstitutions); Tokenizer tokenizer = new Tokenizer(c, this, expression, allowComments, allowNewlineSubstitutions);
// stripping lousy but acceptable semicolons // stripping lousy but acceptable semicolons
List<Tokenizer.Token> cleanedTokens = tokenizer.fixSemicolons(); List<Tokenizer.Token> cleanedTokens = tokenizer.postProcess();
Tokenizer.Token lastFunction = null; Tokenizer.Token lastFunction = null;
Tokenizer.Token previousToken = null; Tokenizer.Token previousToken = null;
+44 -5
View File
@@ -43,7 +43,7 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
this.newLinesMarkers = allowNewLineMakers; this.newLinesMarkers = allowNewLineMakers;
} }
public List<Token> fixSemicolons() public List<Token> postProcess()
{ {
Iterable<Token> iterable = () -> this; Iterable<Token> iterable = () -> this;
List<Token> originalTokens = StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toList()); List<Token> originalTokens = StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toList());
@@ -60,9 +60,27 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
current.surface = ";"; current.surface = ";";
current.type = Token.TokenType.OPERATOR; current.type = Token.TokenType.OPERATOR;
} }
if (current.type == Token.TokenType.MARKER)
{
// dealing with tokens in reversed order
if ("{".equals(current.surface))
{
cleanedTokens.add(current.morphedInto(Token.TokenType.OPEN_PAREN, "("));
current.morph(Token.TokenType.FUNCTION, "m");
}
else if ("[".equals(current.surface))
{
cleanedTokens.add(current.morphedInto(Token.TokenType.OPEN_PAREN, "("));
current.morph(Token.TokenType.FUNCTION, "l");
}
else if ("}".equals(current.surface) || "]".equals(current.surface))
{
current.morph(Token.TokenType.CLOSE_PAREN, ")");
}
}
cleanedTokens.add(current); cleanedTokens.add(current);
} }
if (current.type != Token.TokenType.MARKER) if (!(current.type == Token.TokenType.MARKER && current.surface.equals("$")))
last = current; last = current;
} }
Collections.reverse(cleanedTokens); Collections.reverse(cleanedTokens);
@@ -242,7 +260,8 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
} }
token.type = ch == '(' ? Token.TokenType.FUNCTION : Token.TokenType.VARIABLE; token.type = ch == '(' ? Token.TokenType.FUNCTION : Token.TokenType.VARIABLE;
} }
else if (ch == '(' || ch == ')' || ch == ',') else if (ch == '(' || ch == ')' || ch == ',' ||
ch == '{' || ch == '}' || ch == '[' || ch == ']')
{ {
if (ch == '(') if (ch == '(')
{ {
@@ -252,17 +271,21 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
{ {
token.type = Token.TokenType.CLOSE_PAREN; token.type = Token.TokenType.CLOSE_PAREN;
} }
else else if (ch == ',')
{ {
token.type = Token.TokenType.COMMA; token.type = Token.TokenType.COMMA;
} }
else
{
token.type = Token.TokenType.MARKER;
}
token.append(ch); token.append(ch);
pos++; pos++;
linepos++; linepos++;
if (expression != null && context != null && previousToken != null && if (expression != null && context != null && previousToken != null &&
previousToken.type == Token.TokenType.OPERATOR && previousToken.type == Token.TokenType.OPERATOR &&
(ch == ')' || ch == ',') && (ch == ')' || ch == ',' || ch == ']' || ch == '}') &&
!previousToken.surface.equalsIgnoreCase(";") !previousToken.surface.equalsIgnoreCase(";")
) )
throw new ExpressionException(context, this.expression, previousToken, throw new ExpressionException(context, this.expression, previousToken,
@@ -376,6 +399,22 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
public int pos; public int pos;
public int linepos; public int linepos;
public int lineno; public int lineno;
public Token morphedInto(TokenType newType, String newSurface)
{
Token created = new Token();
created.surface = newSurface;
created.type = newType;
created.pos = pos;
created.linepos = linepos;
created.lineno= lineno;
return created;
}
public void morph(TokenType type, String s)
{
this.type = type;
this.surface = s;
}
public void append(char c) public void append(char c)
{ {