From 335ce95c507f58b63a007181cefc6593ca7d0c6b Mon Sep 17 00:00:00 2001 From: "M.V. Hutz" Date: Tue, 13 Jan 2026 02:00:00 +0000 Subject: [PATCH] feat: add comment support to saccharine language (#25) ## Description The saccharine language previously lacked comment support, preventing proper code documentation. This PR implements '#' comment syntax similar to Python. Comments can appear on their own line or at the end of a line, with all content after '#' ignored until the next newline or EOF. The tokenizer now detects '#' and skips characters appropriately without creating tokens. ### Decisions Comments are silently consumed during tokenization rather than being preserved as tokens, keeping the token stream clean for the parser. The implementation preserves newlines after comments by using the iterator's Back() method, allowing them to be processed as soft breaks. ## Benefits Developers can now document their saccharine code with inline and full-line comments. The implementation is minimal and efficient, adding no overhead to the token stream. Tests verify that comments work correctly in various positions without breaking code execution. ## Checklist - [x] Code follows conventional commit format. - [x] Branch follows naming convention (`/`). Always use underscores. - [x] Tests pass (if applicable). - [x] Documentation updated (if applicable). Closes #24 Reviewed-on: https://git.maximhutz.com/mvhutz/lambda/pulls/25 Co-authored-by: M.V. Hutz Co-committed-by: M.V. Hutz --- pkg/saccharine/token/parse.go | 15 +++++++++++++++ tests/comments.expected | 1 + tests/comments.test | 17 +++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 tests/comments.expected create mode 100644 tests/comments.test diff --git a/pkg/saccharine/token/parse.go b/pkg/saccharine/token/parse.go index ef0ad15..b7d5033 100644 --- a/pkg/saccharine/token/parse.go +++ b/pkg/saccharine/token/parse.go @@ -77,6 +77,21 @@ func getToken(i *iterator.Iterator[rune]) (*Token, error) { } case letter == ';': return NewHardBreak(index), nil + case letter == '#': + // Skip everything until the next newline or EOF. + for !i.Done() { + r, err := i.Next() + if err != nil { + return nil, trace.Wrap(err, "error while parsing comment") + } + + if r == '\n' { + // Put the newline back so it can be processed as a soft break. + i.Back() + break + } + } + return nil, nil case unicode.IsSpace(letter): return nil, nil case isVariable(letter): diff --git a/tests/comments.expected b/tests/comments.expected new file mode 100644 index 0000000..2dfe6a3 --- /dev/null +++ b/tests/comments.expected @@ -0,0 +1 @@ +VALUE diff --git a/tests/comments.test b/tests/comments.test new file mode 100644 index 0000000..c033ae0 --- /dev/null +++ b/tests/comments.test @@ -0,0 +1,17 @@ +# This is a full-line comment at the start +# The following defines the identity function +identity := \x.x # This is an end-of-line comment + +# Define a simple function that applies a function twice +twice := \f.\x.(f + # Comments can be anywhere! +(f x)) + +# Test that comments don't interfere with expressions +result := (twice identity VALUE) # Should just return VALUE + +# Multiple comments in a row +# can appear anywhere +# without breaking the code + +result # Final comment at the end