From d573578b28bc4393dac7f3154b5da29b1fa75358 Mon Sep 17 00:00:00 2001 From: lit Date: Tue, 25 Mar 2025 14:41:17 +0800 Subject: [PATCH] repl: support eof, define object with fields (#24784) For `nim secret`: - **fix(repl): eof(ctrl-D/Z) and ctrl-C were ignored** - **feat(repl): continueLine figures section, constr, bool ops** --------- Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com> --- compiler/llstream.nim | 52 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/compiler/llstream.nim b/compiler/llstream.nim index cc81484830..9392bb41b2 100644 --- a/compiler/llstream.nim +++ b/compiler/llstream.nim @@ -11,7 +11,7 @@ import pathutils - +import std/strutils when defined(nimPreviewSlimSystem): import std/syncio @@ -86,6 +86,47 @@ const LineContinuationOprs = {'+', '-', '*', '/', '\\', '<', '>', '!', '?', '^', '|', '%', '&', '$', '@', '~', ','} AdditionalLineContinuationOprs = {'#', ':', '='} + LineContinuationTokens = [ + "let", "var", "const", "type", # section + "object", "tuple", + # from ./layouter.oprSet + "div", "mod", "shl", "shr", "in", "notin", "is", + "isnot", "not", "of", "as", "from", "..", "and", "or", "xor", + ] # must be all `nimIdentNormalized`-ed + +proc eqIdent(a, bNormalized: string): bool = + a.nimIdentNormalize == bNormalized + +proc endsWithIdent(s, subs: string): bool = + let le = subs.len + if le > s.len: return false + s[^le .. ^1].eqIdent subs + +proc continuesWithIdent(s, subs: string, start: int): bool = + s.substr(start, start+subs.high).eqIdent subs + +proc endsWithIdent(s, subs: string, endIdx: var int): bool = + endIdx.dec subs.len + result = s.continuesWithIdent(subs, endIdx+1) + +proc containsObjectOf(x: string): bool = + const sep = ' ' + var idx = x.rfind(sep) + if idx == -1: return + template eatWord(word) = + while x[idx] == sep: idx.dec + result = x.endsWithIdent(word, idx) + if not result: return + eatWord "of" + eatWord "object" + result = true + +proc endsWithLineContinuationToken(x: string): bool = + result = false + for tok in LineContinuationTokens: + if x.endsWithIdent(tok): + return true + result = x.containsObjectOf proc endsWithOpr*(x: string): bool = result = x.endsWith(LineContinuationOprs) @@ -93,7 +134,9 @@ proc endsWithOpr*(x: string): bool = proc continueLine(line: string, inTripleString: bool): bool {.inline.} = result = inTripleString or line.len > 0 and ( line[0] == ' ' or - line.endsWith(LineContinuationOprs+AdditionalLineContinuationOprs)) + line.endsWith(LineContinuationOprs+AdditionalLineContinuationOprs) or + line.endsWithLineContinuationToken() + ) proc countTriples(s: string): int = result = 0 @@ -109,7 +152,10 @@ proc llReadFromStdin(s: PLLStream, buf: pointer, bufLen: int): int = s.rd = 0 var line = newStringOfCap(120) var triples = 0 - while readLineFromStdin(if s.s.len == 0: ">>> " else: "... ", line): + while true: + if not readLineFromStdin(if s.s.len == 0: ">>> " else: "... ", line): + # now readLineFromStdin meets EOF (ctrl-D/Z) or ctrl-C + quit() s.s.add(line) s.s.add("\n") inc triples, countTriples(line)