Skip to content

Commit f593881

Browse files
authored
Merge pull request #498 from b3b00/test/fstrings
Test/fstrings
2 parents f8b50be + ac2acce commit f593881

File tree

8 files changed

+258
-28
lines changed

8 files changed

+258
-28
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/compiler/ExpressionTyper.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ public WhileType TypeExpression(Expression expr, CompilerContext context)
2929
return varType;
3030
}
3131

32+
if (expr is FString fstring)
33+
{
34+
return WhileType.STRING;
35+
}
36+
3237
throw new SignatureException($"unknow expression type ({expr.GetType().Name})");
3338
}
3439

src/samples/while/model/FString.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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+
if (Elements.Count == 1)
44+
{
45+
return Elements[0].EmitByteCode(context, emiter);
46+
}
47+
48+
return null;
49+
}
50+
51+
public WhileType Whiletype { get; set; } = WhileType.STRING;
52+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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+
if (IsStringElement)
55+
{
56+
return StringElement.EmitByteCode(context, emiter);
57+
}
58+
else
59+
{
60+
return VariableElement.EmitByteCode(context, emiter);
61+
}
62+
}
63+
}

src/sly/lexer/fsm/FSMLexer.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -314,36 +314,44 @@ private FSMMatch<N> ConsumeIndents3(ReadOnlyMemory<char> source, LexerPosition l
314314
{
315315
case LexerIndentationType.Indent:
316316
{
317+
var position = lexerPosition.Clone();
318+
position.IsPush = false;
319+
position.IsPop = false;
320+
position.Mode = null;
317321
var indent = FSMMatch<N>.Indent(lexerPosition.Indentation.CurrentLevel);
318322
indent.Result = new Token<N>
319323
{
320324
IsIndent = true,
321325
IsUnIndent = false,
322326
IsNoIndent = false,
323-
Position = lexerPosition.Clone()
327+
Position = position
324328
};
325329
indent.IsNoIndent = false;
326330
indent.IsIndent = true;
327331
indent.IsUnIndent = false;
328-
indent.NewPosition = lexerPosition.Clone();
332+
indent.NewPosition = position;
329333
indent.NewPosition.Index += currentShift.Length;
330334
indent.NewPosition.Column += currentShift.Length;
331335
return indent;
332336
}
333337
case LexerIndentationType.UIndent:
334338
{
335339
var uIndent = FSMMatch<N>.UIndent(lexerPosition.Indentation.CurrentLevel);
340+
var position = lexerPosition.Clone();
341+
position.IsPush = false;
342+
position.IsPop = false;
343+
position.Mode = null;
336344
uIndent.Result = new Token<N>
337345
{
338346
IsIndent = false,
339347
IsUnIndent = true,
340348
IsNoIndent = false,
341-
Position = lexerPosition.Clone()
349+
Position = position
342350
};
343351
uIndent.IsNoIndent = false;
344352
uIndent.IsIndent = false;
345353
uIndent.IsUnIndent = true;
346-
uIndent.NewPosition = lexerPosition.Clone();
354+
uIndent.NewPosition = position;
347355
uIndent.NewPosition.Index += currentShift.Length;
348356
uIndent.NewPosition.Column += currentShift.Length;
349357
return uIndent;

src/sly/lexer/fsm/FSMMatch.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ public static FSMMatch<N> Indent(int level)
6666
IsIndent = true,
6767
IsSuccess = true,
6868
IndentationLevel = level,
69+
IsPop = false,
70+
IsPush = false,
6971
Result = new Token<N> {IsIndent = true, IsEOS = false}
7072
};
7173
}
@@ -76,6 +78,8 @@ public static FSMMatch<N> UIndent(int level, int count = 1)
7678
{
7779
IsUnIndent = true,
7880
IsSuccess = true,
81+
IsPop = false,
82+
IsPush = false,
7983
IndentationLevel = level,
8084
Result = new Token<N> {IsUnIndent = true, IsEOS = false},
8185
UnIndentCount = count

0 commit comments

Comments
 (0)