Joan edukira
Ridgun
Euskara

23 Ridgun Liburua

fmt lib-a — 2D Formateatzaile Taularatu Kanonikoa eta 9 Formatuko Sintaxi-nabarmentzailea

23.1. Zergatik existitzen da fmt lib-a? (Benetako arazoa eta Ridgun filosofia)

«Zergatik behar dut fmt lib bat hutsetik Ridgun hutsean idatzia, betiko C liburutegi bat estekatu beharrean?»

Hori da edozein sistema-ingeniarik fmt-era iristean egiten duen lehen galdera. Eta erantzunak ridgun-libs-en filosofia osoa laburbiltzen du:

Izan gaitezen zintzoak: Ridgun kodearen edertasuna ezin hobeto lerrokatutako zutabe taularatuetan datza (::, =, |, ->, --), baina zuriuneak eskuz lerrokatzea edo kode koloreztatua terminal, HTML eta LaTeXerako esportatzea neketsua da.

fmt lib-a Ridgunen 2D formateatze taularatuko eta nabarmentze lexikoko motor ofiziala da: fn :: sinadurak, ekuazioak, | zainak eta -- iruzkinak lerrokatzen ditu, eta 9 irteera-formatutara esportatzen du (FmtPlain, FmtTty, FmtTrueColor, FmtHtmlInline, FmtHtmlCss, FmtMarkdown, FmtPango, FmtLatex, FmtRtf).

Ekosistema tradizional batean, FMT domeinuko zereginak ebazteak C-ko kanpo-mendekotasunak arrastatzea, erakusle gordinekin borrokatzea, mota-bihurketa opakuak, egiaztatu gabeko salbuespenak edo zabor-biltzailearen geldialdi ustekabekoak jasatea dakar. Ridgunen, fmt lib-ak (src/main/ridgun/lib/fmt.rg) lau printzipio negoziatu ezinekin heltzen dio arazoari:

  1. Deklaratu import fmt (edo import fmt as alias) fitxategiaren hasieran: lib bakoitzak module :: fmt izen-espazioa definitzen du eta --strict moduan hitz anitzeko funtzioei zuriune naturalekin deitzen zaie beti.
  2. Kateatu zure datu-hodiak ezkerretik eskuinera -> bidez: idatzi sarrera lehen urratsa -> bigarren urratsa -> emaitza, erabili (+ _ _ +) maskarak sekuentziak desegituratzeko eta kendu _ = sententzia sekuentzialetan (edo baztertu -> () bidez).
  3. Isats-errekurtsioa TCOrekin (Tail-Call Optimization): fmt-eko barne-ibilbide guztiak $O(1)$ pila-espazioko begizta natiboetara konpilatzen dira.
  4. Memoria determinista (RMM1 / RMM2): tarteko egitura bakoitza bere azken irakurketa amaitzen den une zehatzean askatzen da, Garbage Collector gabe.

23.2. Artefaktu natiboak, inportazioa eta fmt APIaren katalogo osoa

ridgun-libs-en, fmt lehen mailako lib bat da, src/main/ridgun/lib/fmt.rg bidean kokatua (FMT domeinua). stable bundle-ekin konpilatzean, hiru formatu natibotan paketatzen da:

ArtefaktuaBideaHelburua
Ridgun Bundle-atarget/bundles/fmt.rglibBanaketa eta inportazio zuzena import fmt bidez
Fitxategi konpilatuatarget/fmt.rgcridgunc-ek egiaztatutako tarteko artefaktua
ELF64 objektu partekatuatarget/libfmt.soC edo libc mendekotasunik gabeko liburutegi dinamiko natiboa

Lib bakoitzak bere izen-espazioa deklaratzen du module :: fmt bidez: nahikoa da goiburuan import fmt (edo import fmt as alias) idaztea eta bere funtzioei zuriune naturalekin (nire funtzioa x) eta -> hodiekin (x nire funtzioa -> emaitza) deitzea.

23.2.1. fmt-eko familia funtzionalen laburpena

Sinadura / Funtzioa / MotaZer egiten duen eta noiz erabili
fmt source / fmt source withRidgun iturburu-kodea formateatzen du 2D zutabe-lerrokatze taularatu kanonikoarekin
fmt checkTrue itzultzen du kodeak dagoeneko fmt source diseinu kanonikoa betetzen badu
fmt render / fmt render withKodea formateatu eta koloreztatzen du 9 FmtTarget irteera-formatuetako edozeinetara
fmt tokenize lineLerro bat TokKeyword, TokType, TokOperator, TokString, TokNumber, TokComment-etan tokenizatzen du

