Skip to content

Commit

Permalink
Implemented template strings
Browse files Browse the repository at this point in the history
  • Loading branch information
popov654 committed Jan 3, 2024
1 parent ccac4af commit 8f52caf
Show file tree
Hide file tree
Showing 12 changed files with 194 additions and 112 deletions.
71 changes: 37 additions & 34 deletions src/com/alstarsoft/tinybrowser/jsparser/Expression.java

Large diffs are not rendered by default.

36 changes: 18 additions & 18 deletions src/com/alstarsoft/tinybrowser/jsparser/Generator.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,24 @@ class nextFunction extends Function {
@Override
public JSValue call(JSObject context, Vector<JSValue> args, boolean as_constr) {
if (args.size() > 0) {
block.yt_value = args.get(0);
f_block.yt_value = args.get(0);
} else {
Expression last_exp = block.last > -1 ? block.children.get(block.last) : null;
Expression last_exp = f_block.last > -1 ? f_block.children.get(f_block.last) : null;
if (last_exp != null && last_exp.yt != null && last_exp.yt != last_exp.start && !(last_exp.yt.val instanceof Generator)) {
block.yt_value = last_value;
f_block.yt_value = last_value;
last_exp.yt = null;
} else if (last_exp != null && last_exp.yt != null && last_exp.yt.prev == last_exp.start) {
block.yt_value = null;
f_block.yt_value = null;
}
}
block.eval();
last_value = block.return_value;
f_block.eval();
last_value = f_block.return_value;
JSObject result = new JSObject();
if (!done) {
result.set("value", block.return_value);
result.set("value", f_block.return_value);
}
result.set("done", new JSBool(block.done));
done = block.done;
result.set("done", new JSBool(f_block.done));
done = f_block.done;
return result;
}
}
Expand All @@ -38,23 +38,23 @@ class throwFunction extends Function {
@Override
public JSValue call(JSObject context, Vector<JSValue> args, boolean as_constr) {
if (args.size() > 0) {
block.error = new JSError(args.get(0), "Error", null);
f_block.error = new JSError(args.get(0), "Error", null);
}
block.eval();
f_block.eval();
JSObject result = new JSObject();
if (!done) {
result.set("value", block.return_value);
result.set("value", f_block.return_value);
}
result.set("done", new JSBool(block.done));
done = block.done;
result.set("done", new JSBool(f_block.done));
done = f_block.done;
return result;
}
}

