Skip to content

Commit cb76665

Browse files
committed
fstrings in indented while
1 parent 60f7a75 commit cb76665

File tree

5 files changed

+204
-17
lines changed

5 files changed

+204
-17
lines changed

src/samples/IndentedWhile/parser/IndentedWhileParserGeneric.cs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,27 @@ public WhileAST skipStmt(WhileAST expression)
143143

144144
#region OPERANDS
145145

146+
// fstrings
147+
[Production("primary : OPEN_FSTRING[d] fstring_element* CLOSE_FSTRING[d]")]
148+
public WhileAST fstring(List<WhileAST> elements)
149+
{
150+
var fstring = new FString(elements.Cast<FStringElement>().ToList(), elements.First().Position);
151+
return fstring;
152+
}
153+
154+
[Production("fstring_element : FSTRING_CONTENT")]
155+
public WhileAST FStringContent(Token<IndentedWhileTokenGeneric> element)
156+
{
157+
return new FStringElement(new StringConstant(element.Value),element.Position);
158+
}
159+
160+
[Production("fstring_element : OPEN_FSTRING_EXPPRESSION[d] IDENTIFIER CLOSE_FSTRING_EXPPRESSION[d]")]
161+
public WhileAST FStringExpression(Token<IndentedWhileTokenGeneric> element)
162+
{
163+
return new FStringElement(new Variable(element.Value),element.Position);
164+
}
165+
166+
146167
[Production("primary: INT")]
147168
public WhileAST PrimaryInt(Token<IndentedWhileTokenGeneric> intToken)
148169
{
@@ -156,11 +177,11 @@ public WhileAST PrimaryBool(Token<IndentedWhileTokenGeneric> boolToken)
156177
return new BoolConstant(bool.Parse(boolToken.StringWithoutQuotes));
157178
}
158179

159-
[Production("primary: STRING")]
160-
public WhileAST PrimaryString(Token<IndentedWhileTokenGeneric> stringToken)
161-
{
162-
return new StringConstant(stringToken.StringWithoutQuotes);
163-
}
180+
// [Production("primary: STRING")]
181+
// public WhileAST PrimaryString(Token<IndentedWhileTokenGeneric> stringToken)
182+
// {
183+
// return new StringConstant(stringToken.StringWithoutQuotes);
184+
// }
164185

165186
[Production("primary: IDENTIFIER")]
166187
public WhileAST PrimaryId(Token<IndentedWhileTokenGeneric> varToken)

src/samples/IndentedWhile/parser/IndentedWhileTokenGeneric.cs

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,17 @@ public enum IndentedWhileTokenGeneric
4242

4343
[Lexeme(GenericToken.KeyWord, "PRINT")] [Lexeme(GenericToken.KeyWord, "print")]
4444
PRINT = 12,
45-
45+
4646
[Lexeme(GenericToken.KeyWord, "RETURN")] [Lexeme(GenericToken.KeyWord, "return")]
4747
RETURN = 13,
4848

4949
#endregion
5050

5151
#region literals 20 -> 29
5252

53-
[Lexeme(GenericToken.Identifier,IdentifierType.AlphaNumericDash)] IDENTIFIER = 20,
54-
55-
[Lexeme(GenericToken.String)] STRING = 21,
53+
[Mode(ModeAttribute.DefaultLexerMode, "fstringExpression")]
54+
[Lexeme(GenericToken.Identifier, IdentifierType.AlphaNumericDash)]
55+
IDENTIFIER = 20,
5656

5757
[Lexeme(GenericToken.Int)] INT = 22,
5858

@@ -88,16 +88,40 @@ public enum IndentedWhileTokenGeneric
8888

8989
#region sugar 50 ->
9090

91-
// [Lexeme(GenericToken.SugarToken, "(")] LPAREN = 50,
92-
//
93-
// [Lexeme(GenericToken.SugarToken, ")")] RPAREN = 51,
9491

9592
[Lexeme(GenericToken.SugarToken, ";")] SEMICOLON = 52,
9693

9794

98-
[SingleLineComment("#")]
99-
COMMENT=1236
95+
[SingleLineComment("#")] COMMENT = 1236,
96+
97+
#endregion
98+
99+
#region fstring 100 ->
100+
101+
[Push("fstringExpression")] [Mode("fstring")] [Sugar("{")]
102+
OPEN_FSTRING_EXPPRESSION = 100,
103+
104+
[Pop] [Mode("fstringExpression")] [Sugar("}")]
105+
CLOSE_FSTRING_EXPPRESSION = 101,
100106

107+
[Sugar("$\"")]
108+
[Push("fstring")]
109+
OPEN_FSTRING,
110+
111+
[Sugar("\"")]
112+
[Mode("fstring")]
113+
[Pop]
114+
CLOSE_FSTRING,
115+
116+
117+
[Mode("fstring")]
118+
[UpTo("{","\"")]
119+
FSTRING_CONTENT
120+
121+
101122
#endregion
123+
124+
125+
102126
}
103127
}

src/samples/while/model/FString.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using csly.whileLang.compiler;
5+
using Sigil;
6+
using sly.lexer;
7+
8+
namespace csly.whileLang.model;
9+
10+
public class FString : Expression
11+
{
12+
public LexerPosition Position { get; set; }
13+
public Scope CompilerScope { get; set; }
14+
15+
public List<FStringElement> Elements { get; set; }
16+
17+
public FString(List<FStringElement> elements, LexerPosition position)
18+
{
19+
this.Elements = elements;
20+
Position = position;
21+
}
22+
23+
public string Dump(string tab)
24+
{
25+
StringBuilder builder = new StringBuilder();
26+
builder.Append($"{{tab}}\"");
27+
foreach (var element in Elements)
28+
{
29+
builder.Append(element.Dump(""));
30+
}
31+
32+
builder.Append("\"");
33+
return builder.ToString();
34+
}
35+
36+
public string Transpile(CompilerContext context)
37+
{
38+
throw new NotImplementedException();
39+
}
40+
41+
public Emit<Func<int>> EmitByteCode(CompilerContext context, Emit<Func<int>> emiter)
42+
{
43+
throw new NotImplementedException();
44+
}
45+
46+
public WhileType Whiletype { get; set; } = WhileType.STRING;
47+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using System;
2+
using csly.whileLang.compiler;
3+
using Sigil;
4+
using sly.lexer;
5+
6+
namespace csly.whileLang.model;
7+
8+
public class FStringElement : WhileAST
9+
{
10+
11+
public LexerPosition Position { get; set; }
12+
13+
public Scope CompilerScope { get; set; }
14+
public Variable VariableElement { get; set; }
15+
16+
public StringConstant StringElement { get; set; }
17+
18+
public bool IsStringElement => StringElement != null;
19+
20+
public bool IsVariable => VariableElement != null;
21+
22+
public FStringElement(Variable variableElement, LexerPosition position)
23+
{
24+
VariableElement = variableElement;
25+
Position = position;
26+
}
27+
28+
public FStringElement(StringConstant stringElement, LexerPosition position)
29+
{
30+
StringElement = stringElement;
31+
Position = position;
32+
}
33+
34+
35+
public string Dump(string tab)
36+
{
37+
if (IsStringElement)
38+
{
39+
return tab + StringElement.Value;
40+
}
41+
else
42+
{
43+
return $"{{tab}}{{{{{VariableElement.Dump("")}}}";
44+
}
45+
}
46+
47+
public string Transpile(CompilerContext context)
48+
{
49+
throw new NotImplementedException();
50+
}
51+
52+
public Emit<Func<int>> EmitByteCode(CompilerContext context, Emit<Func<int>> emiter)
53+
{
54+
throw new NotImplementedException();
55+
}
56+
}

tests/ParserTests/samples/IndentedWhileTests.cs

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Linq;
1+
using System;
2+
using System.Linq;
23
using csly.indentedWhileLang.compiler;
34
using csly.indentedWhileLang.parser;
45
using csly.whileLang.interpreter;
@@ -147,9 +148,9 @@ public void TestIfThenElse()
147148
var program = @"
148149
# TestIfThenElse
149150
if true then
150-
a := ""hello""
151+
a := $""hello""
151152
else
152-
b := ""world""
153+
b := $""world""
153154
";
154155
var result = parser.Parse(program);
155156
Check.That(result).IsOkParsing();
@@ -206,6 +207,44 @@ public void TestNestedIfThenElse()
206207
}
207208

208209

210+
[Fact]
211+
public void TestFString()
212+
{
213+
var buildResult = buildParser();
214+
var parser = buildResult.Result;
215+
var program = @"
216+
# fstring
217+
v1 := 1
218+
v2 := 2
219+
fstring := $""{v1} - content - {v2} - end""
220+
";
221+
Console.WriteLine("==================================");
222+
Console.WriteLine("=== parse fstring");
223+
Console.WriteLine("==================================");
224+
Console.WriteLine();
225+
var result = parser.Parse(program);
226+
Check.That(result).IsOkParsing();
227+
Check.That(result.Result).IsNotNull();
228+
Check.That(result.Result).IsInstanceOf<SequenceStatement>();
229+
SequenceStatement seq = result.Result as SequenceStatement;
230+
Check.That(seq.Count).IsEqualTo(3);
231+
var fstringAssign = seq.Get(2) as AssignStatement;
232+
Check.That(fstringAssign).IsNotNull();
233+
Check.That(fstringAssign.VariableName).IsEqualTo("fstring");
234+
Check.That(fstringAssign.Value).IsInstanceOf<FString>();
235+
var fString = fstringAssign.Value as FString;
236+
Check.That(fString).IsNotNull();
237+
Check.That(fString.Elements).CountIs(4);
238+
Check.That(fString.Elements[0]).IsInstanceOf<FStringElement>();
239+
Check.That((fString.Elements[0] as FStringElement).IsVariable);
240+
Check.That(fString.Elements[1]).IsInstanceOf<FStringElement>();
241+
Check.That((fString.Elements[1] as FStringElement).IsStringElement);
242+
Check.That(fString.Elements[2]).IsInstanceOf<FStringElement>();
243+
Check.That((fString.Elements[2] as FStringElement).IsVariable);
244+
Check.That(fString.Elements[3]).IsInstanceOf<FStringElement>();
245+
Check.That((fString.Elements[3] as FStringElement).IsStringElement);
246+
}
247+
209248
[Fact]
210249
public void TestInfiniteWhile()
211250
{

0 commit comments

Comments
 (0)