23.2.2. src/main/ridgun/lib/fmt.rg-eko mota eta sinadura guztien katalogoa

Jarraian duzu src/main/ridgun/lib/fmt.rg fitxategian definitutako mota aljebraiko (type), eragile (op ::) eta funtzio-sinadura (fn ::) guztien inbentario osoa (7 mota, 0 eragile eta 166 funtzio):

fmt-eko mota aljebraikoak eta erregistroak (type):

type FmtTarget = FmtPlain | FmtTty | FmtTrueColor | FmtHtmlInline | FmtHtmlCss | FmtMarkdown | FmtPango | FmtLatex | FmtRtf
type FmtTheme = FmtThemeNone | FmtThemeDark | FmtThemeLight
type FmtConfig = indent_width: Int, max_align_params: Int, max_line_width: Int, is_aligned: Bool, target_format: FmtTarget, color_theme: FmtTheme
type FmtToken = FmtTok String Int
type FmtSig = NoSig | SigInfo String [String] String String [Int] Int Int
type FmtClause = NoClause | ClauseInfo [String] Bool String
type FmtWhereBind = NoWhereBind | WhereBindInfo String String
#Funtzioa / Sinadura (fn ::)Itzulera-mota
1fn :: default fmt configFmtConfig
2fn :: fmt config Int Int Int Bool FmtTarget FmtThemeFmtConfig
3fn :: fmt max Int IntInt
4fn :: fmt str list len [String]Int
5fn :: fmt str head [String]String
6fn :: fmt int at [Int] IntInt
7fn :: fmt spaces IntString
8fn :: fmt is hspace IntBool
9fn :: fmt leading indent loop String Int IntInt
10fn :: fmt leading indent StringInt
11fn :: fmt trim left loop String Int IntString
12fn :: fmt trim left StringString
13fn :: fmt trim right loop String IntString
14fn :: fmt trim right StringString
15fn :: fmt trim StringString
16fn :: fmt split raw lines loop String Int Int Int Int [String][String]
17fn :: fmt split raw lines String[String]
18fn :: fmt join lines [String]String
19fn :: fmt skip quoted String Int Int IntInt
20fn :: fmt find comment col String Int IntInt
21fn :: fmt strip comment StringString
22fn :: fmt strip comment at String IntString
23fn :: fmt extract comment StringString
24fn :: fmt extract comment at String IntString
25fn :: fmt skip hspace String Int IntInt
26fn :: fmt scan group end String Int Int IntInt
27fn :: fmt scan word end String Int Int IntInt
28fn :: fmt scan token end String Int Int IntInt
29fn :: fmt scan tokens loop String Int Int [FmtToken][FmtToken]
30fn :: fmt scan tokens at String Int Int [FmtToken][FmtToken]
31fn :: fmt scan tokens at step String Int Int [FmtToken] Int[FmtToken]
32fn :: fmt scan tokens String[FmtToken]
33fn :: fmt split sig arrow [FmtToken] [String](Bool, [String], String, Int)
34fn :: fmt is sig type tok StringBool
35fn :: fmt all type toks [String]Bool
36fn :: fmt is bare fn lhs [String]Bool
37fn :: fmt infer bare kind [String]String
38fn :: fmt parse sig line StringFmtSig
39fn :: fmt parse sig tokens Int String String [FmtToken]FmtSig
40fn :: fmt finish bare sig parse String String (Bool, [String], String, Int)FmtSig
41fn :: fmt finish sig parse String String String (Bool, [String], String, Int)FmtSig
42fn :: fmt append comment String StringString
43fn :: fmt has fat arrow [FmtToken]Bool
44fn :: fmt is top decl line StringBool
45fn :: fmt is top decl toks Int String [FmtToken]Bool
46fn :: fmt op tokens match [String] [String]Bool
47fn :: fmt is bare kind StringBool
48fn :: fmt sig base col StringInt
49fn :: fmt sig base col from FmtSigInt
50fn :: fmt clause matches sig String [String] [String]Bool
51fn :: fmt split clause eq [FmtToken] [String]([String], Bool, Int)
52fn :: fmt next nonblank is guard [String]Bool
53fn :: fmt check guard line String [String]Bool
54fn :: fmt parse clause line FmtSig String BoolFmtClause
55fn :: fmt parse clause clean String [String] String String String BoolFmtClause
56fn :: fmt check clause split String [String] String Bool ([String], Bool, Int)FmtClause
57fn :: fmt build clause info String [String] Bool IntFmtClause
58fn :: fmt find where arrow [FmtToken]Int
59fn :: fmt parse where line String BoolFmtWhereBind
60fn :: fmt parse where clean String String StringFmtWhereBind
61fn :: fmt build where bind String String IntFmtWhereBind
62fn :: fmt check where nonempty String StringFmtWhereBind
63fn :: fmt map str lens [String][Int]
64fn :: fmt slot width Int IntInt
65fn :: fmt max widths [Int] [String][Int]
66fn :: fmt build col starts [Int] Int[Int]
67fn :: fmt end col [Int] IntInt
68fn :: fmt scan group widths FmtSig [String] [Int] Int Bool Int([Int], Int)
69fn :: fmt scan group step FmtSig String [String] [Int] Int Bool Int FmtClause FmtWhereBind([Int], Int)
70fn :: fmt compute group geometry FmtSig [String] FmtConfigFmtSig
71fn :: fmt count op params [String]Int
72fn :: fmt count sig params String [String]Int
73fn :: fmt finish group geometry String [String] String String ([Int], Int) FmtConfigFmtSig
74fn :: fmt select group geometry String [String] String String [Int] Int Int Int Int FmtConfigFmtSig
75fn :: fmt pad lhs tokens [String] [Int] Int StringString
76fn :: fmt sig prefix String StringString
77fn :: fmt format sig line FmtSigString
78fn :: fmt format clause line FmtSig [String] Bool StringString
79fn :: fmt finish clause rhs String Bool String Int IntString
80fn :: fmt format where line FmtSig String String IntString
81fn :: fmt line opens block StringBool
82fn :: fmt check block opener String IntBool
83fn :: fmt line closes block StringBool
84fn :: fmt guard indent Int Int Int String IntInt
85fn :: fmt guard indent clean Int Int Int String String IntInt
86fn :: fmt format group body FmtSig [String] Int String Bool FmtConfig[String]
87fn :: fmt format group line FmtSig String String String Int [String] Int String Bool FmtConfig FmtClause FmtWhereBind[String]
88fn :: fmt format guard line FmtSig String Int [String] Int String FmtConfig Int[String]
89fn :: fmt next body indent Int String IntInt
90fn :: fmt next body indent clean Int String String IntInt
91fn :: fmt indent body line Int String String IntString
92fn :: fmt take group lines [String] [String]([String], [String])
93fn :: fmt format top lines [String] Int String FmtConfig[String]
94fn :: fmt dispatch top line String [String] Int String FmtConfig FmtSig[String]
95fn :: fmt run sig group FmtSig ([String], [String]) FmtConfig[String]
96fn :: fmt format non sig top String [String] Int String FmtConfig[String]
97fn :: fmt is digit IntBool
98fn :: fmt is upper IntBool
99fn :: fmt is lower IntBool
100fn :: fmt is ident char IntBool
101fn :: fmt is keyword StringBool
102fn :: fmt is logic op StringBool
103fn :: fmt is bool lit StringBool
104fn :: fmt classify word String BoolString
105fn :: fmt escape html loop String Int Int StringString
106fn :: fmt escape html StringString
107fn :: fmt escape latex loop String Int Int StringString
108fn :: fmt escape latex StringString
109fn :: fmt escape rtf loop String Int Int StringString
110fn :: fmt escape rtf StringString
111fn :: fmt escape for target String FmtTargetString
112fn :: fmt cat css class StringString
113fn :: fmt cat ansi16 StringString
114fn :: fmt cat rgb String FmtThemeString
115fn :: fmt cat hex String FmtThemeString
116fn :: fmt cat is bold StringBool
117fn :: fmt cat rtf idx StringString
118fn :: fmt span css String StringString
119fn :: fmt span tty String StringString
120fn :: fmt span truecolor String String BoolString
121fn :: fmt span html inline String String BoolString
122fn :: fmt span pango String String BoolString
123fn :: fmt span latex String String BoolString
124fn :: fmt span rtf String String BoolString
125fn :: fmt render span String String FmtTarget FmtThemeString
126fn :: fmt scan ident end String Int IntInt
127fn :: fmt scan space end String Int IntInt
128fn :: fmt find close brace String Int IntInt
129fn :: fmt render nonempty String String FmtTarget FmtThemeString
130fn :: fmt highlight dquote brace String Int Int Int Int FmtTarget FmtTheme StringString
131fn :: fmt highlight dquote loop String Int Int Int FmtTarget FmtTheme StringString
132fn :: fmt multi op at String Int IntString
133fn :: fmt is single op IntBool
134fn :: fmt comment cat StringString
135fn :: fmt hl space step String Int Int Bool FmtTarget FmtTheme String IntString
136fn :: fmt hl dquote step String Int Int FmtTarget FmtTheme String IntString
137fn :: fmt hl squote step String Int Int FmtTarget FmtTheme String IntString
138fn :: fmt hl pragma step String Int Int FmtTarget FmtTheme String IntString
139fn :: fmt hl mop step String Int Int FmtTarget FmtTheme String StringString
140fn :: fmt hl ident step String Int Int Bool FmtTarget FmtTheme String IntString
141fn :: fmt highlight line loop String Int Int Bool FmtTarget FmtTheme StringString
142fn :: fmt line starts clause StringBool
143fn :: fmt map tok strs [FmtToken][String]
144fn :: fmt highlight line String FmtTarget FmtThemeString
145fn :: fmt highlight lines [String] FmtTarget FmtTheme[String]
146fn :: fmt join rtf lines [String]String
147fn :: fmt html pre open FmtThemeString
148fn :: fmt rtf colortbl FmtThemeString
149fn :: fmt wrap target doc [String] FmtTarget FmtThemeString
150fn :: fmt html stylesheet FmtThemeString
151fn :: fmt source with config String FmtConfigString
152fn :: format ridgun source StringString
153fn :: fmt to tty with theme String FmtThemeString
154fn :: fmt to tty StringString
155fn :: fmt to truecolor with theme String FmtThemeString
156fn :: fmt to truecolor StringString
157fn :: fmt to html with theme String FmtThemeString
158fn :: fmt to html StringString
159fn :: fmt to html css StringString
160fn :: fmt to markdown StringString
161fn :: fmt to pango with theme String FmtThemeString
162fn :: fmt to pango StringString
163fn :: fmt to latex with theme String FmtThemeString
164fn :: fmt to latex StringString
165fn :: fmt to rtf with theme String FmtThemeString
166fn :: fmt to rtf StringString

