Skip to content

Commit 8d464ce

Browse files
committed
String manipulation
1 parent 4dcb990 commit 8d464ce

File tree

12 files changed

+771
-161
lines changed

12 files changed

+771
-161
lines changed

Compiler/Demo.j

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,77 @@
44
.method static public main([Ljava/lang/String;)V
55
.limit stack 100
66
.limit locals 100
7-
ldc " HelloWorld "
7+
ldc "Hello "
8+
astore 0
9+
new java/lang/StringBuilder
10+
dup
11+
invokespecial java/lang/StringBuilder/<init>()V
12+
aload 0
13+
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
14+
invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
15+
astore 99
16+
new java/lang/StringBuilder
17+
dup
18+
invokespecial java/lang/StringBuilder/<init>()V
19+
aload 0
20+
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
21+
aload 99
22+
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
23+
invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
24+
astore 0
25+
new java/lang/StringBuilder
26+
dup
27+
invokespecial java/lang/StringBuilder/<init>()V
28+
aload 0
29+
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
30+
aload 99
31+
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
32+
invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
33+
astore 0
34+
new java/lang/StringBuilder
35+
dup
36+
invokespecial java/lang/StringBuilder/<init>()V
37+
aload 0
38+
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
39+
aload 99
40+
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
41+
invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
42+
astore 0
43+
new java/lang/StringBuilder
44+
dup
45+
invokespecial java/lang/StringBuilder/<init>()V
46+
aload 0
47+
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
48+
aload 99
49+
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
50+
invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
51+
astore 0
52+
new java/lang/StringBuilder
53+
dup
54+
invokespecial java/lang/StringBuilder/<init>()V
55+
aload 0
56+
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
57+
aload 99
58+
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
59+
invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
60+
astore 0
61+
new java/lang/StringBuilder
62+
dup
63+
invokespecial java/lang/StringBuilder/<init>()V
64+
aload 0
65+
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
66+
aload 99
67+
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
68+
invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
69+
astore 0
70+
new java/lang/StringBuilder
71+
dup
72+
invokespecial java/lang/StringBuilder/<init>()V
73+
aload 0
74+
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
75+
aload 99
76+
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
77+
invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
878
astore 0
979
getstatic java/lang/System/out Ljava/io/PrintStream;
1080
aload 0

Compiler/code.pc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
d=" HelloWorld "
1+
d="Hello "
2+
d=d*8
23
println(d)

Compiler/src/pc/compiler/Compiler.java

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,12 @@
1919
import pc.parser.PCParser.PrintContext;
2020
import pc.parser.PCParser.PrintlnContext;
2121
import pc.parser.PCParser.ProgramContext;
22+
import pc.parser.PCParser.StringAddContext;
23+
import pc.parser.PCParser.StringAddDecimalContext;
24+
import pc.parser.PCParser.StringAddDigitContext;
25+
import pc.parser.PCParser.StringAddStringContext;
2226
import pc.parser.PCParser.StringContext;
27+
import pc.parser.PCParser.StringRepeatContext;
2328
import pc.parser.PCParser.SubtractContext;
2429
import pc.parser.PCParser.VariableContext;
2530

@@ -134,6 +139,70 @@ public String visitString(StringContext ctx) {
134139
return null;
135140
}
136141

142+
public String visitStringAdd(StringAddContext ctx) {
143+
if(symbolTable.get(ctx.var.getText())!=null) {
144+
SymbolTableNode tmp = symbolTable.get(ctx.var.getText());
145+
type = tmp.getType();
146+
if(type.equals("Ljava/lang/String;"))
147+
type = "a";
148+
appendToFile("\nnew java/lang/StringBuilder");
149+
appendToFile("\ndup\ninvokespecial java/lang/StringBuilder/<init>()V");
150+
appendToFile("\n" + type + "load " + tmp);
151+
appendToFile("\ninvokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;");
152+
visit(ctx.right);
153+
appendToFile("\ninvokevirtual java/lang/StringBuilder/append(" + type.toUpperCase() + ")Ljava/lang/StringBuilder;");
154+
appendToFile("\ninvokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;");
155+
type = "a";
156+
}
157+
return null;
158+
}
159+
160+
public String visitStringAddDigit(StringAddDigitContext ctx) {
161+
type = "i";
162+
appendToFile("\nldc " + ctx.digit.getText());
163+
return null;
164+
}
165+
166+
public String visitStringAddDecimal(StringAddDecimalContext ctx) {
167+
type = "f";
168+
appendToFile("\nldc " + ctx.decimal.getText());
169+
return null;
170+
}
171+
172+
public String visitStringAddString(StringAddStringContext ctx) {
173+
type = "Ljava/lang/String;";
174+
appendToFile("\nldc " + ctx.str.getText());
175+
return null;
176+
}
177+
178+
public String visitStringRepeat(StringRepeatContext ctx) {
179+
if(symbolTable.get(ctx.var.getText())!=null) {
180+
SymbolTableNode tmp = symbolTable.get(ctx.var.getText());
181+
type = tmp.getType();
182+
if(type.equals("Ljava/lang/String;"))
183+
type = "a";
184+
appendToFile("\nnew java/lang/StringBuilder");
185+
appendToFile("\ndup\ninvokespecial java/lang/StringBuilder/<init>()V");
186+
appendToFile("\n" + type + "load " + tmp);
187+
appendToFile("\ninvokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;");
188+
appendToFile("\ninvokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;");
189+
appendToFile("\n" + type + "store 99");
190+
int count = Integer.parseInt(ctx.digit.getText());
191+
for(int i=1;i<count;i++) {
192+
appendToFile("\nnew java/lang/StringBuilder");
193+
appendToFile("\ndup\ninvokespecial java/lang/StringBuilder/<init>()V");
194+
appendToFile("\n" + type + "load " + tmp);
195+
appendToFile("\ninvokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;");
196+
appendToFile("\n" + type + "load 99");
197+
appendToFile("\ninvokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;");
198+
appendToFile("\ninvokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;");
199+
if(i<count-1)
200+
appendToFile("\n" + type + "store " + tmp);
201+
}
202+
}
203+
return null;
204+
}
205+
137206
public String visitVariable(VariableContext ctx) {
138207
if(symbolTable.get(ctx.var.getText())!=null) {
139208
SymbolTableNode tmp = symbolTable.get(ctx.var.getText());

Parser/bin/pc/parser/PC.tokens

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ WHITESPACE=15
1818
'println('=3
1919
'='=4
2020
','=5
21-
'/'=6
21+
'+'=6
2222
'*'=7
23-
'-'=8
24-
'+'=9
23+
'/'=8
24+
'-'=9
2525
'\n'=10

Parser/bin/pc/parser/PCLexer.tokens

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ WHITESPACE=15
1818
'println('=3
1919
'='=4
2020
','=5
21-
'/'=6
21+
'+'=6
2222
'*'=7
23-
'-'=8
24-
'+'=9
23+
'/'=8
24+
'-'=9
2525
'\n'=10

Parser/grammar/PC.g4

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,34 @@ programPart : printStatement
77
| newLine
88
;
99

10-
printStatement : 'print(' exp=expression ')' #Print
11-
| 'println(' exp=expression ')' #Println
10+
printStatement : 'print(' exp=expressions ')' #Print
11+
| 'println(' exp=expressions ')' #Println
1212
;
1313

14-
variableDefinition : var=IDENTIFIER '=' exp=expression ',' variableDefinition #MultipleVariable
15-
| var=IDENTIFIER '=' exp=expression #LastVariable
16-
;
14+
variableDefinition : var=IDENTIFIER '=' exp=expressions ',' variableDefinition #MultipleVariable
15+
| var=IDENTIFIER '=' exp=expressions #LastVariable
16+
;
17+
18+
expressions : stringExpression+
19+
| expression+
20+
;
21+
22+
stringExpression : stringRead
23+
| stringConcat
24+
| stringMultiply
25+
;
26+
27+
stringConcat : var=IDENTIFIER '+' right=stringConcat #StringAdd
28+
| str=STRING #StringAddString
29+
| digit=DIGIT #StringAddDigit
30+
| decimal=DECIMAL #StringAddDecimal
31+
;
32+
33+
stringMultiply : var=IDENTIFIER '*' digit=DIGIT #StringRepeat
34+
;
35+
36+
stringRead : str=STRING #String
37+
;
1738

1839
expression : leftExp=expression '/' rightExp=expression #Divide
1940
| leftExp=expression '*' rightExp=expression #Multiply
@@ -22,7 +43,6 @@ expression : leftExp=expression '/' rightExp=expression #Divide
2243
| digit=DIGIT #Digit
2344
| decimal=DECIMAL #Decimal
2445
| var=IDENTIFIER #Variable
25-
| str=STRING #String
2646
;
2747

2848
newLine : '\n' #Line

Parser/src/pc/parser/PC.tokens

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ WHITESPACE=15
1818
'println('=3
1919
'='=4
2020
','=5
21-
'/'=6
21+
'+'=6
2222
'*'=7
23-
'-'=8
24-
'+'=9
23+
'/'=8
24+
'-'=9
2525
'\n'=10

Parser/src/pc/parser/PCBaseVisitor.java

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,56 +59,105 @@ public class PCBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements PCV
5959
* <p>The default implementation returns the result of calling
6060
* {@link #visitChildren} on {@code ctx}.</p>
6161
*/
62-
@Override public T visitAdd(PCParser.AddContext ctx) { return visitChildren(ctx); }
62+
@Override public T visitExpressions(PCParser.ExpressionsContext ctx) { return visitChildren(ctx); }
6363
/**
6464
* {@inheritDoc}
6565
*
6666
* <p>The default implementation returns the result of calling
6767
* {@link #visitChildren} on {@code ctx}.</p>
6868
*/
69-
@Override public T visitDivide(PCParser.DivideContext ctx) { return visitChildren(ctx); }
69+
@Override public T visitStringExpression(PCParser.StringExpressionContext ctx) { return visitChildren(ctx); }
7070
/**
7171
* {@inheritDoc}
7272
*
7373
* <p>The default implementation returns the result of calling
7474
* {@link #visitChildren} on {@code ctx}.</p>
7575
*/
76-
@Override public T visitDigit(PCParser.DigitContext ctx) { return visitChildren(ctx); }
76+
@Override public T visitStringAdd(PCParser.StringAddContext ctx) { return visitChildren(ctx); }
7777
/**
7878
* {@inheritDoc}
7979
*
8080
* <p>The default implementation returns the result of calling
8181
* {@link #visitChildren} on {@code ctx}.</p>
8282
*/
83-
@Override public T visitVariable(PCParser.VariableContext ctx) { return visitChildren(ctx); }
83+
@Override public T visitStringAddString(PCParser.StringAddStringContext ctx) { return visitChildren(ctx); }
8484
/**
8585
* {@inheritDoc}
8686
*
8787
* <p>The default implementation returns the result of calling
8888
* {@link #visitChildren} on {@code ctx}.</p>
8989
*/
90-
@Override public T visitDecimal(PCParser.DecimalContext ctx) { return visitChildren(ctx); }
90+
@Override public T visitStringAddDigit(PCParser.StringAddDigitContext ctx) { return visitChildren(ctx); }
9191
/**
9292
* {@inheritDoc}
9393
*
9494
* <p>The default implementation returns the result of calling
9595
* {@link #visitChildren} on {@code ctx}.</p>
9696
*/
97-
@Override public T visitMultiply(PCParser.MultiplyContext ctx) { return visitChildren(ctx); }
97+
@Override public T visitStringAddDecimal(PCParser.StringAddDecimalContext ctx) { return visitChildren(ctx); }
9898
/**
9999
* {@inheritDoc}
100100
*
101101
* <p>The default implementation returns the result of calling
102102
* {@link #visitChildren} on {@code ctx}.</p>
103103
*/
104-
@Override public T visitSubtract(PCParser.SubtractContext ctx) { return visitChildren(ctx); }
104+
@Override public T visitStringRepeat(PCParser.StringRepeatContext ctx) { return visitChildren(ctx); }
105105
/**
106106
* {@inheritDoc}
107107
*
108108
* <p>The default implementation returns the result of calling
109109
* {@link #visitChildren} on {@code ctx}.</p>
110110
*/
111111
@Override public T visitString(PCParser.StringContext ctx) { return visitChildren(ctx); }
112+
/**
113+
* {@inheritDoc}
114+
*
115+
* <p>The default implementation returns the result of calling
116+
* {@link #visitChildren} on {@code ctx}.</p>
117+
*/
118+
@Override public T visitAdd(PCParser.AddContext ctx) { return visitChildren(ctx); }
119+
/**
120+
* {@inheritDoc}
121+
*
122+
* <p>The default implementation returns the result of calling
123+
* {@link #visitChildren} on {@code ctx}.</p>
124+
*/
125+
@Override public T visitDivide(PCParser.DivideContext ctx) { return visitChildren(ctx); }
126+
/**
127+
* {@inheritDoc}
128+
*
129+
* <p>The default implementation returns the result of calling
130+
* {@link #visitChildren} on {@code ctx}.</p>
131+
*/
132+
@Override public T visitDigit(PCParser.DigitContext ctx) { return visitChildren(ctx); }
133+
/**
134+
* {@inheritDoc}
135+
*
136+
* <p>The default implementation returns the result of calling
137+
* {@link #visitChildren} on {@code ctx}.</p>
138+
*/
139+
@Override public T visitVariable(PCParser.VariableContext ctx) { return visitChildren(ctx); }
140+
/**
141+
* {@inheritDoc}
142+
*
143+
* <p>The default implementation returns the result of calling
144+
* {@link #visitChildren} on {@code ctx}.</p>
145+
*/
146+
@Override public T visitDecimal(PCParser.DecimalContext ctx) { return visitChildren(ctx); }
147+
/**
148+
* {@inheritDoc}
149+
*
150+
* <p>The default implementation returns the result of calling
151+
* {@link #visitChildren} on {@code ctx}.</p>
152+
*/
153+
@Override public T visitMultiply(PCParser.MultiplyContext ctx) { return visitChildren(ctx); }
154+
/**
155+
* {@inheritDoc}
156+
*
157+
* <p>The default implementation returns the result of calling
158+
* {@link #visitChildren} on {@code ctx}.</p>
159+
*/
160+
@Override public T visitSubtract(PCParser.SubtractContext ctx) { return visitChildren(ctx); }
112161
/**
113162
* {@inheritDoc}
114163
*

Parser/src/pc/parser/PCLexer.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ public class PCLexer extends Lexer {
2929
};
3030

3131
private static final String[] _LITERAL_NAMES = {
32-
null, "'print('", "')'", "'println('", "'='", "','", "'/'", "'*'", "'-'",
33-
"'+'", "'\n'"
32+
null, "'print('", "')'", "'println('", "'='", "','", "'+'", "'*'", "'/'",
33+
"'-'", "'\n'"
3434
};
3535
private static final String[] _SYMBOLIC_NAMES = {
3636
null, null, null, null, null, null, null, null, null, null, null, "DIGIT",
@@ -109,8 +109,8 @@ public PCLexer(CharStream input) {
109109
"\7r\2\2\"#\7t\2\2#$\7k\2\2$%\7p\2\2%&\7v\2\2&\'\7*\2\2\'\4\3\2\2\2()\7"+
110110
"+\2\2)\6\3\2\2\2*+\7r\2\2+,\7t\2\2,-\7k\2\2-.\7p\2\2./\7v\2\2/\60\7n\2"+
111111
"\2\60\61\7p\2\2\61\62\7*\2\2\62\b\3\2\2\2\63\64\7?\2\2\64\n\3\2\2\2\65"+
112-
"\66\7.\2\2\66\f\3\2\2\2\678\7\61\2\28\16\3\2\2\29:\7,\2\2:\20\3\2\2\2"+
113-
";<\7/\2\2<\22\3\2\2\2=>\7-\2\2>\24\3\2\2\2?@\7\f\2\2@\26\3\2\2\2AC\t\2"+
112+
"\66\7.\2\2\66\f\3\2\2\2\678\7-\2\28\16\3\2\2\29:\7,\2\2:\20\3\2\2\2;<"+
113+
"\7\61\2\2<\22\3\2\2\2=>\7/\2\2>\24\3\2\2\2?@\7\f\2\2@\26\3\2\2\2AC\t\2"+
114114
"\2\2BA\3\2\2\2CD\3\2\2\2DB\3\2\2\2DE\3\2\2\2E\30\3\2\2\2FH\t\2\2\2GF\3"+
115115
"\2\2\2HI\3\2\2\2IG\3\2\2\2IJ\3\2\2\2JK\3\2\2\2KM\7\60\2\2LN\t\2\2\2ML"+
116116
"\3\2\2\2NO\3\2\2\2OM\3\2\2\2OP\3\2\2\2P\32\3\2\2\2QU\7$\2\2RT\t\3\2\2"+

Parser/src/pc/parser/PCLexer.tokens

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ WHITESPACE=15
1818
'println('=3
1919
'='=4
2020
','=5
21-
'/'=6
21+
'+'=6
2222
'*'=7
23-
'-'=8
24-
'+'=9
23+
'/'=8
24+
'-'=9
2525
'\n'=10

0 commit comments

Comments
 (0)