feat: backtick raw/multi-line strings + QBE backend fixes
- Add backtick raw string literals (Go-style ): no escape processing, multi-line - C backend: handle backtick strings in emitExpr - Self-hosted lexer: lexScanBacktickString support - QBE backend: handle backtick strings in data sections - QBE: remove broken extern declarations (QBE resolves at link time) - QBE: fix comparison result types (ceql → w, extend to l) - QBE: fix SSA parameter name clash (_p_ prefix for params) - QBE: const inlining via HirLower + QBE emitter - QBE: proper type mapping for bool/char types - hir_lower: collect dkConst declarations for const propagation
This commit is contained in:
+4
-1
@@ -160,8 +160,11 @@ proc emitExpr(be: var CBackend, node: HirNode): string =
|
||||
else: return "false"
|
||||
of tkStringLiteral:
|
||||
var text = node.litToken.text
|
||||
# Backtick raw string: strip backticks, escape content for C
|
||||
if text.len >= 2 and text[0] == '`' and text[text.len-1] == '`':
|
||||
text = "\"" & cEscape(text[1 ..< text.len-1]) & "\""
|
||||
# If text has no surrounding quotes, it's from constFoldConstDecl (already unescaped)
|
||||
if text.len >= 2 and text[0] == '"' and text[text.len-1] == '"':
|
||||
elif text.len >= 2 and text[0] == '"' and text[text.len-1] == '"':
|
||||
# Strip c8" c16" c32" prefixes — in C they are just regular string literals
|
||||
if text.startsWith("c32\""):
|
||||
text = "\"" & cEscape(text[4 ..< text.len-1]) & "\""
|
||||
|
||||
@@ -277,6 +277,18 @@ proc scanString(lex: var Lexer, startLoc: SourceLocation, prefixLen: int): Token
|
||||
discard lex.advance() # closing "
|
||||
result = lex.makeToken(tkStringLiteral, startLoc, startPos)
|
||||
|
||||
proc scanBacktickString(lex: var Lexer, startLoc: SourceLocation): Token =
|
||||
## Scan a backtick-delimited raw string literal: content is literal,
|
||||
## no escape processing, newlines are preserved.
|
||||
let startPos = lex.pos - 1 # include the opening backtick
|
||||
while not lex.isAtEnd() and lex.peek() != '`':
|
||||
discard lex.advance()
|
||||
if lex.isAtEnd():
|
||||
lex.emitError(startLoc, "unterminated backtick string literal")
|
||||
else:
|
||||
discard lex.advance() # closing backtick
|
||||
result = lex.makeToken(tkStringLiteral, startLoc, startPos)
|
||||
|
||||
proc scanChar(lex: var Lexer, startLoc: SourceLocation, prefixLen: int): Token =
|
||||
let startPos = lex.pos - prefixLen
|
||||
if lex.peek() == '\'':
|
||||
@@ -523,6 +535,11 @@ proc nextToken(lex: var Lexer): Token =
|
||||
if c == '"':
|
||||
return lex.scanString(startLoc, 0)
|
||||
|
||||
# Backtick-delimited raw string: `...`
|
||||
if c == '`':
|
||||
discard lex.advance()
|
||||
return lex.scanBacktickString(startLoc)
|
||||
|
||||
# Char prefixes: c8' c16' c32' — must come before ident check
|
||||
if c == 'c' and lex.peek(1) in {'8', '1', '3'}:
|
||||
let d = lex.peek(1)
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ type
|
||||
##Literals
|
||||
tkIntLiteral # 42 0xFF 0b1010 0o77
|
||||
tkFloatLiteral # 3.14 1.0e-9
|
||||
tkStringLiteral # "hello" c8"hello" c16"hello" c32"hello"
|
||||
tkStringLiteral # "hello" c8"hello" c16"hello" c32"hello" `raw multi-line`
|
||||
tkCharLiteral # 'A' c8'A' c16'A' c32'A'
|
||||
tkBoolLiteral # true false
|
||||
|
||||
|
||||
Reference in New Issue
Block a user