23.3. fmt sakonki esploratzen: Funtzionalitate bakoitzaren urratsez urratseko adibideak

Ez da nahikoa sinadura-taula ikustea: fmt lib-aren funtzionalitate bakoitza Ridgunen exekutagarriak diren adibide progresiboen bidez esploratuko dugu. Eguneroko bi errezeta taularatuekin hasiko gara eta ondoren xehetasunez ikusiko ditugu src/test/ridgun/test fmt.rg-en egiaztatutako agertoki funtzional eta muga-kasu guztiak.

23.3.1. 1. adibidea: Fluxu nagusia estilo taularatuan fmt erabiliz

Ikusi nola Ridgunen = ikurrak eta fmt bidezko eraldaketa-urratsak taula garbi bat bezala lerrokatuta geratzen diren, beharrezkoak ez diren aldagai aldakorrik edo ezkutuko albo-ondoriorik gabe:

import fmt

fn :: formatear y verificar String => String Bool
      formatear y verificar codigo =
        codigo fmt ridgun -> limpio
        limpio fmt check ridgun -> es_ok
        (limpio, es_ok)

23.3.2. 2. adibidea: Konposizio segurua eta muga-kasuen kudeaketa

fmt lib-eko funtzio oro | guarda boolearrekin eta ridgun-libs-eko gainerako 32 lib-ekin konposatzeko diseinatuta dago:

