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

Sean Charles (emacstheviking) objitsu at gmail.com
Tue Jan 25 21:39:55 AEDT 2022


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.

Sean.



> On 25 Jan 2022, at 10:33, Fabrice Nicol <fabrnicol at gmail.com> wrote:
> 
> Sean, 
> 
> your preferred style of input looks json-like. In this case, as there is no language-internal construct to directly parse this, you should perhaps take a look at Julien's json library (https://github.com/juliensf/mercury-json <https://github.com/juliensf/mercury-json>). This means that your data should be imported from file and not hard-coded. Beyond a certain load, this is good practice anyhow in almost all languages I know of, with standard Prolog a possible and controversial exception.
> 
> Fabrice
> 
> Le 25/01/2022 à 09:18, Sean Charles (emacstheviking) a écrit :
>> I actually did try that way but I didn’t like it, I wanted something that more accurately —read— as it was to be if that makes sense… also I guess it was influnced by the fact it’s being ported from SWI| Prolog code I wrote before I realised Mercury was The Way.
>>  
>> The actual SWI code is this, and I wanted it to be as visually close as possible henc eusing pair() worked for me but I wondered if there was an alternative.
>> 
>> Thanks Fabrice.
>> Sean
>> 
>> 
>> 
>> type_dict(
>>     _{ names:
>>        _{
>>            main: "i", % TODO: invert: i: [main, argc] ?!?!?
>>            argc: "i",
>>            argv: "ppc"
>>            %i: [i,j,k,n,x,y,z],
>>            % c: [c, chr] %TODO: SHOULD I DO THIS???
>>            % TODO: Provide a means to UNDO some defaults eg specify
>>            % an empty replacement as a signal to remove key
>>        },
>>        types:
>>        _{
>>            v:    "void",
>>            pv:   "void*",
>> 
>>            c:    "char",
>>            sc:   "signed char",
>>            uc:   "unsigned char",
>>            pc:   "char*",
>>            ppc:  "char**",
>>            cpc:  "const char*",
>>            cppc:  "const char**",
>> 
>>            sh:   "short",
>>            shi:  "short int",
>>            ssh:  "signed short",
>>            sshi: "signed short int",
>> 
>>            us:   "unsigned short",
>>            ushi: "unsigned short int",
>> 
>>            i:    "int",
>>            s:    "signed",
>>            si:   "signed int",
>> 
>>            u:    "unsigned",
>>            ui:   "unsigned int",
>> 
>>            l:    "long",
>>            li:   "long int",
>>            sl:   "signed long",
>>            sli:  "signed long int",
>> 
>>            ul:   "unsigned long",
>>            uli:  "unsigned long int",
>> 
>>            ll:   "long long",
>>            lli:  "long long int",
>>            sll:  "signed long long",
>>            slli: "signed long long int",
>> 
>>            ull:  "unsigned long long",
>>            ulli: "unsigned longlong int",
>> 
>>            f:    "float",
>>            d:    "double",
>>            ld:   "long double",
>> 
>>            b:    "_Bool", % TODO: "auto-include" stdbool.h ?!?!?
>>            '?':  "_Bool",
>> 
>>            % some extra ones that I find I use all the time
>> 
>>            fi:  "FILE",
>>            pfi: "FILE*"
>>        },
>>        defaults:
>>        _{
>>            variable: "i",
>>            function: "v"
>>        },
>>        %% maps supported types to printf() format specifier for EMIT
>>        printf:
>>        _{
>>            'void*': "%p",
>>            'char': "%c",
>>            'signed char': "%c",
>>            'unsigned char': "%uc",
>>            'char*': "%s",
>>            'char**': "%p",
>>            'const char*': "%s",
>>            'const char**': "%p",
>>            'short': "%i",
>>            'short int': "%i",
>>            'signed short': "%i",
>>            'signed short int': "%ui",
>>            'unsigned short': "%ui",
>>            'unsigned short int': "%ui",
>>            'int': "%i",
>>            'signed': "%i",
>>            'signed int': "%i",
>>            'unsigned': "%ui",
>>            'unsigned int': "%ui",
>>            'long': "%li",
>>            'long int': "%li",
>>            'signed long': "%li",
>>            'signed long int': "%li",
>>            'unsigned long': "%ul",
>>            'unsigned long int': "%ul",
>>            'long long': "%lli",
>>            'long long int': "%lli",
>>            'signed long long': "%lli",
>>            'signed long long int': "%lli",
>>            'unsigned long long': "%llu",
>>            'unsigned long long int': "%llu",
>>            'float': "%g",
>>            'double': "%g",
>>            'long double': "%Lg",
>>            '_Bool': "%i",
>>            'FILE*': "%p"
>>            }
>>      }
>> ).
>> 
>> 
>> 
>> 
>> 
>> 
>>> On 25 Jan 2022, at 00:27, Fabrice Nicol <fabrnicol at gmail.com <mailto:fabrnicol at gmail.com>> wrote:
>>> 
>>> Below is an alternative, which has pros and cons. 
>>> 
>>> A bit more concise, but you have to align the data carefully to avoid input errors.
>>> 
>>> Or, if you have lots of data, you can write a database in a file, and parse (use the GH csv library for example).
>>> 
>>> %%
>>> 
>>> :-module map_test.
>>> :-interface.
>>> :-import_module io.
>>> :-import_module map.
>>> :-import_module string.
>>> :-pred create_maps(map(string, string), map(string, string)).
>>> :-mode create_maps(out, out) is det.
>>> 
>>> :-pred main(io::di, io::uo) is det.
>>> 
>>> :-implementation.
>>> 
>>> :-import_module list.
>>> 
>>> %% create
>>> 
>>> create_maps(Types, Vars) :-
>>>     K1 = ["i",       "psz",         "    v",            "pv",
>>>              "c",       "sc",               "uc",           "pc",
>>>              "ppc",    "cpc",             "cppc"],
>>>     V1 = ["int",     "char*",           "void",       "void*",
>>>             "char",   "signed char", "unsigned char", "char*",
>>>             "char**", "const char*", "const char**"],
>>>     K2 = ["argc",   "argv"],
>>>     V2 = ["int",    "ppc"],
>>>     det_insert_from_corresponding_lists(K1, V1, map.init, Types),
>>>     det_insert_from_corresponding_lists(K2, V2, map.init, Vars).
>>> 
>>> %% test
>>> 
>>> main(!IO) :- create_maps(Types, Vars),
>>>     write_string(Types^det_elem("cpc"), !IO),
>>>     nl(!IO),
>>>     write_string(Vars^det_elem("argc"), !IO),
>>>     nl(!IO).
>>> 
>>> :-end_module
>>> 
>>> %%
>>> 
>>> $ ./map_test
>>> 
>>> const char*
>>> int
>>> 
>>> %%
>>> 
>>> Fabrice
>>> 
>>> 
>>> 
>>>> Is there a more concise way of creating a map full of static data? The best I have obtained is this:
>>>> 
>>>> default_typemap = Out :-
>>>>     map.from_assoc_list([
>>>>         ("i"    - "int"),
>>>>         ("psz"  - "char*"),
>>>>         ("v"    - "void"),
>>>>         ("pv"   - "void*"),
>>>>         ("c"    - "char"),
>>>>         ("sc"   - "signed char"),
>>>>         ("uc"   - "unsigned char"),
>>>>         ("pc"   - "char*"),
>>>>         ("ppc"  - "char**"),
>>>>         ("cpc"  - "const char*"),
>>>>         ("cppc" - "const char**")
>>>>     ],
>>>>     Types),
>>>>     map.from_assoc_list([
>>>>         ("argc" - "int"),
>>>>         ("argv" - "ppc")
>>>>     ],
>>>>     Vars),
>>>> :
>>>> : .. more code..
>>>> :
>>>> 
>>>> Each backend coder that is a for typed language will be providing an initial lookup of both variables and types so it can infer necessary typing at code render time.
>>>> 
>>>> Thanks,
>>>> Sean
>>>> 
>>>> 
>>>> 
>>>> _______________________________________________
>>>> users mailing list
>>>> users at lists.mercurylang.org <mailto:users at lists.mercurylang.org>
>>>> https://lists.mercurylang.org/listinfo/users <https://lists.mercurylang.org/listinfo/users>
>> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20220125/53c38f16/attachment-0001.html>


More information about the users mailing list