Skip to content

Commit 09eea10

Browse files
committed
Added the #Var keyword
1 parent 8dc005d commit 09eea10

4 files changed

Lines changed: 207 additions & 4 deletions

File tree

Intellij.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@
122122
#Paste
123123
#TEXT
124124
#Text
125+
#VAR
126+
#Var
125127
#WITH
126128
#With
127129
#define
@@ -135,6 +137,7 @@
135137
#make
136138
#paste
137139
#text
140+
#var
138141
#with
139142
```
140143
- Ignore case: `unchecked`

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
### Jamplate is a C-style pre-processor that mainly made for Java.
22

33
## How To Use
4-
- `#define` to define a variable
4+
- `#define` to define a constant (yet overridable) value to a specified address
5+
- `#var` to define a variable (also overridable) value to a specified address
56
- `#if` `#elif` `#else` to control the flow and `#endif` to close `#if` statements
67
- `#text` for debugging purposes, makes plain text.
78
- `#paste` to paste a variable defined in the scope it is located on.

src/main/java/org/jamplate/parser/ScopeParser.java

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
* The default jamplate parser that parses {@link String}s into {@link Scope}s.
2828
*
2929
* @author LSafer
30-
* @version 0.0.3
30+
* @version 0.0.5
3131
* @since 0.0.1 ~2020.09.19
3232
*/
3333
public class ScopeParser implements PollParser<Scope> {
@@ -37,6 +37,12 @@ public class ScopeParser implements PollParser<Scope> {
3737
* @since 0.0.2 ~2020.09.21
3838
*/
3939
protected static final Pattern COMMON_PARAMETERS_ARRAY = Pattern.compile("\\s*(?<PARAMETER>(?:[^|]|(?:(?<=\\\\)[|]))*\\S)\\s*(?=[|]|$)");
40+
/**
41+
* Common pattern to extract definition parameters.
42+
*
43+
* @since 0.0.5 ~2020.09.22
44+
*/
45+
protected static final Pattern COMMON_PARAMETERS_DEF = Pattern.compile("^\\s*(?<ADDRESS>\\S+)\\s*(?<LOGIC>.*)$");
4046
/**
4147
* Common pattern to extract single integer parameter.
4248
*
@@ -67,6 +73,7 @@ public class ScopeParser implements PollParser<Scope> {
6773
* @since 0.0.1 ~2020.09.20
6874
*/
6975
protected static final Pattern COMMON_PARAMETER_PAIR = Pattern.compile("\\s*(?<KEY>\\S+)\\s*:\\s*(?<LOGIC>\\S+)\\s*");
76+
7077
/**
7178
* A pattern that catches jamplate commands.
7279
*
@@ -85,7 +92,7 @@ public class ScopeParser implements PollParser<Scope> {
8592
*
8693
* @since 0.0.1 ~2020.09.20
8794
*/
88-
protected static final Pattern PATTERN_DEFINE_PARAMETERS = Pattern.compile("^\\s*(?<ADDRESS>\\S+)\\s*(?<LOGIC>.*)$");
95+
protected static final Pattern PATTERN_DEFINE_PARAMETERS = ScopeParser.COMMON_PARAMETERS_DEF;
8996

9097
/**
9198
* A pattern to be used to detect {@link Elif} commands.
@@ -216,6 +223,19 @@ public class ScopeParser implements PollParser<Scope> {
216223
*/
217224
protected static final Pattern PATTERN_TEXT_PARAMETERS = Pattern.compile("^\\s*(?<TEXT>.*)$");
218225

226+
/**
227+
* A pattern to be used to detected {@link Var} commands.
228+
*
229+
* @since 0.0.5 ~2020.09.22
230+
*/
231+
protected static final Pattern PATTERN_VAR = Pattern.compile("^#VAR", Pattern.CASE_INSENSITIVE);
232+
/**
233+
* A pattern to be used to extract the parameters of a {@link Var} command.
234+
*
235+
* @since 0.0.5 ~2020.09.22
236+
*/
237+
protected static final Pattern PATTERN_VAR_PARAMETER = ScopeParser.COMMON_PARAMETERS_DEF;
238+
219239
/**
220240
* A pattern to be used to detect {@link With} commands.
221241
*
@@ -309,6 +329,7 @@ public void parse(List poll) {
309329
this.parseMakes(poll);
310330
this.parsePastes(poll);
311331
this.parseTexts(poll);
332+
this.parseVars(poll);
312333
this.parseWiths(poll);
313334

314335
//clear leftovers
@@ -348,7 +369,7 @@ protected void parseDefines(List poll) {
348369
Matcher valueMatcher = ScopeParser.PATTERN_DEFINE_PARAMETERS.matcher(value);
349370

350371
if (valueMatcher.find()) {
351-
//target value #DEFINE parameters only
372+
//target valid #DEFINE parameters only
352373
String address = valueMatcher.group("ADDRESS");
353374
String logic = valueMatcher.group("LOGIC");
354375

@@ -732,6 +753,48 @@ protected void parseTexts(List poll) {
732753
}
733754
}
734755

756+
/**
757+
* Parse all the var statements in a {@link String} in the given {@code poll} into {@link Var}
758+
* scopes.
759+
*
760+
* @param poll the poll to parse all the var statements in it.
761+
* @throws NullPointerException if the given {@code poll} is null.
762+
* @throws ParseException if any parse exception occurs.
763+
* @since 0.0.1 ~2020.09.20
764+
*/
765+
protected void parseVars(List poll) {
766+
Objects.requireNonNull(poll, "poll");
767+
768+
ListIterator iterator = poll.listIterator();
769+
while (iterator.hasNext()) {
770+
Object object = iterator.next();
771+
772+
if (object instanceof String) {
773+
//target Strings only
774+
String string = (String) object;
775+
Matcher matcher = ScopeParser.PATTERN_VAR.matcher(string);
776+
777+
if (matcher.find()) {
778+
//target #VAR commands only
779+
String value = string.substring(matcher.end());
780+
Matcher valueMatcher = ScopeParser.PATTERN_VAR_PARAMETER.matcher(value);
781+
782+
if (valueMatcher.find()) {
783+
//target valid #VAR parameters only
784+
String address = valueMatcher.group("ADDRESS");
785+
String logic = valueMatcher.group("LOGIC");
786+
787+
//Replace
788+
iterator.set(new Var(
789+
address,
790+
this.logic.parse(logic)
791+
));
792+
}
793+
}
794+
}
795+
}
796+
}
797+
735798
/**
736799
* Parse all the with statements in a {@link String} in the given {@code poll} into {@link With}
737800
* scopes.
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*
2+
* Copyright 2020 Cufy
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.jamplate.scope;
17+
18+
import org.jamplate.logic.Constant;
19+
import org.jamplate.logic.Logic;
20+
import org.jamplate.memory.ScopeMemory;
21+
22+
import java.io.IOException;
23+
import java.util.Objects;
24+
25+
/**
26+
* A scope that defines a {@link Logic} to an address, and can be modified later.
27+
*
28+
* @author LSafer
29+
* @version 0.0.5
30+
* @since 0.0.5 ~2020.09.22
31+
*/
32+
public class Var extends AbstractScope {
33+
/**
34+
* The address this scope is holding its {@link #value} to.
35+
*
36+
* @since 0.0.5 ~2020.09.22
37+
*/
38+
protected final String address;
39+
/**
40+
* The value this scope is currently mapping to {@link #address}.
41+
*
42+
* @since 0.0.5 ~2020.09.22
43+
*/
44+
protected Logic value;
45+
46+
/**
47+
* Create a new scope that can hold a value to the given {@code address}.
48+
*
49+
* @param address the address the constructed scope is holding values to.
50+
* @throws NullPointerException if the given {@code address} is null.
51+
* @since 0.0.5 ~2020.09.22
52+
*/
53+
public Var(String address) {
54+
Objects.requireNonNull(address, "address");
55+
this.address = address;
56+
this.value = new Constant("");
57+
}
58+
59+
/**
60+
* Create a new scope that defines the given {@code value} to the given {@code address}. The
61+
* created scope's {@code value} can be replaced later.
62+
*
63+
* @param address the address to map the given {@code value} to.
64+
* @param value the value the created scope will hold initially.
65+
* @throws NullPointerException if the given {@code address} or {@code value} is null.
66+
* @since 0.0.5 ~2020.09.22
67+
*/
68+
public Var(String address, Logic value) {
69+
Objects.requireNonNull(address, "address");
70+
Objects.requireNonNull(value, "value");
71+
this.address = address;
72+
this.value = value;
73+
}
74+
75+
/**
76+
* Return the {@link #address} of this scope.
77+
*
78+
* @return the {@link #address} of this scope.
79+
* @since 0.0.5 ~2020.09.22
80+
*/
81+
public final String address() {
82+
return this.address;
83+
}
84+
85+
/**
86+
* Return the {@link #value} of this scope.
87+
*
88+
* @return the {@link #value} of this scope.
89+
* @since 0.0.5 ~2020.09.22
90+
*/
91+
public final Logic value() {
92+
return this.value;
93+
}
94+
95+
@Override
96+
public synchronized Logic memory(String address) {
97+
Objects.requireNonNull(address, "address");
98+
return this.address.equals(address) ?
99+
this.value :
100+
super.memory(address);
101+
}
102+
103+
@Override
104+
protected Appendable invoke(Appendable appendable, ScopeMemory memory) throws IOException {
105+
Objects.requireNonNull(appendable, "appendable");
106+
Objects.requireNonNull(memory, "memory");
107+
108+
//little journey to previous scopes :)...
109+
for (Scope scope = this.previous; scope != null; scope = scope.previous())
110+
if (scope instanceof Var) {
111+
//found someone that could understand me!
112+
Var var = (Var) scope;
113+
114+
if (this.address.equals(var.address()))
115+
//that was my brother
116+
synchronized (this) {
117+
//hay brother, could you please update your value and be like me?
118+
var.value(this.value);
119+
}
120+
}
121+
122+
return super.invoke(appendable, memory);
123+
}
124+
125+
/**
126+
* Update the {@link #value} of this scope.
127+
*
128+
* @param value the value of this scope.
129+
* @throws NullPointerException if the given {@code value} is null.
130+
* @since 0.0.5
131+
*/
132+
public synchronized void value(Logic value) {
133+
Objects.requireNonNull(value, "value");
134+
this.value = value;
135+
}
136+
}

0 commit comments

Comments
 (0)