[m-users.] Initialising a map with static data

Dirk Ziegemeyer dirk at ziegemeyer.de
Wed Jan 26 01:23:08 AEDT 2022


Sean,

> Am 25.01.2022 um 11:39 schrieb Sean Charles (emacstheviking) <objitsu at gmail.com>:
> 
> I considered that too! Ironically I have my own parser that specifically handles the FELT language construct so I could enter it as a static string and run it through the parser and assimilate it that way, as the REPL does oddly enough!
> 
> Here is the file I used from the repl to set up the C runtime, well, until last night.
> 
> FELT > tmap @ctypes.ini
> 
> (#f:typemap
>         :VARIABLES {
>             ('argc'   "int")
>             ('argv'   "char**")
>             main        int
>             (filename psz)
>         }
>         :Types {
>             "int"         i             ; implicit in C
>             "int"         i             ; implicit in C
>             "float"       f
>             "double"      d
>             "char"        [ c ch chr ]  ; ditto
>             "const char*" psz           ; ditto
>             "char**"      ppc
>             :int [j k l m n i]
>         }
> )
> 
> So I could make that a string and compile it but it felt somehow inefficient when I know I could statically init maps instead…who know…I may change my mind on this one but dynamically parsing and loading a string didn’t ‘feel right’ but I might change my mind, as I have said.

There is another option in case you decide to read the data at runtime from file: io.read

Example:

Create a file "my_defs.m" with this content:

my_type("i"    - "int").
my_type("psz"  - "char*").
my_type("v"    - "void").
my_type("pv"   - "void*").
my_type("c"    - "char").
my_type("sc"   - "signed char").
my_type("uc"   - "unsigned char").
my_type("pc"   - "char*").
my_type("ppc"  - "char**").
my_type("cpc"  - "const char*").
my_type("cppc" - "const char**").

my_var("argc" - "int").
my_var("argv" - "ppc").


Use this code to read the file "my_defs.m" at runtime:

:- type my_defs
    --->    my_type(pair(string, string))
    ;       my_var(pair(string, string)).


:- pred read_terms(map(string, string)::out, map(string, string)::out,
    io::di, io::uo) is det.

read_terms(Types, Vars, !IO) :-
    io.open_input("my_defs.m", Result, !IO),
    (
        Result = io.ok(Stream),
        read_terms_until_eof(Stream, map.init, Types, map.init, Vars, !IO),
        io.close_input(Stream, !IO)
    ;
        Result = io.error(Error),
        require.error(Error)
    ).


:- pred read_terms_until_eof(io.input_stream::in,
    map(string, string)::in, map(string, string)::out,
    map(string, string)::in, map(string, string)::out,
    io::di, io::uo) is det.

read_terms_until_eof(Stream, !Types, !Vars, !IO) :-
    io.read(Stream, Result, !IO),
    (
        Result = io.ok(Term),
        (
            Term = my_type(Key - Value),
            map.det_insert(Key, Value, !Types)
        ;
            Term = my_var(Key - Value),
            map.det_insert(Key, Value, !Vars)
        )
        read_terms_until_eof(Stream, !Types, !Vars, !IO)
    ;
        Result = io.eof
    ;
        Result = io.error(Msg, LineNumber),
        require.error(string.format("error in line %i: %s",
            [i(LineNumber), s(Msg)]))
    ).

Dirk.


More information about the users mailing list