import fmt

fn :: exportar bloque html String => String
      exportar bloque html codigo =
        fmt highlight ridgun codigo FmtHtmlCss

23.3.3. 3. adibidea: => sinaduren, = klausulen, -> loturen eta -- iruzkinen lerrokatze taularatu kanonikoa (fmt ridgun, fmt ridgun with)

Adibide praktiko honetan fmt bloke funtzional honetan nola portatzen den sakonki aztertzen dugu, sarrera estandarrak, parametro-konbinazioak eta muga-balioak barne:

fn :: test fmt canonical alignment and config => ()
      test fmt canonical alignment and config =
        nl = char from code 10
        raw_src = "fn :: add Int Int => Int" + nl + "add x y = x + y" + nl + "add 0 y_long = y_long" + nl
        expected_2d = "fn :: add Int Int    => Int" + nl + "      add x   y      =  x + y" + nl + "      add 0   y_long =  y_long" + nl
        out_2d = format ridgun source raw_src
        assert str eq out_2d expected_2d "AC1: canonical 2D tabular alignment"

        -- Unaligned config (`is_aligned = False`) uses single-space separation
        cfg_unaligned = fmt config 2 4 80 False FmtPlain FmtThemeNone
        out_unaligned = fmt source with config raw_src cfg_unaligned
        expected_unaligned = "fn :: add Int Int => Int" + nl + "      add x y = x + y" + nl + "      add 0 y_long = y_long" + nl
        assert str eq out_unaligned expected_unaligned "AC1: unaligned FmtConfig"

        -- Guard and `where` alignment with custom indent_width = 4
        guard_src = "fn :: clamp Int => Int" + nl + "clamp x" + nl + "| x < 0 = 0" + nl + "| otherwise = x" + nl + "where" + nl + "lo -> 0" + nl
        cfg_ind4 = fmt config 4 4 80 True FmtPlain FmtThemeNone
        out_ind4 = fmt source with config guard_src cfg_ind4
        assert true (str contains out_ind4 "          | x < 0 = 0") "AC1: custom indent_width = 4 guard indentation"
        assert true (str contains out_ind4 "              lo -> 0") "AC1: custom indent_width = 4 where binding alignment"
        ()

