go: lex.sx — raw string literals (backtick) + 9 tests [nothing]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 22s

Adds Go raw string literals per Go spec § String literals:
backtick-delimited, no escape processing, may span multiple
lines, '\r' chars discarded from the value.

gl-read-raw-string! mirrors gl-read-string! but skips escape
handling and the \r filter. scan! routes the leading backtick
to it; emits "string" type (same as interpreted strings — no
need to distinguish at parse/type time).

lex 123/123.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-27 07:22:01 +00:00
parent e60c74f8c3
commit 65467c232b
5 changed files with 90 additions and 17 deletions

View File

@@ -10,7 +10,7 @@
;; legacy 0123 octal; underscores between digits allowed)
;; "float" — decimal float literals (3.14, .5, 1., 1e10, 1.5e-3, 1E5)
;; "imag" — imaginary literals (2i, 3.14i, 1e2i)
;; "string" — interpreted string literals "..."
;; "string" — interpreted string literals "..." OR raw string literals `...`
;; "rune" — rune literals 'x' (single char + simple escapes)
;; "op" — operators & punctuation; :value is the literal text
;; "semi" — explicit ';' or auto-inserted (Go spec § Semicolons)
@@ -253,6 +253,30 @@
(gl-string-loop)))))
(gl-string-loop)
(join "" chars))))
(define
gl-read-raw-string!
(fn
()
(gl-advance! 1)
(let
((chars (list)))
(define
gl-raw-loop
(fn
()
(cond
(>= pos src-len)
nil
(= (gl-cur) "`")
(gl-advance! 1)
(= (gl-cur) "\r")
(do (gl-advance! 1) (gl-raw-loop))
:else (do
(append! chars (gl-cur))
(gl-advance! 1)
(gl-raw-loop)))))
(gl-raw-loop)
(join "" chars))))
(define
gl-read-rune!
(fn
@@ -426,6 +450,11 @@
((start pos) (v (gl-read-string!)))
(gl-emit! "string" v start)
(gl-scan!))
(= (gl-cur) "`")
(let
((start pos) (v (gl-read-raw-string!)))
(gl-emit! "string" v start)
(gl-scan!))
(= (gl-cur) "'")
(let
((start pos) (v (gl-read-rune!)))

View File

@@ -1,9 +1,9 @@
{
"language": "go",
"total_pass": 114,
"total": 114,
"total_pass": 123,
"total": 123,
"suites": [
{"name":"lex","pass":114,"total":114,"status":"ok"},
{"name":"lex","pass":123,"total":123,"status":"ok"},
{"name":"parse","pass":0,"total":0,"status":"pending"},
{"name":"types","pass":0,"total":0,"status":"pending"},
{"name":"eval","pass":0,"total":0,"status":"pending"},

View File

@@ -1,10 +1,10 @@
# Go-on-SX Scoreboard
**Total: 114 / 114 tests passing**
**Total: 123 / 123 tests passing**
| | Suite | Pass | Total |
|---|---|---|---|
| ✅ | lex | 114 | 114 |
| ✅ | lex | 123 | 123 |
| ⬜ | parse | 0 | 0 |
| ⬜ | types | 0 | 0 |
| ⬜ | eval | 0 | 0 |

View File

@@ -143,7 +143,38 @@
(go-test "imag: ASI at newline" (tok-types "1i\n") (list "imag" "semi" "eof"))
;; ── string literals ───────────────────────────────────────────────
(go-test "raw: simple" (tok-values "`hello`") (list "hello" "\n" nil))
(go-test "raw: empty" (tok-values "``") (list "" "\n" nil))
(go-test
"raw: backslash literal — no escape processing"
(tok-values "`a\\nb`")
(list "a\\nb" "\n" nil))
(go-test
"raw: multi-line"
(tok-values "`line1\nline2`")
(list "line1\nline2" "\n" nil))
(go-test
"raw: contains double-quote"
(tok-values "`say \"hi\"`")
(list "say \"hi\"" "\n" nil))
(go-test
"raw: CR stripped (Go spec § String literals)"
(tok-values "`a\r\nb`")
(list "a\nb" "\n" nil))
(go-test "raw: type" (tok-types "`x`") (list "string" "semi" "eof"))
;; ── rune literals ─────────────────────────────────────────────────
(go-test
"raw: then +"
(tok-types "`x` + 1")
(list "string" "op" "int" "semi" "eof"))
(go-test
"raw: ASI at newline after"
(tok-types "`abc`\n")
(list "string" "semi" "eof"))
(go-test "string: empty" (tok-values "\"\"") (list "" "\n" nil))
;; ── comments ──────────────────────────────────────────────────────
(go-test "string: hello" (tok-values "\"hello\"") (list "hello" "\n" nil))
(go-test
"string: with space"
@@ -155,14 +186,12 @@
"string: escape backslash"
(tok-values "\"a\\\\b\"")
(list "a\\b" "\n" nil))
(go-test "string: type" (tok-types "\"x\"") (list "string" "semi" "eof"))
;; ── rune literals ─────────────────────────────────────────────────
;; ── operators & punctuation ───────────────────────────────────────
(go-test "string: type" (tok-types "\"x\"") (list "string" "semi" "eof"))
(go-test "rune: simple" (tok-values "'a'") (list "a" "\n" nil))
(go-test "rune: escape" (tok-values "'\\n'") (list "\n" "\n" nil))
(go-test "rune: type" (tok-types "'a'") (list "rune" "semi" "eof"))
;; ── comments ──────────────────────────────────────────────────────
(go-test "line comment" (tok-types "// ignored") (list "eof"))
(go-test "line comment then code" (tok-values "// hi\nx") (list "x" "\n" nil))
(go-test "block comment" (tok-types "/* a b c */") (list "eof"))
@@ -175,7 +204,7 @@
(tok-types "x /* multi\nline */ y")
(list "ident" "semi" "ident" "semi" "eof"))
;; ── operators & punctuation ───────────────────────────────────────
;; ── automatic semicolon insertion (Go spec § Semicolons) ──────────
(go-test
"ops: arithmetic"
(tok-values "+ - * / %")
@@ -200,8 +229,6 @@
"punct: comma colon dot"
(tok-values ", : .")
(list "," ":" "." nil))
;; ── automatic semicolon insertion (Go spec § Semicolons) ──────────
(go-test
"ASI: after ident at newline"
(tok-types "x\ny")
@@ -213,6 +240,8 @@
(tok-types "\"hi\"\n")
(list "string" "semi" "eof"))
(go-test "ASI: after rune" (tok-types "'a'\n") (list "rune" "semi" "eof"))
;; ── short program ─────────────────────────────────────────────────
(go-test
"ASI: after )"
(tok-types "f()\n")
@@ -222,37 +251,45 @@
(tok-types "x[0]\n")
(list "ident" "op" "int" "op" "semi" "eof"))
(go-test "ASI: after }" (tok-types "{}\n") (list "op" "op" "semi" "eof"))
;; ── report ────────────────────────────────────────────────────────
(go-test "ASI: after ++" (tok-types "i++\n") (list "ident" "op" "semi" "eof"))
(go-test
"ASI: NOT after +"
(tok-types "x +\ny")
(list "ident" "op" "ident" "semi" "eof"))
(go-test
"ASI: NOT after ("
(tok-types "f(\nx)")
(list "ident" "op" "ident" "op" "semi" "eof"))
(go-test
"ASI: blank lines collapse — single semi only"
(tok-types "x\n\n\ny")
(list "ident" "semi" "ident" "semi" "eof"))
(go-test
"ASI: at EOF after ident"
(tok-types "x")
(list "ident" "semi" "eof"))
(go-test
"ASI: explicit semi"
(tok-types "x;y")
(list "ident" "semi" "ident" "semi" "eof"))
;; ── short program ─────────────────────────────────────────────────
(go-test
"short-decl: x := 42 (types)"
(tok-types "x := 42")
(list "ident" "op" "int" "semi" "eof"))
(go-test
"short-decl: x := 42 (values)"
(tok-values "x := 42")
(list "x" ":=" "42" "\n" nil))
(go-test
"func decl shape"
(tok-types "func foo() int { return 0 }")
@@ -269,5 +306,4 @@
"semi"
"eof"))
;; ── report ────────────────────────────────────────────────────────
(define go-lex-test-summary (str "lex " go-test-pass "/" go-test-count))

View File

@@ -143,11 +143,13 @@ Progress-log line → push `origin/loops/go`.
ident/int/string/rune/{break,continue,fallthrough,return}/{++,--,),],}}.
- [x] Float / imaginary literals (decimal floats: `3.14 .5 1. 1e10 1.5e-3`;
imag: `2i 3.14i 1e2i`; hex floats `0x1.fp0` deferred)
- [ ] Raw string literals `` `...` ``
- [x] Raw string literals `` `...` `` (multi-line, no escape processing,
`\r` stripped per Go spec § String literals; same `"string"` type
as interpreted strings)
- [x] Hex/octal/binary integer literals (0x… 0o… 0b…) + underscores
(legacy 0123 octal also accepted; consumes lex-hex-digit?)
- [ ] Full operator set audit (47 distinct per Go spec)
- **Acceptance:** lex/ suite at 50+ tests. Current: 114/114.
- **Acceptance:** lex/ suite at 50+ tests. Current: 123/123.
### Phase 2 — Parser (`lib/go/parse.sx`) ⬜
- Consume `lib/guest/core/pratt.sx` + `lib/guest/core/ast.sx`. Chisel notes
@@ -406,6 +408,12 @@ _(none yet)_
_Newest first. Append one dated entry per commit._
- 2026-05-27 — Phase 1 cont.: raw string literals (backtick-delimited).
Multi-line, no escape processing, `\r` stripped per Go spec § String
literals. Same `"string"` token type as interpreted strings — parsers
/ type checkers don't need to distinguish. +9 tests, lex 123/123.
`[nothing]` — pure Go work; raw strings don't touch the substrate or
lib/guest story.
- 2026-05-27 — Phase 1 cont.: decimal float + imaginary literals.
`3.14`, `.5`, `1.`, `1e10`, `1.5e-3`, `2i`, `3.14i`. `gl-finish-number!`
handles exponent + `i` suffix; `gl-read-number!` returns the type