Evening

I'm seeing a weird effect when concatenting things:
WITH q(tape,dp) AS (SELECT '04E', 1)
  SELECT SUBSTR(tape,1,dp-1) || SUBSTR(tape,dp,1)+1 || SUBSTR(tape,dp+1) AS 
expect_14E,
         SUBSTR(tape,1,dp-1) AS segment_1,
         SUBSTR(tape,dp,1)+1 AS segment_2,
         SUBSTR(tape,dp+1) AS segment_3
    FROM q;

expect_14E  segment_1   segment_2   segment_3 
----------  ----------  ----------  ----------
14                      1           4E        

As the name of the column implies... I'm expecting '14E' from that
concatenation, it instead seems to be dropping the last character.

I originally found this in sqlite3 3.19.3 as distributed in 64-bit ubuntu
17.10; on that same system, I get the same effect in the amalgamation
3.22.0, compiled just now, thus:

sqlite-amalgamation-3220000$ gcc -o sqlite3 sqlite3.c shell.c -ldl -lpthread

For entertainment purposes only, I discovered this while trying to
implement a BF interpreter using CTEs, pasted below.

Have a good evening,
Gary


WITH RECURSIVE
  program AS (SELECT '+++.,>++++.,<<++++++.,' AS p, 'HELLO' AS input),
  jumpdepth AS (SELECT 0 AS idx, 0 AS jumpdepth, '' AS jumplist, NULL as 
jumpback, NULL AS direction, p || '0' AS p FROM program
          UNION ALL
        SELECT idx+1,
             CASE SUBSTR(p, idx+1, 1) WHEN '[' THEN jumpdepth+1 WHEN ']' THEN 
jumpdepth-1 ELSE jumpdepth END,
             CASE SUBSTR(p, idx+1, 1) WHEN '[' THEN SUBSTR('0000' || (idx+1), 
-4) || jumplist WHEN ']' THEN SUBSTR(jumplist,5) ELSE jumplist END,
             CASE SUBSTR(p, idx+1, 1) WHEN ']' THEN CAST(SUBSTR(jumplist,1,4) 
AS INTEGER) ELSE NULL END,
             CASE SUBSTR(p, idx+1, 1) WHEN '[' THEN 'L' WHEN ']' THEN 'R' ELSE 
NULL END, p
          FROM jumpdepth
          WHERE LENGTH(p)>=idx),
  jumptable(a,b,dir) AS
       (SELECT idx,jumpback,'L' FROM jumpdepth WHERE jumpback IS NOT NULL
          UNION ALL
        SELECT jumpback,idx+1,'R' FROM jumpdepth WHERE jumpback IS NOT NULL),
  bf AS (SELECT p, 1 AS ip, 1 AS dp, '' AS output, input, CAST('0' AS TEXT) AS 
tape
           FROM program
        UNION ALL
        SELECT p, CASE WHEN jumptable.b IS NOT NULL AND
                ((dir='L' AND SUBSTR(tape, dp, 1)=0) OR (dir='R' AND 
SUBSTR(tape,dp,1)!=0)) THEN jumptable.b ELSE ip+1 END,
        CASE SUBSTR(p, ip, 1) WHEN '>' THEN dp+1 WHEN '<' THEN MAX(dp-1,1) ELSE 
dp END,
        CASE WHEN SUBSTR(p, ip, 1)='.' THEN (output || SUBSTR(tape, dp, 1)) 
ELSE output END,
        CASE WHEN SUBSTR(p, ip, 1)=',' THEN SUBSTR(input, 2) ELSE input END,
        CASE SUBSTR(p, ip, 1)
                WHEN '<' THEN CASE WHEN dp=1 THEN '0' || tape ELSE tape END
                WHEN '>' THEN CASE WHEN dp=LENGTH(tape) THEN tape || '0' ELSE 
tape END
                WHEN '+' THEN SUBSTR(tape,1,dp-1) || SUBSTR(tape,dp,1)+1 || 
SUBSTR(tape,dp+1)
                WHEN '-' THEN SUBSTR(tape,1,dp-1) || SUBSTR(tape,dp,1)-1 || 
SUBSTR(tape,dp+1)
                WHEN ',' THEN SUBSTR(tape,1,dp-1) || SUBSTR(input,1,1) || 
SUBSTR(tape,dp+1)
                ELSE tape END
  FROM bf LEFT JOIN jumptable ON jumptable.a=ip WHERE LENGTH(p) >= ip)
SELECT ip,dp,input,output,tape FROM bf LIMIT 1000;



_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to