23.3.4. 4. adibidea: 16 koloreko ANSI eta 24 biteko TrueColor nabarmendura lexikoa TTY eta NO_COLOR detekzio automatikoarekin

Adibide praktiko honetan fmt bloke funtzional honetan nola portatzen den sakonki aztertzen dugu, sarrera estandarrak, parametro-konbinazioak eta muga-balioak barne:

fn :: test fmt terminal highlighting tty and truecolor => ()
      test fmt terminal highlighting tty and truecolor =
        nl = char from code 10
        esc = char from code 27
        interp_tok = (char from code 123) + "name" + (char from code 125)
        sample = "-- @implements FR-FMT-001" + nl + "-- comment line" + nl + "fn :: greet String => String" + nl + "greet name = \"Hello " + interp_tok + "\" + (int_to_str 0x2A)" + nl

        tty_dark = fmt to tty sample
        assert true (str contains tty_dark (esc + "[1;32m-- @implements FR-FMT-001" + esc + "[0m")) "AC2: TTY pragma highlight"
        assert true (str contains tty_dark (esc + "[90m-- comment line" + esc + "[0m")) "AC2: TTY comment highlight"
        assert true (str contains tty_dark (esc + "[1;35mfn" + esc + "[0m")) "AC2: TTY keyword highlight"
        assert true (str contains tty_dark (esc + "[1;34mgreet" + esc + "[0m")) "AC2: TTY function name highlight"
        assert true (str contains tty_dark (esc + "[33mString" + esc + "[0m")) "AC2: TTY type highlight"
        assert true (str contains tty_dark (esc + "[36m" + interp_tok + esc + "[0m")) "AC2: TTY string interpolation highlight"
        assert true (str contains tty_dark (esc + "[36m0x2A" + esc + "[0m")) "AC2: TTY hex number highlight"

        tty_none = fmt to tty with theme sample FmtThemeNone
        assert false (str contains tty_none esc) "AC2: FmtThemeNone emits no ANSI escape codes"

        tc_dark = fmt to truecolor sample
        assert true (str contains tc_dark (esc + "[1;38;2;198;120;221mfn" + esc + "[0m")) "AC2: TrueColor dark keyword RGB"
        assert true (str contains tc_dark (esc + "[1;38;2;97;175;239mgreet" + esc + "[0m")) "AC2: TrueColor dark function RGB"

        tc_light = fmt to truecolor with theme sample FmtThemeLight
        assert true (str contains tc_light (esc + "[1;38;2;166;38;164mfn" + esc + "[0m")) "AC2: TrueColor light keyword RGB"
        ()

23.3.5. 5. adibidea: Nabarmendutako dokumentuen esportazioa HTML5 (<pre><code>), Pango Markup, LaTeX, RTF eta SVG bektorialera

Adibide praktiko honetan fmt bloke funtzional honetan nola portatzen den sakonki aztertzen dugu, sarrera estandarrak, parametro-konbinazioak eta muga-balioak barne:

