[m-users.] String comparison when compiling to C

Richard O'Keefe raoknz at gmail.com
Sat Aug 24 18:35:09 AEST 2024


What else would one be doing?  Earning a living, perhaps (:-).
I'm slowly building a reconstruction of the classic British AI
programming language Pop-2.
Something it shares with Forth and PostScript is a visible stack, and
the range of data types
is roughly similar to PostScript or Scheme.
One curiosity of all three languages is that although they have no
static type checking,
the official descriptions all use an *informal* type system for built-ins.
(For Forth, start at section 2.2.2 of
https://forth-standard.org/standard/notation ).
It took a lot of effort to figure out a "descriptively adequate" type
system for Pop-2,
and a lot of working functions wouldn't pass it, but it has proven an
AMAZING help in
design. Which is of course no surprise to Mercury users.

Given that background, I will be *fascinated* to see what a strongly
typed Forth looks like.

On Sat, 24 Aug 2024 at 18:19, Sean Charles (emacstheviking)
<objitsu at gmail.com> wrote:
>
> Hi Richard,
>
> All sorted thanks, I already had `string` imported. I think working with Python has dulled my brain sometimes.
> The Mercury `way` is a much better fit for how I intend to work it going forward, I am writing a strongly typed FORTH with Mercury as a rapid application tool for another project.
>
> I have this code now, so far, but eventually I plan to support all the Mercury numerical types, different bases etc as FORTH allows, it won't be a strict standards compliant FORTH but rather, my interpretation of it guided by Mercury...
>
> %
> % Comparison operators.
> %
> core("<",           stack('<')).
>
> :- pred '<'(opstate::in, opstate::out, dstk::in, dstk::out) is det.
>     % [ V2, V1 ] <=> ( n1 n2 -- flag ) ie TOS is n2, is V1, global rule!
> '<'(!Mode, !Stk) :-
>     ( if [ V2, V1 | Rest ] = !.Stk then
>         !:Stk = Rest,
>         ( if V1 = int(N1), V2 = int(N2) then
>             ( if compare(<, N1, N2)
>             then push_true(!Mode, !Stk)
>             else push_false(!Mode, !Stk)
>             )
>         else if V1 = str(S1), V2 = str(S2) then
>             trace [io(!IO)] (
>                 io.format("> %s %s\n", [s(string(V1)),s(string(V2))],!IO)
>             ),
>             ( if compare(<, S1, S2)
>             then push_true(!Mode, !Stk)
>             else push_false(!Mode, !Stk)
>             )
>         else
>             seterr("> requires two objects of the same type.", !Mode)
>         )
>     else stkerr(">", 2, !.Stk, !Mode)).
>
> Once all the types I want are in the above code, then I will find a way to reduce the code, `compare/3` is great in that respect as it is a uniform interface across types.
>
> I hope to find a way to generalise the call to `compare/3`, I will experiment!!! As much as Mercury sometimes makes my head want to explode at times, I can't help thinking that if the worldf at large used it, the world might be a better place, well, at least less global tech issues, e.g. Crowdstrike.
>
> It's a bunch of fun so far at times (sarcasm emoji) but what else would one be doing?
>
> Thanks again,
> Sean.
>
>
> On 24 Aug 2024, at 06:56, Richard O'Keefe <raoknz at gmail.com> wrote:
>
> Does
> :- import_module string.
> ...
>    compare(>, S1, S2)
>
> work for you?
>
> On Sat, 24 Aug 2024 at 02:53, Sean Charles (emacstheviking)
> <objitsu at gmail.com> wrote:
>
>
>
> % The builtin comparison operation on strings is also implementation
> % dependent. The current implementation performs string comparison using
> %
> % - C's strcmp() function, when compiling to C;
>
> Guided by the text, "The builtin comparison operation on strings "... I assumed that >, <, >= etc would work fork string types but my code:
>
>    615 op_greater_than(!Mode, !Stk) :-
>    616     ( if [ V1, V2 | Rest ] = !.Stk then
>    617         !:Stk = Rest,
>    618
>    619         ( if V1 = int(N1), V2 = int(N2) then
>    620             trace [io(!IO)] (
>    621                 io.format("> %s %s\n", [s(string(V1)),s(string(V2))],!IO)
>    622             ),
>    623             ( if N1 > N2
>    624             then push_true(!Mode, !Stk)
>    625             else push_false(!Mode, !Stk)
>    626             )
>    627
>    628         else if V1 = str(S1), V2 = str(S2) then
>    629             trace [io(!IO)] (
>    630                 io.format("> %s %s\n", [s(string(V1)),s(string(V2))],!IO)
>    631             ),
>    632             ( if S1 > S2
>    633             then push_true(!Mode, !Stk)
>    634             else push_false(!Mode, !Stk)
>    635             )
>    636         else
>    637             seterr("> requires two objects of the same type.", !Mode)
>
> gets these errors:
>
> dstack.m:632: In clause for predicate `op_greater_than'/4:
> dstack.m:632:   in call to predicate `int.>'/2:
> dstack.m:632:   in argument 1:
> dstack.m:632:     variable `S1' has type
> dstack.m:632:       string,
> dstack.m:632:     expected type was
> dstack.m:632:       int;
> dstack.m:632:   in argument 2:
> dstack.m:632:     variable `S2' has type
> dstack.m:632:       string,
> dstack.m:632:     expected type was
> dstack.m:632:       int.
>
>
> So what is the 'way' to do string comparisons? I find it odd in all the code I've written, I have never needed to do this before!
>
> Thanks,
> Sean.
>
> _______________________________________________
> users mailing list
> users at lists.mercurylang.org
> https://lists.mercurylang.org/listinfo/users
>
>


More information about the users mailing list