Skip to content

Commit

Permalink
fstrings in indented while
Browse files Browse the repository at this point in the history
  • Loading branch information
b3b00 committed Nov 4, 2024
1 parent 60f7a75 commit cb76665
Show file tree
Hide file tree
Showing 5 changed files with 204 additions and 17 deletions.
31 changes: 26 additions & 5 deletions src/samples/IndentedWhile/parser/IndentedWhileParserGeneric.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,27 @@ public WhileAST skipStmt(WhileAST expression)

#region OPERANDS

// fstrings
[Production("primary : OPEN_FSTRING[d] fstring_element* CLOSE_FSTRING[d]")]
public WhileAST fstring(List<WhileAST> elements)
{
var fstring = new FString(elements.Cast<FStringElement>().ToList(), elements.First().Position);
return fstring;
}

[Production("fstring_element : FSTRING_CONTENT")]
public WhileAST FStringContent(Token<IndentedWhileTokenGeneric> element)
{
return new FStringElement(new StringConstant(element.Value),element.Position);
}

[Production("fstring_element : OPEN_FSTRING_EXPPRESSION[d] IDENTIFIER CLOSE_FSTRING_EXPPRESSION[d]")]
public WhileAST FStringExpression(Token<IndentedWhileTokenGeneric> element)
{
return new FStringElement(new Variable(element.Value),element.Position);
}


[Production("primary: INT")]
public WhileAST PrimaryInt(Token<IndentedWhileTokenGeneric> intToken)
{
Expand All @@ -156,11 +177,11 @@ public WhileAST PrimaryBool(Token<IndentedWhileTokenGeneric> boolToken)
return new BoolConstant(bool.Parse(boolToken.StringWithoutQuotes));
}

[Production("primary: STRING")]
public WhileAST PrimaryString(Token<IndentedWhileTokenGeneric> stringToken)
{
return new StringConstant(stringToken.StringWithoutQuotes);
}
// [Production("primary: STRING")]
// public WhileAST PrimaryString(Token<IndentedWhileTokenGeneric> stringToken)
// {
// return new StringConstant(stringToken.StringWithoutQuotes);
// }

[Production("primary: IDENTIFIER")]
public WhileAST PrimaryId(Token<IndentedWhileTokenGeneric> varToken)
Expand Down
42 changes: 33 additions & 9 deletions src/samples/IndentedWhile/parser/IndentedWhileTokenGeneric.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,17 @@ public enum IndentedWhileTokenGeneric

[Lexeme(GenericToken.KeyWord, "PRINT")] [Lexeme(GenericToken.KeyWord, "print")]
PRINT = 12,

[Lexeme(GenericToken.KeyWord, "RETURN")] [Lexeme(GenericToken.KeyWord, "return")]
RETURN = 13,

#endregion

#region literals 20 -> 29

[Lexeme(GenericToken.Identifier,IdentifierType.AlphaNumericDash)] IDENTIFIER = 20,

[Lexeme(GenericToken.String)] STRING = 21,
[Mode(ModeAttribute.DefaultLexerMode, "fstringExpression")]
[Lexeme(GenericToken.Identifier, IdentifierType.AlphaNumericDash)]
IDENTIFIER = 20,

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

Expand Down Expand Up @@ -88,16 +88,40 @@ public enum IndentedWhileTokenGeneric

#region sugar 50 ->

// [Lexeme(GenericToken.SugarToken, "(")] LPAREN = 50,
//
// [Lexeme(GenericToken.SugarToken, ")")] RPAREN = 51,

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


[SingleLineComment("#")]
COMMENT=1236
[SingleLineComment("#")] COMMENT = 1236,

#endregion

#region fstring 100 ->

[Push("fstringExpression")] [Mode("fstring")] [Sugar("{")]
OPEN_FSTRING_EXPPRESSION = 100,

[Pop] [Mode("fstringExpression")] [Sugar("}")]
CLOSE_FSTRING_EXPPRESSION = 101,

[Sugar("$\"")]
[Push("fstring")]
OPEN_FSTRING,

[Sugar("\"")]
[Mode("fstring")]
[Pop]
CLOSE_FSTRING,


[Mode("fstring")]
[UpTo("{","\"")]
FSTRING_CONTENT


#endregion



}
}
47 changes: 47 additions & 0 deletions src/samples/while/model/FString.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Text;
using csly.whileLang.compiler;
using Sigil;
using sly.lexer;

namespace csly.whileLang.model;