fn :: test fmt enriched document targets => ()
      test fmt enriched document targets =
        nl = char from code 10
        src = "fn :: cmp Int Int => Bool" + nl + "cmp a b = a < b AND b > 0" + nl

        -- 1. Inline HTML
        html_out = fmt to html src
        assert true (str starts with html_out "<pre class=\"ridgun-code\"") "AC3: HTML inline wrapper"
        assert true (str contains html_out "<span style=\"color:#c678dd;font-weight:bold\">fn</span>") "AC3: HTML inline keyword span"
        assert true (str contains html_out "&lt;") "AC3: HTML escapes < operator"
        assert true (str contains html_out "&gt;") "AC3: HTML escapes > operator"

        -- 2. CSS-class HTML + Stylesheet
        css_html = fmt to html css src
        assert true (str contains css_html "<span class=\"rg-kw\">fn</span>") "AC3: HTML CSS keyword class"
        assert true (str contains css_html "<span class=\"rg-fn\">cmp</span>") "AC3: HTML CSS function class"
        assert true (str contains css_html "<span class=\"rg-type\">Int</span>") "AC3: HTML CSS type class"
        assert true (str contains css_html "<span class=\"rg-logic\">AND</span>") "AC3: HTML CSS logic operator class"
        sheet_dark = fmt html stylesheet FmtThemeDark
        sheet_light = fmt html stylesheet FmtThemeLight
        assert true (str contains sheet_dark ".rg-kw") "AC3: Dark CSS stylesheet"
        assert true (str contains sheet_light "#fafafa") "AC3: Light CSS stylesheet"

        -- 3. Markdown
        md_out = fmt to markdown src
        assert true (str starts with md_out ("

-- 4. Pango Markup pango_out = fmt to pango src _ = assert true (str starts with pango_out ("<tt>" + nl)) "AC3: Pango <tt> wrapper" _ = assert true (str contains pango_out "<span foreground="#c678dd" weight="bold">fn</span>") "AC3: Pango span markup"

-- 5. LaTeX Verbatim latex_out = fmt to latex src _ = assert true (str contains latex_out "Verbatim") "AC3: LaTeX Verbatim environment" _ = assert true (str contains latex_out "textcolor[HTML]") "AC3: LaTeX textcolor macro"

-- 6. RTF rtf_out = fmt to rtf src _ = assert true (str contains rtf_out "rtf1") "AC3: RTF header" _ = assert true (str contains rtf_out "colortbl") "AC3: RTF color table" _ = assert true (str contains rtf_out "\cf1\b fn") "AC3: RTF bold color span" ()


---

## 23.4. Kaputaren azpian: nola dagoen eraikia `fmt` Ridgun hutsean (`src/main/ridgun/lib/fmt.rg`)

`ridgun-libs`-en abantaila handienetako bat **C-ko kutxa beltzik ez egotea** da. `src/main/ridgun/lib/fmt.rg` ireki dezakezu eta eragiketa bakoitza *pattern matching*, `|` / `|.` guarda-zuhaitzak eta isats-errekurtsioa (TCO) erabiliz nola inplementatuta dagoen irakurri. Ikus ditzagun bere benetako inplementazioaren funtsezko piezak:

### 23.4.1. Barne-inplementazioa: Configuration Constructors

Ikusi nola `fmt.rg`-ek lehenik `fn :: ... => ...` sinadurak egituratzen dituen eta kasu bakoitza lerrokatutako ekuazioen eta isats-deien bidez ebazten duen:

module :: fmt

fn :: default fmt config => FmtConfig default fmt config = FmtConfig 2 4 80 True FmtPlain FmtThemeNone

fn :: fmt config Int Int Int Bool FmtTarget FmtTheme => FmtConfig fmt config indent_w max_params max_w aligned target theme = FmtConfig (fmt max 1 indent_w) (fmt max 0 max_params) (fmt max 20 max_w) aligned target theme


### 23.4.2. Barne-inplementazioa: Signature Parsing (`fn ::` / `op ::`)

Ikusi nola `fmt.rg`-ek lehenik `fn :: ... => ...` sinadurak egituratzen dituen eta kasu bakoitza lerrokatutako ekuazioen eta isats-deien bidez ebazten duen:

fn :: fmt split sig arrow [FmtToken] [String] => (Bool, [String], String, Int) fmt split sig arrow [] _ = (False, [], "", 0) fmt split sig arrow ((FmtTok tok col):rest) lhs_acc | tok == "=>" OR tok == "->" = (True, lhs_acc, tok, col) | otherwise = fmt split sig arrow rest (lhs_acc :: [tok])

fn :: fmt is sig type tok String => Bool fmt is sig type tok "" = False fmt is sig type tok tok = ch = str char at tok 0 (ch >= 65 AND ch <= 90) OR ch == 91 OR ch == 40

fn :: fmt all type toks [String] => Bool fmt all type toks [] = True fmt all type toks (t:rest) | fmt is sig type tok t = fmt all type toks rest | otherwise = False

fn :: fmt is bare fn lhs [String] => Bool fmt is bare fn lhs (first_w:rest) | NOT (fmt is sig type tok first_w) = fmt all type toks rest fmt is bare fn lhs _ = False

fn :: fmt infer bare kind [String] => String fmt infer bare kind lhs_strs | fmt is bare fn lhs lhs_strs = "bare_fn" | otherwise = "bare_op"

fn :: fmt parse sig line String => FmtSig fmt parse sig line line = clean = fmt strip comment line cmt = fmt extract comment line toks = fmt scan tokens clean fmt parse sig tokens (fmt leading indent line) clean cmt toks

fn :: fmt parse sig tokens Int String String [FmtToken] => FmtSig fmt parse sig tokens _ clean cmt ((FmtTok kind ):(FmtTok "::" ):rest) | kind == "fn" OR kind == "op" = fmt finish sig parse clean cmt kind (fmt split sig arrow rest []) fmt parse sig tokens 0 clean cmt ((FmtTok w col):rest) | w == "type" OR w == "expand" OR w == "import" OR w == "global" OR w == "context" OR w == "shared" OR w == "hardware" OR (str starts with w "@") OR (str starts with w "--") OR (str starts with w "|") = NoSig | otherwise = fmt finish bare sig parse clean cmt (fmt split sig arrow ([FmtTok w col] :: rest) []) fmt parse sig tokens _ _ _ _ = NoSig

fn :: fmt finish bare sig parse String String (Bool, [String], String, Int) => FmtSig fmt finish bare sig parse _ _ (False, , , ) = NoSig fmt finish bare sig parse _ (True, [], , ) = NoSig fmt finish bare sig parse clean cmt (True, lhs_strs, arrow_s, arrow_col) | arrow_s == "=>" = fmt finish sig parse clean cmt (fmt infer bare kind lhs_strs) (True, lhs_strs, arrow_s, arrow_col) | otherwise = NoSig


### 23.4.3. Barne-inplementazioa: Lexical Token Classification & Syntax Highlighting

Ikusi nola `fmt.rg`-ek lehenik `fn :: ... => ...` sinadurak egituratzen dituen eta kasu bakoitza lerrokatutako ekuazioen eta isats-deien bidez ebazten duen:

fn :: fmt is digit Int => Bool fmt is digit c = c >= 48 and c <= 57

fn :: fmt is upper Int => Bool fmt is upper c = c >= 65 and c <= 90

fn :: fmt is lower Int => Bool fmt is lower c = c >= 97 and c <= 122

fn :: fmt is ident char Int => Bool fmt is ident char c = (fmt is upper c) or (fmt is lower c) or (fmt is digit c) or c == 95

fn :: fmt is keyword String => Bool fmt is keyword w = w == "fn" or w == "op" or w == "type" or w == "expand" or w == "import" or w == "module" or w == "where" or w == "otherwise" or w == "with" or w == "do" or w == "mut" or w == "in" or w == "agent" or w == "send" or w == "to" or w == "receive" or w == "from" or w == "try" or w == "stop" or w == "timeout" or w == "global" or w == "context" or w == "shared" or w == "hardware" or w == "atomic" or w == "region" or w == "limit" or w == "map" or w == "filter" or w == "fold"

fn :: fmt is logic op String => Bool fmt is logic op w = w == "AND" or w == "OR" or w == "XOR" or w == "NOT" or w == "and" or w == "or" or w == "xor" or w == "not" or w == "shl" or w == "shr" or w == "rotr" or w == "rotl"

fn :: fmt is bool lit String => Bool fmt is bool lit w = w == "True" or w == "False"

fn :: fmt classify word String Bool => String fmt classify word "" _ = "plain" fmt classify word w in_fn = | fmt is keyword w = "keyword" | fmt is logic op w = "logic" | fmt is bool lit w = "bool" | fmt is upper (str char at w 0) = "type" | fmt is digit (str char at w 0) = "number" | in_fn = "function" | otherwise = "plain"


### 23.4.4. Barne-inplementazioa: Public Entry Points

Ikusi nola `fmt.rg`-ek lehenik `fn :: ... => ...` sinadurak egituratzen dituen eta kasu bakoitza lerrokatutako ekuazioen eta isats-deien bidez ebazten duen:

fn :: fmt source with config String FmtConfig => String fmt source with config src cfg = src fmt split raw lines -> raw_lines fmt format top lines raw_lines 0 "" cfg -> formatted_lines cfg target_format -> target cfg color_theme -> theme fmt highlight lines formatted_lines target theme -> highlighted fmt wrap target doc highlighted target theme

fn :: format ridgun source String => String format ridgun source src = fmt source with config src (default fmt config)

fn :: fmt to tty with theme String FmtTheme => String fmt to tty with theme src theme = fmt source with config src (FmtConfig 2 4 80 True FmtTty theme)

fn :: fmt to tty String => String fmt to tty src = fmt to tty with theme src FmtThemeDark

fn :: fmt to truecolor with theme String FmtTheme => String fmt to truecolor with theme src theme = fmt source with config src (FmtConfig 2 4 80 True FmtTrueColor theme)

fn :: fmt to truecolor String => String fmt to truecolor src = fmt to truecolor with theme src FmtThemeDark

fn :: fmt to html with theme String FmtTheme => String fmt to html with theme src theme = fmt source with config src (FmtConfig 2 4 80 True FmtHtmlInline theme)

fn :: fmt to html String => String fmt to html src = fmt to html with theme src FmtThemeDark

fn :: fmt to html css String => String fmt to html css src = fmt source with config src (FmtConfig 2 4 80 True FmtHtmlCss FmtThemeDark)

fn :: fmt to markdown String => String fmt to markdown src = fmt source with config src (FmtConfig 2 4 80 True FmtMarkdown FmtThemeNone)

fn :: fmt to pango with theme String FmtTheme => String fmt to pango with theme src theme = fmt source with config src (FmtConfig 2 4 80 True FmtPango theme)

fn :: fmt to pango String => String fmt to pango src = fmt to pango with theme src FmtThemeDark

fn :: fmt to latex with theme String FmtTheme => String fmt to latex with theme src theme = fmt source with config src (FmtConfig 2 4 80 True FmtLatex theme)

fn :: fmt to latex String => String fmt to latex src = fmt to latex with theme src FmtThemeDark

fn :: fmt to rtf with theme String FmtTheme => String fmt to rtf with theme src theme = fmt source with config src (FmtConfig 2 4 80 True FmtRtf theme)

fn :: fmt to rtf String => String fmt to rtf src = fmt to rtf with theme src FmtThemeDark


---

## 23.5. Berme algoritmikoak, `RMM1`/`RMM2` memoria eta `fmt`-en Urrezko 5 Arauak

- **Berme algoritmikoa eta segurtasunekoa**: Idempotentzia zorrotza (`fmt source (fmt source s) == fmt source s`) eta token semantikoen % 100eko kontserbazioa.
- **$O(1)$ pila-konplexutasuna TCOrekin**: `src/main/ridgun/lib/fmt.rg`-eko begizta errekurtsibo guztiak isats-posizioan daude; beraz, `ridgunc`-ek pila-hazkuntzarik gabeko jauzi natiboetara konpilatzen ditu.
- **Memoria determinista (`RMM1`/`RMM2`)**: Zero zabor-biltzaile etenaldi; tarteko egitura guztiak modu deterministan askatzen dira esparrutik irtetean.
- **Etengabeko egiaztapena**: Zorrotz probatua `stable check` eta `src/test/ridgun/test fmt.rg` suite automatizatuaren bidez.

### `fmt`-ekin programatzeko Urrezko 5 Arauak

1. **Deklaratu `import fmt` fitxategiaren hasieran** eta baliatu zuriuneen eta azpimarren arteko baliokidetasuna zure kodea prosa bezala irakur dadin.
2. **Lerrokatu zure datu-hodiak `=` ikurrarekin**: kateatu `fmt`-erako deiak izen propioko urratsetan eta utzi `stable format`-i zutabeak lerrokatzen.
3. **Baliatu `fmt`-eko funtzio osoak zure `|` guardetan**: egiaztatu itzulera-balioak edo askatu ADTak *pattern matching* bidez, kanpoko sarrera beti baliozkoa dela suposatu beharrean.
4. **Saihestu egitura handiak kopiatzea eremu bat kontsultatu besterik behar ez baduzu**: gogoratu `RMM2`-n sarrerako argumentuek ez dituztela kontagailuak handitzen edo txikitzen (`+0` / `-0`).
5. **Konbinatu `fmt` eta `test` (`import test`)**: idatzi beti asertzioak `assert equals` edo `assert true` erabiliz zure domeinuaren inbarianteak finkatzeko.

---

**24. kapituluan** **`cli`** lib-a sakonki esploratuko dugu (`cli` lib-a — Banderak, Aukerak, `--` Hesia, Azpikomandoak eta Ingurune-aldagaiak).