-
-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add full string interpolation as syntax extension #321
Labels
Milestone
Comments
2 tasks
After implementing #150 you can now read from the parser stream in syntax extensions: (set-special! "$" 'raw-string lips.specials.SYMBOL)
(define (raw-string)
(if (char=? (peek-char) #\")
(begin
(read-char)
(let loop ((result (vector)) (char (peek-char)))
(read-char)
(if (char=? char #\")
(apply string (vector->list result))
(loop (vector-append result (vector char)) (peek-char)))))))
(print $"foo \ bar")
This is working example that read raw string like in Python. So it will be possible to add full string interpolation. |
jcubic
added a commit
that referenced
this issue
Mar 26, 2024
jcubic
added a commit
that referenced
this issue
Mar 26, 2024
jcubic
added a commit
that referenced
this issue
Mar 26, 2024
Here is a working full string interpolation: (set-special! "#\"" 'string-interpolation lips.specials.SYMBOL)
(define (string-interpolation)
(let loop ((current "") (result (vector)) (char (read-char)))
(cond ((and (char=? char #\$)
(char=? (peek-char) #\{))
(read-char)
(let ((expr (read)))
(let ((next (peek-char)))
(if (char=? next #\})
(begin
(read-char)
(loop "" (vector-append result (vector current expr)) (read-char)))
(error (string-append "Parse Error: expecting } got " (repr next)))))))
((char=? char #\\)
(loop (string-append part (repr (read-char))) result (read-char)))
((char=? char #\")
`(string-append ,@(map (lambda (expr)
(if (string? expr)
expr
`(repr ,expr)))
(vector->list (vector-append result (vector current))))))
((eof-object? char)
(error "Parse Error: expecting character #eof found"))
(else
(loop (string-append part (repr char)) result (read-char))))))
(let ((x 10) (y 20))
(print #"this is string \" ${(+ x y)} hello ${(repr "hello" #t)}
world")) I will probably split this into two functions. NOTE the code doesn't handle indentation like LIPS string. |
jcubic
added a commit
that referenced
this issue
Apr 5, 2024
jcubic
added a commit
that referenced
this issue
Apr 5, 2024
jcubic
added a commit
that referenced
this issue
May 13, 2024
jcubic
added a commit
that referenced
this issue
May 13, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is an implementation that works right now
But it has limitations you can't put strings as an interpolated value, because it will break the parser, to be fully working as expected you should be able to use something like this:
But this will not work because the parser doesn't know that it should process
${...}
differently. So interpolation would need to be built into the parser but I don't want that.The alternative is to wait to have
(read)
inside syntax extensions. So this will need to wait for #150For better regex that will work with strings inside quoted expressions, see How to match everything except single character but not inside double quoted string on StackOverflow.
The text was updated successfully, but these errors were encountered: