[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