Skip to content

Instantly share code, notes, and snippets.

@LCamel
Created November 21, 2025 09:55
Show Gist options
  • Select an option

  • Save LCamel/8ad36c401b43230e0fdf19bf82dd1e38 to your computer and use it in GitHub Desktop.

Select an option

Save LCamel/8ad36c401b43230e0fdf19bf82dd1e38 to your computer and use it in GitHub Desktop.
GCL line column offset Loc Range coordinate

如果我們把 Lexer.hs 中的 translateLoc 和 update 改成

import Debug.Trace (trace)
...

    translateLoc (TsToken (L loc x) rest) = TsToken (L (update' loc x) x) (translateLoc rest)
      where
        update' NoLoc x = NoLoc
        update' before@(Loc start (Pos path l c co)) x = result'
          where result = Loc start (Pos path l (c + 1) (co + 1))
                result' = trace ("translateLoc: " ++ show x ++ " before: " ++ show before ++ " after: " ++ show result) result

這樣如果我們的 source code 只有 "{True}" 按下 load 會在 run 起來的 vscode 的 output "GCL LSP Server" 視窗看到

translateLoc: { before: Loc (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 1 0) (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 1 0) after: Loc (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 1 0) (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 2 1)
translateLoc: True before: Loc (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 2 1) (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 5 4) after: Loc (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 2 1) (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 6 5)
translateLoc: } before: Loc (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 6 5) (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 6 5) after: Loc (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 6 5) (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 7 6)

整理一下就是

{
before 1 1 0, 1 1 0
after  1 1 0, 1 2 1

True
before 1 2 1, 1 5 4
after  1 2 1, 1 6 5

}
before 1 6 5, 1 6 5
after  1 6 5, 1 7 6

也就是 translateLoc 讀到 lexer 的輸入本來就是 1-based, 輸出也是沒變 但現在把結尾從 inclusive 往後改成 exclusive 了

而這段的註解我還沒完全弄懂:

    -- According to the document in Data.Loc.Range, the original meaning of Loc is
    -- different from how we use it as Range (to simply put, Range extends 1 in col and charOffset).
    -- The lexer records tokens' ranges in Loc, and we use translateLoc to make it Range.

這段 code 是這時加的:

  作者: geoffcysu
  時間: 2022-09-01 17:48:44 +0800
  Commit: 7cdc7e5d0546f4cccdf7e62be65db2b6830f55ba
  Commit message: "Delete old Syntax.Parser, rename Syntax.Parser2 as the new Syntax.Parser."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment