Menu

Mentoring chats?

2020-07-05
2020-08-01
  • Brian Tiffin

    Brian Tiffin - 2020-07-05

    Not meaning to pester, Daniel, but also keen and at the bottom of the XPL learning curve.

    Are you up for a few beginner questions here in your discussion forum?

    As a for instance, how would an XPL guru go about defining uppercase(str) and lowercase(str) procedures, given that the code should be EBCDIC and ASCII agnostic, changing the str in place.

    I've tried a few things like byte(str, pos) = byte(map, j) on the left hand side of an assignment, but all I seem to get, is more confused. :-)

    Another; in the conversion section, CHARACTER -> Integer is illegal. How about a simple convert of '1' to 1? More to the point, not using compile time literal syntax, but from substr or indexing.

    n = substr('1234', 1, 1);
    

    Don't want the character code for '2', value, but a numeric 2, computed at runtime. Again, ASCII EBCDIC agnostic if possible. More than willing to scan tables of suitable digits depending on base.

    If you don't feel like being a first level XPL student tech support question answerer here, Daniel, then that'll be ok. ;-)

    Plan is to fill out some Rosetta Code entries for XPL, and I like to start with some Simple Tasks to get over the new to XPL hump. Things like the Sum digits of an integer (in a given base) task. I'd like the solution to cover more than just the bit-string default types and conversions built into XPL. From 2 to say base-36.

    Oh, and just in case you don't mind the simple minded starter questions. One last one (for now). Is there an idiom for terminating a counted loop early? For example, looking to see if a character is in a map, leave when found, in a do loop counting across the length of the map. Is it simply what I think it is, a DO WHILE with & and | logical operators in the expression and explicit counting in the loop?

    Again, an answer of 'go read...' will be ok, Daniel. This is all currently for fun. If things work out, the goal will be a demo of an XPL to C generated DSL, embedded in COBOL. For now, simply for the joy of the pursuit.

    Have good, make well,
    Blue

     
  • Daniel Weaver

    Daniel Weaver - 2020-07-30
    /* lower to UPPER case conversion */
    
    declare map(255) bit(8);
    
    declare shift character initial (
    'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
    
    initialization:
       procedure;
          declare (i, j) fixed;
    
          do i = 0 to 255;
             map(i) = i;
          end;
          do i = 0 to 25; 
             j = byte(shift, i + 26);
             map(byte(shift, i)) = j;
          end;
       end initialization;
    
    uppercase:
       procedure(s) character;
          declare s character,
             i fixed;
    
          s = unique(s);
          do i = 0 to length(s) - 1;
             byte(s, i) = map(byte(s, i));
          end;
          return s;
       end uppercase;
    
    main:
       procedure;
          output = 'abc...xyz->' || uppercase('abc...xyz');
       end main;
    
    call initialization;
    call main;
    
    eof;
    
     

    Last edit: Daniel Weaver 2020-07-31
    • Brian Tiffin

      Brian Tiffin - 2020-07-31

      Nice. Thanks, Daniel.

      Works the charm.

      Did have to fix the /* */ comments in the first line. SourceForge markup ate the asterisks for italics. Not a biggy, and on par for SourceForge markdown expectations. :-)

      Have good, make well,
      Blue

       
  • Daniel Weaver

    Daniel Weaver - 2020-07-30

    The lack of a BREAK statement in XPL is a problem. There are a few ways to work around this problem. Here are some suggestions:

    looping = 1;
       do while looping;
             if some_end_condition then looping = 0;
             /* do more stuff */
       end;
    
    /* In XPL the upper limit is not recalculated */
    /* This will not work */
    x = 100;
     do i = 0 to x;
        if some_end_condition then x = 0;
        /* ... */
     end;
    
     /* But you can change the index variable */
     x = 100;
        do i = 0 to x;
           if some_end_condition then i = 256;
           /* ... */
        end;
    
     /* You can also use the goto statement */
        do i = 0 to 100;
              if some_end_condition then goto exit_label;
              /* ... */
        end;
        exit_label:  /* Loop escape */
    
    /* At times I will put the loop into a seperate procedure */
    search:
       procedure;
             do i = 0 to 100;
                  if some_end_condition then return;
             end;
        end search;
    

    Dan

     

    Last edit: Daniel Weaver 2020-08-01
    • Brian Tiffin

      Brian Tiffin - 2020-07-31

      Thanks again.

      I spent about a year back in the early 80's under a mentor who was the "structured programming, or no programming" type. Thinking back, he may have been from Denmark and loyal to the likes of Dijkstra. <joking></joking> It was good training in goto-less at all costs programming. :-)

      I'll post more starter questions if/when I put up the Rosetta Code XPL page and some of the simple tasks.

      Edit: adding a listing

      Didn't have time last night to dig up the first day coding attempt, just so you know I'm appreciative of the response and the time you spent porting XPL, Daniel. Feel free to critique and/or point out sloppy, insecure. undefined behaviour, or outright obvious misunderstandings on my part. ;-)

      /* Sum digits of an integer, in a given base */
      sumdigi: procedure(num, base) fixed;
        declare num fixed, base fixed;
        declare display character;
        display = num;
      
        declare i fixed, digit bit(8), total fixed;
        total = 0;
        do i = 0 to length(display) - 1 by 1;
          digit = byte(display, i);
          total = total + digit - byte('0');
        end;
        output = 'num: ' || num || ' digit-sum: ' || total;
      
        /* Needs numeric base support ... */
      end sumdigi;
      
      /* Uppercase */
      uppercase: procedure(letters) character;
        declare (letters, letter, newletters) character;
        declare (i, j, found) fixed;
        declare uppers character initial('ABCDEFGHIJKLMNOPQRSTUVWXYZ');
        declare lowers character initial('abcdefghijklmnopqrstuvwxyz');
        newletters = letters;
        do i = 0 to length(newletters) by 1;
          letter = substr(newletters, i, 1);
          j = 0;
          found = 0;
          do while j < length(lowers) & found = 0;
            if byte(letter) = byte(lowers, j) then do;
              byte(newletters, i) = byte(uppers, j);
              found = 1;
            end;
            j = j + 1;
          end;
        end;
        return newletters;
      end uppercase;
      
      /* Default main */
      call sumdigi(1, 10);
      call sumdigi(12, 10);
      call sumdigi(123, 10);
      call sumdigi(1234, 10);
      //call sumdigi("(4)ABC", 16);
      
      declare trial character initial('abcdeFGH012');
      output = 'uppercase(' || trial || ')';
      output = uppercase(trial);
      eof
      

      Cheers,
      Blue

       

      Last edit: Brian Tiffin 2020-07-31
  • Daniel Weaver

    Daniel Weaver - 2020-08-01

    The line:

     total = total + digit - byte('0');
    

    Should read:

     total = total * base + digit - byte('0');
    

    This should work for any base from 2 to 10.

    In my example the function UNIQUE makes a copy of the string so that the uppercase function does not corrupt other strings.
    For Example:

    base_data = 'abcdef';
    new_stuff = uppercase(substr(base_data, 1, 3));
    /* Should not corrupt the value of the string "base_data " */

    It's easy to get a unique copy of a string. You move it to the top of the free string area.
    Example:

    new_string = substr('?' || old_string, 1);

     

    Last edit: Daniel Weaver 2020-08-01
    • Brian Tiffin

      Brian Tiffin - 2020-08-01

      :-)

      When I get comfortable enough to make the XPL language page on Rosetta, your routine will be put to use for case conversion, not the first day student copy listed above.

      I was about to pester about learning the ins and outs of references vs copies. REBOL programming seems a little similar in that area. When to leverage the efficiencies of references and when new copies need to be made. Thanks for the hint.

      Getting over the first few hurldes, will add base handling to the sum-digits task sample. Secondary goal after that baby step will be trying to get the same XPL sources compiled and running on MVS 3.8j and with your XPL to C compiler.

      Have good. make well,
      Blue

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.