public Generator(Block b) {
b.is_func = true;
b.is_gen = true;
block = b;
f_block = b;
items.put("next", new nextFunction());
items.put("throw", new throwFunction());
}
Expand All @@ -77,8 +77,8 @@ public void set(String str, JSValue value) {

@Override
public String toString() {
if (block.func == null) return "{Generator}";
return block.func.toPaddedString(0);
if (f_block.func == null) return "{Generator}";
return f_block.func.toPaddedString(0);
}

@Override
Expand All @@ -87,7 +87,7 @@ public String getType() {
}

private JSValue last_value;
private Block block = null;
private Block f_block = null;
private boolean done = false;
private String type = "Object";
}
4 changes: 2 additions & 2 deletions src/com/alstarsoft/tinybrowser/jsparser/JSArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public JSArray(Token head, Expression exp, TokenPointer pointer) {
|| t.getType() == Token.VALUE) && level == 1 && level2 == 0) {
if (t.getType() == Token.VALUE && (t.next.getType() == Token.OP && t.next.getContent().equals(",") ||
t.next.getType() == Token.ARRAY_END)) {
items.add(JSValue.create(JSValue.getType(t.getContent()), t.getContent()));
items.add(JSValue.create(JSValue.getType(t.getContent()), t.getContent(), block));
} else {
Token ct = t;
while (ct != null && (ct.next.getType() != Token.OP || !ct.next.getContent().equals(",")) &&
Expand Down Expand Up @@ -294,7 +294,7 @@ public JSArray deepClone() {
if (items.get(i).getType().matches("Object|Array")) {
v.add(((JSObject)items.get(i)).deepClone());
} else {
v.add(JSValue.create(items.get(i).getType(), items.get(i).toString()));
v.add(JSValue.create(items.get(i).getType(), items.get(i).toString(), block));
}
}
JSArray clone = new JSArray(v);
Expand Down
4 changes: 2 additions & 2 deletions src/com/alstarsoft/tinybrowser/jsparser/JSEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public JSEvent(JSObject target, String eventType, HashMap<String, String> data)
Set<String> keys = data.keySet();
for (String key: keys) {
String type = JSValue.getType(data.get(key));
JSValue val = JSValue.create(type, data.get(key));
JSValue val = JSValue.create(type, data.get(key), block);
items.put(key, val);
}
}
Expand All @@ -37,7 +37,7 @@ public JSEvent(HTMLElement target, HTMLElement relatedTarget, HashMap<String, St
Set<String> keys = data.keySet();
for (String key: keys) {
String type = JSValue.getType(data.get(key));
JSValue val = JSValue.create(type, data.get(key));
JSValue val = JSValue.create(type, data.get(key), block);
items.put(key, val);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/com/alstarsoft/tinybrowser/jsparser/JSObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public JSObject(Token head, Expression exp, TokenPointer pointer) {
|| t.getType() == Token.VALUE) && state == 1 && level == 1 && level2 == 0) {
if (t.getType() == Token.VALUE && (t.next.getType() == Token.OP && t.next.getContent().equals(",") ||
t.next.getType() == Token.OBJECT_END)) {
items.put(key, JSValue.create(JSValue.getType(t.getContent()), t.getContent()));
items.put(key, JSValue.create(JSValue.getType(t.getContent()), t.getContent(), block));
} else if (t.getType() == Token.OBJECT_ENTITY) {
t.val.incrementRefCount();
if (t.val instanceof Function) {
Expand Down Expand Up @@ -297,7 +297,7 @@ public JSObject deepClone() {
} else if (val.getType().matches("Object|Array")) {
copy.items.put(key, ((JSObject)val).deepClone());
} else {
copy.items.put(key, JSValue.create(val.getType(), val.toString()));
copy.items.put(key, JSValue.create(val.getType(), val.toString(), block));
}
}
return copy;
Expand Down
7 changes: 4 additions & 3 deletions src/com/alstarsoft/tinybrowser/jsparser/JSParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ else if (state == READ_COMMENT) {
if (ch == '\n') {
line++;
lastLineStartPos = pos+1;
if (state == READ_STRING && !esc) {
if (state == READ_STRING && strToken != '`' && !esc) {
errorDescription = getErrorMessage("unexpected new line character");
System.err.println(errorDescription);
correct = false;
Expand Down Expand Up @@ -478,7 +478,7 @@ else if (state == READ_COMMENT) {
return;
}

if (state == READY && (ch == '"' || ch == '\'') && !esc) {
if (state == READY && (ch == '"' || ch == '\'' || ch == '`') && !esc) {
state = READ_STRING;
strToken = ch;
pos++;
Expand All @@ -488,7 +488,8 @@ else if (state == READ_COMMENT) {
if (state == READ_STRING && ch == strToken && !esc) {
state = READY;
String s = last_token;
if (substate != READ_OBJECT_FIELD) s = "\"" + s + "\"";
if (strToken == '`') s = "`" + s + "`";
else if (substate != READ_OBJECT_FIELD) s = "\"" + s + "\"";
else s = "<" + s + ">";
Token t = new Token(s);
strToken = '\0';
Expand Down
94 changes: 79 additions & 15 deletions src/com/alstarsoft/tinybrowser/jsparser/JSString.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,69 +11,121 @@ public JSString() {
items.put("__proto__", StringProto.getInstance());
}
public JSString(String val) {
this(val, null);
}
public JSString(String val, Block block) {
if (val == null) val = "";
items.put("__proto__", StringProto.getInstance());
value = val;
if (val.replaceAll("\n", "").matches("^`.*`$")) {
val = val.substring(1, val.length()-1);
originalValue = val;
dynamic = true;
} else {
value = val;
}

}

public void evaluate() {
String val = originalValue;
int pos = 0;
int lastPos = 0;
int lastPosType = 0;
Vector<String> parts = new Vector<String>();
Vector<Integer> positions = new Vector<Integer>();
while (pos < val.length()) {
if (val.charAt(pos) == '\\') {
pos++;
continue;
}
if (val.charAt(pos) == '$' && val.charAt(pos+1) == '{') {
positions.add(pos++);
continue;
}
if (pos > 0 && lastPosType == 0 && val.charAt(pos) == '}' && positions.size() > 0) {
int start = positions.get(0);
positions.clear();

if (lastPos < start) {
parts.add(val.substring(lastPos, start));
}

JSParser jp = new JSParser(val.substring(start+2, pos));
Expression expr = Expression.create(jp.getHead());
((Block)expr).scope = block.scope;

parts.add(expr.eval().getValue().toString());
lastPos = pos+1;
}
pos++;
}
if (pos > lastPos+1) {
parts.add(val.substring(lastPos, pos));
}
value = "";
for (String p: parts) {
value += p;
}
}

public JSString toLowerCase() {
return new JSString(value.toLowerCase());
return new JSString(value.toLowerCase(), block);
}

public JSString toUpperCase() {
return new JSString(value.toUpperCase());
return new JSString(value.toUpperCase(), block);
}

public JSInt length() {
return new JSInt(value.length());
}

public JSString slice() {
return new JSString(value);
return new JSString(value, block);
}

public JSString slice(JSInt start) {
return new JSString(value.substring((int)start.getValue()));
return new JSString(value.substring((int)start.getValue()), block);
}

public JSString slice(JSInt start, JSInt end) {
return new JSString(value.substring((int)start.getValue(), (int)end.getValue()));
return new JSString(value.substring((int)start.getValue(), (int)end.getValue()), block);
}

public JSArray split(JSString delimiter) {
Vector<JSValue> v = new Vector<JSValue>();
if (delimiter.getValue().isEmpty()) {
char[] chars = value.toCharArray();
for (int i = 0; i < chars.length; i++) {
v.add(new JSString(String.valueOf(chars[i])));
v.add(new JSString(String.valueOf(chars[i]), block));
}
} else {
String[] parts = value.split(delimiter.getValue());
for (int i = 0; i < parts.length; i++) {
v.add(new JSString(parts[i]));
v.add(new JSString(parts[i], block));
}
}
return new JSArray(v);
}

public JSArray split() {
return new JSArray(new JSString(value));
return new JSArray(new JSString(value, block));
}

public JSString charAt(JSInt index) {
return new JSString(String.valueOf(value.charAt((int)index.getValue())));
return new JSString(String.valueOf(value.charAt((int)index.getValue())), block);
}

public JSString replace(JSString from, JSString to) {
return new JSString(value.replace(from.getValue(), to.getValue()));
return new JSString(value.replace(from.getValue(), to.getValue()), block);
}

public JSString replaceRegexp(String regexp, JSString to) {
return new JSString(value.replace(regexp, to.getValue()));
return new JSString(value.replace(regexp, to.getValue()), block);
}

public JSString replaceRegexpAll(String regexp, JSString to) {
return new JSString(value.replaceAll(regexp, to.getValue()));
return new JSString(value.replaceAll(regexp, to.getValue()), block);
}

public JSString get(int index) {
Expand Down Expand Up @@ -139,10 +191,14 @@ public JSValue parseFloat() {

@Override
public JSString asString() {
return new JSString(value);
if (dynamic) {
return new JSString(value, block);
}
return new JSString(value, block);
}

public String getValue() {
if (dynamic) evaluate();
return value;
}

Expand All @@ -159,14 +215,22 @@ public int compareTo(Object obj) {

@Override
public JSString clone() {
return new JSString(value);
JSString str = new JSString(value, block);
str.originalValue = originalValue;
str.dynamic = dynamic;
return str;
}

@Override
public String toString() {
if (dynamic) {
evaluate();
}
return "\"" + value + "\"";
}

boolean dynamic = false;
private String originalValue;
private String value;
private String type = "String";
}
Loading

0 comments on commit 8f52caf

Please sign in to comment.