macro librarylibs/Csv/src/Csv.xtlm

Csv: its macro library -- c_olumns<, a table's columns as named, typed variables. Imported with the functions, under one alias: "cs:" u_se< "Csv". A macro is a function from the source text written left and right of its call to the source that replaces the call, run before the program is compiled (X_eTaL MC10). Names with m: are macros; those under h: are private to this file.

source · imports t: libs/Strings/src/Strings.xtl

lowers : Char

value (private) · line 11
lowers ← "abcdefghijklmnopqrstuvwxyz"
Used in: letters, ʰn̲ame?

letters : Char

value (private) · line 12
letters ← lowers c̲at ⎕A c̲at ⎕D
Used in: ʰn̲ame?

Parsing

ʰn̲ame? : Truthy a => Char -> a

function (private) · line 17

Whether a text can be a variable's name.

ʰn̲ame? ← { n → (0 < t̲ally n) ∧ ((f̲irst n) m̲ember? lowers) ∧ '∧ r̲/ n m̲ember? letters }

ʰc̲ut : Char -> Int

function (private) · line 20

A column's name and kind, from "name:kind".

ʰc̲ut ← { c → (f̲irst w̲here c = f̲irst ":") − 1 }

ʰc̲olName : Char -> Char

function (private) · line 21
ʰc̲olName ← { c → (ʰc̲ut c) t̲ake c }

ʰc̲olKind : Char -> Char

function (private) · line 22
ʰc̲olKind ← { c → (1 + ʰc̲ut c) d̲rop c }

ʰc̲olumn? : Truthy a => Char -> a

function (private) · line 25

Whether a column is "name:text" or "name:number".

ʰc̲olumn? ← { c →
  1 ≠ t̲ally w̲here c = f̲irst ":" ? 0 = 1
  (ʰn̲ame? ʰc̲olName c) ∧ ("text" m̲atch ʰc̲olKind c) ∨ "number" m̲atch ʰc̲olKind c
}
Used in: ᵐc̲olumns<

ʰc̲ode : Char -> Char -> Char

function (private) · line 32

The code for one column of table tb: its texts, found by header, the header left out; numbers read from them when the kind is number.

ʰc̲ode ← { tb c →
  n ← ʰc̲olName c
  texts ← "(1 d_rop ((f_irst " c̲at tb c̲at ") i_ndexOf e_nclose \"" c̲at n c̲at "\") s_elect_2 " c̲at tb c̲at ")"
  "text" m̲atch ʰc̲olKind c ? n c̲at " := " c̲at texts
  n c̲at " := n_umbers d_isclose '{ e_nclose (d_isclose _l) c_at \" \" c_at d_isclose _r } r_/ " c̲at texts
}
Used in: ᵐc̲olumns<

The macro

ᵐc̲olumns< : Char -> Char -> Char

macro · line 51

"city:text population:number" cs:c_olumns< "t": the columns of table t (a table as cs:r_ows gives it, its first row the header) as variables named after them: city the texts of column "city", population its numbers (Floats). When the program is compiled the schema is checked and a definition written per column, so the rest of the program uses the columns by name and their kinds are type-checked like any variable (population c_at "x" is a type error). A malformed schema or table name stops the compiler: error[bad-columns]. Columns are found by their header when the program runs.

ᵐc̲olumns< ← { schema tb →
  cs ← ᵗw̲ords schema
  0 = t̲ally cs ? "bad-columns left" ⎕R̲EJECT "no columns: write name:text or name:number"
  bad ← (n̲ot '{ ʰc̲olumn? d̲isclose ⍵ } e̲ach cs) r̲eplicate cs
  0 < t̲ally bad ? "bad-columns left" ⎕R̲EJECT (d̲isclose f̲irst bad) c̲at " is not a column: write name:text or name:number (a lowercase name)"
  n̲ot ʰn̲ame? ᵗt̲rim tb ? "bad-columns right" ⎕R̲EJECT tb c̲at " is not a table's name"
  "\n" ᵗj̲oin '{ c → (ᵗt̲rim tb) ʰc̲ode d̲isclose c } m̲ap cs
}
Used in: city