public class FString : Expression
{
public LexerPosition Position { get; set; }
public Scope CompilerScope { get; set; }

public List<FStringElement> Elements { get; set; }

public FString(List<FStringElement> elements, LexerPosition position)
{
this.Elements = elements;
Position = position;
}

public string Dump(string tab)
{
StringBuilder builder = new StringBuilder();
builder.Append($"{{tab}}\"");
foreach (var element in Elements)
{
builder.Append(element.Dump(""));
}

builder.Append("\"");
return builder.ToString();
}

public string Transpile(CompilerContext context)
{
throw new NotImplementedException();
}

public Emit<Func<int>> EmitByteCode(CompilerContext context, Emit<Func<int>> emiter)
{
throw new NotImplementedException();
}

public WhileType Whiletype { get; set; } = WhileType.STRING;
}
56 changes: 56 additions & 0 deletions src/samples/while/model/FStringElement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System;
using csly.whileLang.compiler;
using Sigil;
using sly.lexer;

namespace csly.whileLang.model;

public class FStringElement : WhileAST
{

public LexerPosition Position { get; set; }

public Scope CompilerScope { get; set; }
public Variable VariableElement { get; set; }

public StringConstant StringElement { get; set; }

public bool IsStringElement => StringElement != null;

public bool IsVariable => VariableElement != null;

public FStringElement(Variable variableElement, LexerPosition position)
{
VariableElement = variableElement;
Position = position;
}

public FStringElement(StringConstant stringElement, LexerPosition position)
{
StringElement = stringElement;
Position = position;
}


public string Dump(string tab)
{
if (IsStringElement)
{
return tab + StringElement.Value;
}
else
{
return $"{{tab}}{{{{{VariableElement.Dump("")}}}";
}
}

public string Transpile(CompilerContext context)
{
throw new NotImplementedException();
}

public Emit<Func<int>> EmitByteCode(CompilerContext context, Emit<Func<int>> emiter)
{
throw new NotImplementedException();
}
}
45 changes: 42 additions & 3 deletions tests/ParserTests/samples/IndentedWhileTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using System;
using System.Linq;
using csly.indentedWhileLang.compiler;
using csly.indentedWhileLang.parser;
using csly.whileLang.interpreter;
Expand Down Expand Up @@ -147,9 +148,9 @@ public void TestIfThenElse()
var program = @"
# TestIfThenElse
if true then
a := ""hello""
a := $""hello""
else
b := ""world""
b := $""world""
";
var result = parser.Parse(program);
Check.That(result).IsOkParsing();
Expand Down Expand Up @@ -206,6 +207,44 @@ public void TestNestedIfThenElse()
}


[Fact]
public void TestFString()
{
var buildResult = buildParser();
var parser = buildResult.Result;
var program = @"
# fstring
v1 := 1
v2 := 2
fstring := $""{v1} - content - {v2} - end""
";
Console.WriteLine("==================================");
Console.WriteLine("=== parse fstring");
Console.WriteLine("==================================");
Console.WriteLine();
var result = parser.Parse(program);
Check.That(result).IsOkParsing();
Check.That(result.Result).IsNotNull();
Check.That(result.Result).IsInstanceOf<SequenceStatement>();
SequenceStatement seq = result.Result as SequenceStatement;
Check.That(seq.Count).IsEqualTo(3);
var fstringAssign = seq.Get(2) as AssignStatement;
Check.That(fstringAssign).IsNotNull();
Check.That(fstringAssign.VariableName).IsEqualTo("fstring");
Check.That(fstringAssign.Value).IsInstanceOf<FString>();
var fString = fstringAssign.Value as FString;
Check.That(fString).IsNotNull();
Check.That(fString.Elements).CountIs(4);
Check.That(fString.Elements[0]).IsInstanceOf<FStringElement>();
Check.That((fString.Elements[0] as FStringElement).IsVariable);
Check.That(fString.Elements[1]).IsInstanceOf<FStringElement>();
Check.That((fString.Elements[1] as FStringElement).IsStringElement);
Check.That(fString.Elements[2]).IsInstanceOf<FStringElement>();
Check.That((fString.Elements[2] as FStringElement).IsVariable);
Check.That(fString.Elements[3]).IsInstanceOf<FStringElement>();
Check.That((fString.Elements[3] as FStringElement).IsStringElement);
}

[Fact]
public void TestInfiniteWhile()
{
Expand Down

0 comments on commit cb76665

Please sign in to comment.