Author Topic: Shorthand Basic  (Read 18440 times)

0 Members and 1 Guest are viewing this topic.

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Shorthand Basic
« on: March 07, 2020, 12:24:36 am »
For the sake of the life cycle I'm trying to push for any given program, here is a new thread for @bplus's excellent little machine, Shorthand Basic.

He describes it nicely here:

https://www.qb64.org/forum/index.php?topic=16.msg115312#msg115312

The main code is this:
Code: QB64: [Select]
  1. _TITLE "SB by bplus 2018-09-14" 'from BRUN v2?  does not use the makeover eval function?
  2. '2018-02-13 adding string array functions put and get, a god awlful amount of shuffling values around to simulate a numneric array
  3. 'get takes numbers out of the string array (of numbers) and puts it in a number variable, a yucky hack!  to get numeric arrays
  4.  
  5. '2018-02-05 BRUN started from Nano3 writtem in SmallBASIC
  6. 'added FB Eval modified for QB64
  7.  
  8. '2018-02-07 change the way variable assignments are made now n and s
  9. 'add theFile$ to BRUN title bar
  10. 'add cp to print in center of screen
  11. 'eliminate Dflag
  12. 'add locate = cr, mostly I want to just get to a row, let's call this row
  13. 'change variable assignment method and arrays and consts to manage
  14. 'modify record for number and string variables
  15. 'add lookup function
  16. 'more shared vaiables for processing in subs and functions
  17.  
  18. 'TO DO
  19. 'add a bunch of string stuff space! I need space!
  20. 'separate area for error reporting and BRUN messaging
  21. 'colors 3 digit number toy rgb system
  22. 'ink for fore color statement
  23. 'paper for back color
  24. 'add line one graphic to do it all?
  25. 'readFile(lineNum),  writeFile(lineNum)
  26. 'try to keep everything case insensitive including variables
  27.  
  28. CONST xmax = 1200
  29. CONST ymax = 720
  30. CONST nmax = 100
  31. CONST smax = 100
  32.  
  33.  
  34. SCREEN _NEWIMAGE(xmax, ymax, 32)
  35. _SCREENMOVE 100, 10
  36. COLOR _RGB32(100, 200, 255), _RGB32(0, 0, 68): CLS
  37.  
  38. debug = 0
  39.  
  40. 'variable tables
  41. DIM SHARED nName$(nmax), nValue(nmax), sName$(smax), sValue$(smax)
  42.  
  43. 'for evaluate
  44. COMMON SHARED EvalErr$, RAD, DEG
  45. EvalErr$ = ""
  46. RAD = _PI / 180.0
  47. DEG = 180 / _PI
  48.  
  49. 'for gosub
  50. DIM SHARED stackIndex AS INTEGER
  51. DIM SHARED stack(1000) AS INTEGER
  52.  
  53. 'for processing program lines
  54. DIM SHARED w$(250)
  55.  
  56. 'integers for main
  57. DIM i AS INTEGER, lineCnt AS INTEGER, nStop AS INTEGER, cl AS INTEGER, wc AS INTEGER, c AS INTEGER, OK AS INTEGER
  58. DIM theFile$, fLine$, temp$, pLine$, s$, fw$, es$, value$, wdx$
  59. DIM v, f, ansY, ansX, ans, nVal
  60. 'get started, do we have a program to run?
  61. IF COMMAND$ = "" THEN theFile$ = "test new string functions SB.txt" ELSE theFile$ = COMMAND$
  62. IF _FILEEXISTS(theFile$) AND RIGHT$(UCASE$(theFile$), 6) = "SB.TXT" THEN
  63.     _TITLE "SB: " + theFile$
  64.     lineCnt = 0: REDIM SHARED p$(0)
  65.     OPEN theFile$ FOR INPUT AS #1
  66.     WHILE EOF(1) = 0
  67.         LINE INPUT #1, fLine$
  68.         REDIM _PRESERVE SHARED p$(lineCnt)
  69.         p$(lineCnt) = wPrep$(fLine$)
  70.         lineCnt = lineCnt + 1
  71.     WEND
  72.     CLOSE #1
  73.     'debug check  p$() loaded
  74.     IF debug THEN
  75.         IF lineCnt > 40 THEN nStop = 40 ELSE nStop = lineCnt - 1
  76.         FOR i = 0 TO nStop
  77.             PRINT RIGHT$(" " + STR$(i), 2); " "; p$(i)
  78.         NEXT
  79.         INPUT "Here is listing of first 40 lines, press enter for run..."; temp$
  80.     END IF
  81.     cl = 0 'current line
  82.  
  83.  
  84.     stackIndex = 0
  85.  
  86.     WHILE cl < lineCnt
  87.         ERASE w$
  88.         pLine$ = p$(cl)
  89.         IF debug THEN PRINT: PRINT "Program line #, line:"; cl, pLine$
  90.         wc = wCnt(pLine$)
  91.         FOR i = 1 TO wc
  92.             w$(i) = Wrd$(pLine$, i)
  93.         NEXT
  94.         SELECT CASE LCASE$(w$(1))
  95.             CASE "c"
  96.                 CLS
  97.             CASE ".", ";", ","
  98.                 s$ = ""
  99.                 FOR i = 2 TO wc
  100.                     v = 0
  101.                     f = nLookUp%(w$(i), v)
  102.                     IF f THEN
  103.                         s$ = s$ + LTRIM$(STR$(v)) + " "
  104.                     ELSE
  105.                         temp$ = ""
  106.                         f = sLookUp%(w$(i), temp$)
  107.                         IF f THEN
  108.                             s$ = s$ + temp$
  109.                         ELSE
  110.                             s$ = s$ + w$(i) + " "
  111.                         END IF
  112.                     END IF
  113.                 NEXT
  114.                 s$ = RTRIM$(s$)
  115.                 IF w$(1) = "." THEN
  116.                     PRINT s$
  117.                 ELSEIF w$(1) = "," THEN
  118.                     PRINT s$,
  119.                 ELSEIF w$(1) = ";" THEN
  120.                     PRINT s$;
  121.                 END IF
  122.             CASE "cp"
  123.                 s$ = ""
  124.                 FOR i = 2 TO wc
  125.                     v = 0
  126.                     f = nLookUp%(w$(i), v)
  127.                     IF f THEN s$ = s$ + LTRIM$(STR$(v)) + " " ELSE s$ = s$ + w$(i) + " "
  128.                 NEXT
  129.                 s$ = RTRIM$(s$)
  130.                 PRINT SPACE$((150 - LEN(s$)) / 2); s$
  131.             CASE "l"
  132.                 ansY = Evaluate(w$(2))
  133.                 ansX = Evaluate(w$(3))
  134.                 IF EvalErr$ = "" THEN
  135.                     LOCATE ansY, ansX
  136.                 ELSE
  137.                     PRINT "Evaluate Error: "; EvalErr$; " occured on line "; cl
  138.                     EXIT WHILE
  139.                 END IF
  140.             CASE "@"
  141.                 s$ = ""
  142.                 FOR i = 4 TO wc
  143.                     v = 0
  144.                     f = nLookUp%(w$(i), v)
  145.                     IF f THEN s$ = s$ + LTRIM$(STR$(v)) + " " ELSE s$ = s$ + w$(i) + " "
  146.                 NEXT
  147.                 ansX = Evaluate(w$(2))
  148.                 ansY = Evaluate(w$(3))
  149.                 IF EvalErr$ = "" THEN
  150.                     _PRINTSTRING (ansX, ansY), s$
  151.                 ELSE
  152.                     PRINT "Evaluate Error: "; EvalErr$; " occured on line "; cl
  153.                     EXIT WHILE
  154.                 END IF
  155.             CASE "w"
  156.                 _DELAY VAL(w$(2))
  157.             CASE "?"
  158.                 s$ = ""
  159.                 FOR i = 3 TO wc
  160.                     v = 0: f = 0
  161.                     f = nLookUp%(w$(i), v)
  162.                     IF f THEN s$ = s$ + LTRIM$(STR$(v)) + " " ELSE s$ = s$ + w$(i) + " "
  163.                 NEXT
  164.                 PRINT s$;
  165.                 INPUT ""; temp$
  166.                 IF temp$ <> "q" THEN
  167.                     ans = Evaluate(temp$)
  168.                     IF EvalErr$ = "" THEN
  169.                         nRecord w$(2), ans
  170.                     ELSE
  171.                         PRINT "Evaluate Error: "; EvalErr$; " occured on line "; cl
  172.                         EXIT WHILE
  173.                     END IF
  174.                 END IF
  175.  
  176.             CASE "g"
  177.                 f = 0
  178.                 FOR i = 0 TO UBOUND(p$)
  179.                     IF Wrd$(p$(i), 1) = ":" AND Wrd$(p$(i), 2) = w$(2) THEN cl = i: f = 1: EXIT FOR
  180.                 NEXT
  181.                 IF f = 0 THEN PRINT "Error: could not find g's : "; w$(2): EXIT WHILE
  182.  
  183.             CASE "]"
  184.                 c = 1: f = 0
  185.                 FOR i = cl - 1 TO 0 STEP -1
  186.                     fw$ = Wrd$(p$(i), 1)
  187.                     IF fw$ = "[" THEN
  188.                         c = c - 1
  189.                         IF c = 0 THEN cl = i: f = 1: EXIT FOR
  190.                     ELSEIF fw$ = "]" THEN
  191.                         c = c + 1
  192.                     END IF
  193.                 NEXT
  194.                 IF f = 0 THEN
  195.                     PRINT "Error: could not find do to match loop on line "; cl
  196.                     EXIT WHILE
  197.                 END IF
  198.             CASE "x"
  199.                 c = 1: f = 0
  200.                 FOR i = cl + 1 TO UBOUND(p$)
  201.                     fw$ = Wrd$(p$(i), 1)
  202.                     IF fw$ = "]" THEN
  203.                         c = c - 1
  204.                         IF c = 0 THEN cl = i: f = 1: EXIT FOR
  205.                     ELSEIF fw$ = "[" THEN
  206.                         c = c + 1
  207.                     END IF
  208.                 NEXT
  209.                 IF f = 0 THEN
  210.                     PRINT "Error: could not find loop to match exit on line "; cl
  211.                     EXIT WHILE
  212.                 END IF
  213.  
  214.             CASE "i"
  215.                 es$ = ""
  216.                 FOR i = 2 TO wc
  217.                     es$ = es$ + w$(i) + " "
  218.                 NEXT
  219.                 es$ = RTRIM$(es$)
  220.                 'PRINT "evaluate this "; es$
  221.                 ans = Evaluate(es$)
  222.                 'PRINT "evaluated to "; ans
  223.                 IF EvalErr$ = "" THEN
  224.                     IF ans = 0 THEN
  225.                         cl = find(cl)
  226.                         IF cl = -1 THEN EXIT WHILE
  227.                     END IF
  228.                 ELSE
  229.                     PRINT "Evaluate Error: "; EvalErr$; " occured on line "; cl
  230.                     EXIT WHILE
  231.                 END IF
  232.             CASE "e"
  233.                 cl = find(cl)
  234.                 IF cl = -1 THEN EXIT WHILE
  235.  
  236.             CASE "z"
  237.                 EXIT WHILE
  238.  
  239.             CASE "s"
  240.                 f = 0
  241.                 FOR i = cl + 1 TO UBOUND(p$)
  242.                     IF Wrd$(p$(i), 1) = "r" THEN cl = i: f = 1: EXIT FOR
  243.                 NEXT
  244.                 IF f = 0 THEN
  245.                     PRINT "Could not find return for sub at line "; cl
  246.                     EXIT WHILE
  247.                 END IF
  248.             CASE "gs"
  249.                 f = 0
  250.                 FOR i = 0 TO UBOUND(p$)
  251.                     IF Wrd$(p$(i), 1) = "s" AND Wrd$(p$(i), 2) = w$(2) THEN f = 1: EXIT FOR
  252.                 NEXT
  253.                 IF f = 0 THEN
  254.                     PRINT "Error: could not find sub "; w$(2)
  255.                     EXIT WHILE
  256.                 ELSE
  257.                     stack(stackIndex) = cl: cl = i: stackIndex = stackIndex + 1
  258.                 END IF
  259.             CASE "r"
  260.                 stackIndex = stackIndex - 1
  261.                 cl = stack(stackIndex): stack(stackIndex) = 0
  262.  
  263.             CASE "n"
  264.                 es$ = ""
  265.                 FOR i = 3 TO wc
  266.                     es$ = es$ + w$(i) + " "
  267.                 NEXT
  268.                 es$ = RTRIM$(es$)
  269.                 ans = Evaluate(es$)
  270.                 IF EvalErr$ = "" THEN
  271.                     nRecord w$(2), ans
  272.                 ELSE
  273.                     PRINT "Evaluate Error: "; EvalErr$; " occured on line "; cl
  274.                     EXIT WHILE
  275.                 END IF
  276.  
  277.             CASE "$" 'record literal strings to variables here
  278.                 es$ = rightOf$(p$(cl), "{")
  279.                 es$ = leftOf$(es$, "}")
  280.                 sRecord w$(2), es$
  281.  
  282.             CASE "sf" 'string functions syntax: sf var sFunction parameters, according to function var will be string or number
  283.                 SELECT CASE w$(3)
  284.                     CASE "+" 'concant string varaible values
  285.                         temp$ = ""
  286.                         FOR i = 4 TO wc
  287.                             IF sLookUp%(w$(i), s$) > 0 THEN temp$ = temp$ + s$
  288.                         NEXT
  289.                         sRecord w$(2), temp$
  290.                     CASE "word"
  291.                         v = INT(Evaluate(w$(5)))
  292.                         OK% = sLookUp%(w$(4), s$)
  293.                         IF v > 0 AND OK% THEN
  294.                             sRecord w$(2), Wrd$(s$, v)
  295.                         ELSE
  296.                             PRINT "word error: could not get " + w$(5) + " word from variable " + w$(4)
  297.                         END IF
  298.                     CASE "spc"
  299.                         sRecord w$(2), SPACE$(INT(Evaluate(w$(4))))
  300.                     CASE "mid"
  301.                     CASE "instr"
  302.                     CASE "date"
  303.                 END SELECT
  304.  
  305.             CASE ">" 'into variable name at w$(2) at nplace w$(3) the str$ value of w$(4) +....
  306.                 'This sub stores into the w$(2) string variable (whether it exists or not)
  307.                 '  the value built up from w$(4) ++++ and made a string
  308.                 '  to the variable value at word location value of w$(3) a number variable
  309.                 '  the w$(3) value must be an existing n variable name
  310.  
  311.                 es$ = ""
  312.                 FOR i = 4 TO wc
  313.                     es$ = es$ + w$(i) + " "
  314.                 NEXT
  315.                 es$ = RTRIM$(es$)
  316.                 'PRINT "evaluate this "; es$
  317.                 ans = Evaluate(es$)
  318.                 'PRINT "evaluated to "; ans
  319.                 IF EvalErr$ = "" THEN
  320.                     OK = wPut(w$(2), w$(3), LTRIM$(STR$(ans)))
  321.                     IF OK = 0 THEN PRINT "Could not find number variable "; w$(3); " in line"; cl: EXIT WHILE
  322.                 ELSE
  323.                     PRINT "Evaluate Error: "; EvalErr$; " occured on line "; cl
  324.                     EXIT WHILE
  325.                 END IF
  326.  
  327.             CASE "<" ' put into var at w$(2)  from array w$(3) at array index w$(4)
  328.                 'briefly pull a number in string array stored as string and store value into variableat w$(2)
  329.                 ' this sub retrieves the word at w$(4) a number variable
  330.                 ' from the string variable at w$(3)
  331.                 ' and stores the value in number variable w$(2)
  332.                 value$ = ""
  333.                 OK% = sLookUp%(w$(3), value$)
  334.                 IF OK% = 0 THEN PRINT "Could not find string variable "; w$(3); " on line "; cl: EXIT WHILE
  335.                 nVal = 0
  336.                 OK% = nLookUp%(w$(4), nVal)
  337.                 IF OK% THEN
  338.                     wdx$ = Wrd$(value$, nVal)
  339.                     nRecord w$(2), VAL(wdx$)
  340.                 ELSE
  341.                     PRINT "Could not find number variable "; w$(4); " in line"; cl: EXIT WHILE
  342.                 END IF
  343.  
  344.         END SELECT
  345.         IF debug THEN
  346.             PRINT
  347.             PRINT " Here is number table:"
  348.             FOR i = 0 TO nmax
  349.                 IF nName$(i) <> "" THEN PRINT i, nName$(i), nValue(i)
  350.             NEXT
  351.             PRINT " Here is strings tables:"
  352.             FOR i = 0 TO smax
  353.                 IF sName$(i) <> "" THEN PRINT i, sName$(i), sValue$(i)
  354.             NEXT
  355.             INPUT "OK line processed "; OK
  356.             PRINT
  357.         END IF
  358.         cl = cl + 1
  359.     WEND
  360.     COLOR _RGB32(0, 0, 68), _RGB32(100, 200, 255)
  361.     LOCATE 43, 2: PRINT "SB run is done, press any..."
  362.     SLEEP
  363.     PRINT "Drag drop a *SB.txt file onto SB.exe to run."
  364.     SLEEP
  365.     END
  366.  
  367. FUNCTION wPut% (sVar$, nVar$, value$) '  nVar$ must exist   "Put" 'into variable name at w$(2) at nplace w$(3) the value at w$(4)
  368.     'if this function fails return false else return 1
  369.     DIM nValue
  370.     DIM OK, i AS INTEGER, wc AS INTEGER
  371.     DIM sVal$, b$
  372.     nValue = 0
  373.     OK = nLookUp%(nVar$, nValue)
  374.     IF OK = 0 THEN wPut% = 0: EXIT FUNCTION
  375.     sVal$ = ""
  376.     OK = sLookUp%(sVar$, sVal$)
  377.     b$ = ""
  378.     IF OK = 0 THEN 'no string var started
  379.         FOR i = 1 TO nValue - 1
  380.             b$ = b$ + "`" + " "
  381.         NEXT
  382.         b$ = b$ + value$
  383.         sRecord sVar$, b$
  384.         wPut% = 1
  385.     ELSE 'sVar$ started so get the string count and put the value in it or at end of it in position nValue
  386.         wc = wCnt(sVal$)
  387.         IF nValue > wc THEN 'new value is past current size
  388.             b$ = sVal$ + " "
  389.             FOR i = wc + 1 TO nValue - 1
  390.                 b$ = b$ + "`" + " "
  391.             NEXT
  392.             b$ = b$ + value$
  393.             sRecord sVar$, b$
  394.             wPut% = 1
  395.         ELSE 'new value replaces one in string
  396.             FOR i = 1 TO wc
  397.                 IF i <> nValue THEN b$ = b$ + Wrd$(sVal$, i) + " " ELSE b$ = b$ + value$ + " "
  398.             NEXT
  399.             sRecord sVar$, RTRIM$(b$)
  400.             wPut% = 1
  401.         END IF
  402.     END IF
  403.  
  404.  
  405. FUNCTION find% (ln AS INTEGER)
  406.     DIM i AS INTEGER, c AS INTEGER
  407.     DIM fw$
  408.     c = 1
  409.     FOR i = ln + 1 TO UBOUND(p$)
  410.         fw$ = Wrd$(p$(i), 1)
  411.         IF fw$ = "f" THEN
  412.             c = c - 1
  413.             IF c = 0 THEN find = i: EXIT FUNCTION
  414.         ELSEIF fw$ = "i" THEN
  415.             c = c + 1
  416.         ELSEIF fw$ = "e" AND c = 1 THEN
  417.             find = i: EXIT FUNCTION
  418.         END IF
  419.     NEXT
  420.     PRINT "Error: could not find e or f to match i in line "; ln
  421.     find = -1
  422.  
  423. SUB nRecord (n$, value)
  424.     DIM mt AS INTEGER, i AS INTEGER
  425.     DIM ln$
  426.     mt = -1
  427.     ln$ = LCASE$(n$)
  428.     FOR i = 0 TO nmax
  429.         IF nName$(i) = "" AND mt = -1 THEN mt = i
  430.         IF nName$(i) = ln$ THEN nValue(i) = value: EXIT SUB
  431.     NEXT
  432.     IF mt <> -1 THEN nName$(mt) = ln$: nValue(mt) = value
  433.  
  434. FUNCTION nLookUp% (nVarName$, value)
  435.     DIM i AS INTEGER
  436.     DIM ln$
  437.     ln$ = LCASE$(nVarName$)
  438.     FOR i = 0 TO nmax
  439.         IF nName$(i) = ln$ THEN value = nValue(i): nLookUp% = 1: EXIT FUNCTION
  440.     NEXT
  441.     value = -999: nLookUp% = 0
  442.  
  443. SUB sRecord (n$, value$)
  444.     DIM mt AS INTEGER, i AS INTEGER
  445.     DIM ln$
  446.     ln$ = LCASE$(n$)
  447.     mt = -1
  448.     FOR i = 0 TO smax 'check if name is used yet, if so set value$ to it
  449.         IF sName$(i) = "" AND mt = -1 THEN mt = i 'save the first open slot in case we need it
  450.         IF sName$(i) = ln$ THEN sValue$(i) = value$: EXIT SUB
  451.     NEXT
  452.     IF mt <> -1 THEN sName$(mt) = ln$: sValue$(mt) = value$
  453.  
  454. FUNCTION sLookUp% (nVarName$, value$)
  455.     DIM i AS INTEGER
  456.     DIM ln$
  457.     ln$ = LCASE$(nVarName$)
  458.     FOR i = 0 TO smax
  459.         IF sName$(i) = ln$ THEN value$ = sValue$(i): sLookUp% = 1: EXIT FUNCTION
  460.     NEXT
  461.     value$ = "": sLookUp% = 0
  462.  
  463.  
  464. 'this preps e$ string for actual evaluation function and makes call to it,
  465. 'checks results for error returns that or number if no error.
  466. FUNCTION Evaluate (e$)
  467.     IF debug THEN PRINT "Evaluate gets: "; e$
  468.     'Dim As String c, b, subst
  469.     DIM b$, c$, subst$, wd$, fun$
  470.     DIM v
  471.     b$ = "" 'rebuild string with padded spaces
  472.     'this makes sure ( ) + * / % ^ are wrapped with spaces, on your own with - sign
  473.     FOR i = 1 TO LEN(e$) 'filter chars and count ()
  474.         c$ = MID$(e$, i, 1)
  475.         IF c$ = ")" THEN
  476.             po = po - 1: b$ = b$ + " ) "
  477.         ELSEIF c$ = "(" THEN
  478.             po = po + 1: b$ = b$ + " ( "
  479.         ELSEIF INSTR("+*/%^", c$) > 0 THEN
  480.             b$ = b$ + " " + c$ + " "
  481.         ELSEIF INSTR(" -.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz<>=", c$) > 0 THEN
  482.             b$ = b$ + c$
  483.         END IF
  484.         IF po < 0 THEN EvalErr$ = "Too many )": EXIT FUNCTION
  485.     NEXT
  486.     IF po <> 0 THEN EvalErr$ = "Unbalanced ()": EXIT FUNCTION
  487.     e$ = wPrep$(b$)
  488.     FOR i = 1 TO 3
  489.         p = wIn(LCASE$(e$), Wrd$("rnd e pi", i))
  490.         WHILE p > 0
  491.             SELECT CASE i
  492.                 CASE 1: subst$ = LTRIM$(STR$(RND))
  493.                 CASE 2: subst$ = LTRIM$(STR$(EXP(1)))
  494.                 CASE 3: subst$ = LTRIM$(STR$(_PI))
  495.             END SELECT
  496.             e$ = wSubst$(e$, p, p, subst$)
  497.             p = wIn(LCASE$(e$), Wrd("rnd e pi", i))
  498.         WEND
  499.     NEXT
  500.     wc = wCnt(e$)
  501.     b$ = ""
  502.     FOR i = 1 TO wc
  503.         wd$ = Wrd$(e$, i)
  504.         v = 0
  505.         f = nLookUp%(wd$, v)
  506.         IF debug THEN PRINT "nLookup of "; wd$; " found:"; f; " value "; v
  507.         IF f THEN b$ = b$ + LTRIM$(STR$(v)) + " " ELSE b$ = b$ + wd$ + " "
  508.     NEXT
  509.     e$ = RTRIM$(b$)
  510.     IF debug THEN PRINT "Evaluate pre digests e to: "; e$
  511.     Evaluate = evalW(e$)
  512.  
  513. ' the recursive part of EVAL, eliminated DFlag, now check lcase$ of fun$
  514. FUNCTION evalW (s$)
  515.     DIM pop AS INTEGER, lPlace AS INTEGER, i AS INTEGER, rPlace AS INTEGER, wc AS INTEGER
  516.     DIM po AS INTEGER, funPlace AS INTEGER, recurs AS INTEGER, p AS INTEGER, o AS INTEGER
  517.     'Dim As String fun, w, test, inner, ops, op, middle
  518.     DIM a, b, innerV, m
  519.     DIM fun$, test$, inner$, w$, ops$, op$, middle$
  520.     IF debug THEN PRINT "EvalW gets: "; s$ 'debug or fun$ to watch recursive calls in reverse
  521.  
  522.  
  523.     pop = wIn(s$, "(") 'parenthesis open place
  524.     WHILE pop > 0
  525.         IF pop = 1 THEN
  526.             fun$ = "": lPlace = 1
  527.         ELSE
  528.             test$ = LCASE$(Wrd$(s$, pop - 1))
  529.             funPlace = wIn("int sin cos tan atan log exp sqr rad deg", test$) 'no asin or acos in QB64
  530.             IF funPlace > 0 THEN
  531.                 fun$ = test$: lPlace = pop - 1
  532.             ELSE
  533.                 fun$ = "": lPlace = pop
  534.             END IF
  535.         END IF
  536.         wc = wCnt(s$): po = 1
  537.         FOR i = pop + 1 TO wc
  538.             IF Wrd$(s$, i) = "(" THEN po = po + 1
  539.             IF Wrd$(s$, i) = ")" THEN po = po - 1
  540.             IF po = 0 THEN rPlace = i: EXIT FOR
  541.         NEXT
  542.         inner$ = ""
  543.         FOR i = (pop + 1) TO (rPlace - 1)
  544.             w$ = Wrd$(s$, i)
  545.             inner$ = inner$ + w$ + " "
  546.             IF wIn("( and or = < > <= >= <> + - * / % ^", w$) > 0 THEN recurs = 1
  547.         NEXT
  548.         IF recurs THEN innerV = evalW(inner$) ELSE innerV = VAL(inner$)
  549.         SELECT CASE LCASE$(fun$)
  550.             CASE "": m = innerV
  551.             CASE "int": m = INT(innerV)
  552.             CASE "sin": m = SIN(innerV)
  553.             CASE "cos": m = COS(innerV)
  554.             CASE "tan": m = TAN(innerV)
  555.                 'QB64 doesn't have these?
  556.                 'CASE "asin": IF DFlag THEN m = DEG * (Asin(innerV)) ELSE m = Asin(innerV)
  557.                 ' CASE "acos": IF DFlag THEN m = DEG * (acos(innerV)) ELSE m = acos(innerV)
  558.             CASE "atan": m = ATN(innerV)
  559.             CASE "log"
  560.                 IF innerV > 0 THEN
  561.                     m = LOG(innerV)
  562.                 ELSE
  563.                     EvalErr$ = "LOG only works on numbers > 0.": EXIT FUNCTION
  564.                 END IF
  565.             CASE "exp" 'the error limit is inconsistent in JB
  566.                 IF -745 <= innerV AND innerV <= 709 THEN 'your system may have different results
  567.                     m = EXP(innerV)
  568.                 ELSE
  569.                     'what the heck???? 708 works fine all alone as limit ?????
  570.                     EvalErr$ = "EXP(n) only works for n = -745 to 709.": EXIT FUNCTION
  571.                 END IF
  572.             CASE "sqr"
  573.                 IF innerV >= 0 THEN
  574.                     m = SQR(innerV)
  575.                 ELSE
  576.                     EvalErr$ = "SQR only works for numbers >= 0.": EXIT FUNCTION
  577.                 END IF
  578.             CASE "rad": m = innerV * RAD
  579.             CASE "deg": m = innerV * DEG
  580.             CASE ELSE: EvalErr$ = "Unidentified function " + fun$: EXIT FUNCTION
  581.         END SELECT
  582.         s$ = wSubst(s$, lPlace, rPlace, LTRIM$(STR$(m)))
  583.         pop = wIn(s$, "(")
  584.     WEND
  585.  
  586.     ops$ = "% ^ / * - + = < > <= >= <> and or not" 'all () cleared, now for binary ops (not not binary but is last!)
  587.     FOR o = 1 TO 15
  588.         op$ = Wrd$(ops$, o)
  589.         p = wIn(s$, op$)
  590.         WHILE p > 0
  591.             a = VAL(Wrd$(s$, p - 1))
  592.             b = VAL(Wrd$(s$, p + 1))
  593.             SELECT CASE op$
  594.                 CASE "%"
  595.                     IF b >= 2 THEN
  596.                         middle$ = LTRIM$(STR$(INT(a) MOD INT(b)))
  597.                     ELSE
  598.                         EvalErr$ = "For a Mod b, b value < 2."
  599.                         EXIT FUNCTION
  600.                     END IF
  601.                 CASE "^"
  602.                     IF INT(b) = b OR a >= 0 THEN
  603.                         middle$ = LTRIM$(STR$(a ^ b))
  604.                     ELSE
  605.                         EvalErr$ = "For a ^ b, a needs to be >= 0 when b not integer."
  606.                         EXIT FUNCTION
  607.                     END IF
  608.                 CASE "/"
  609.                     IF b <> 0 THEN
  610.                         middle$ = LTRIM$(STR$(a / b))
  611.                     ELSE
  612.                         EvalErr$ = "Div by 0"
  613.                         EXIT FUNCTION
  614.                     END IF
  615.                 CASE "*": middle$ = LTRIM$(STR$(a * b))
  616.                 CASE "-": middle$ = LTRIM$(STR$(a - b))
  617.                 CASE "+": middle$ = LTRIM$(STR$(a + b))
  618.                 CASE "=": IF a = b THEN middle$ = "1" ELSE middle$ = "0"
  619.                 CASE "<": IF a < b THEN middle$ = "1" ELSE middle$ = "0"
  620.                 CASE ">": IF a > b THEN middle$ = "1" ELSE middle$ = "0"
  621.                 CASE "<=": IF a <= b THEN middle$ = "1" ELSE middle$ = "0"
  622.                 CASE ">=": IF a >= b THEN middle$ = "1" ELSE middle$ = "0"
  623.                 CASE "<>": IF a <> b THEN middle$ = "1" ELSE middle$ = "0"
  624.                 CASE "and": IF a <> 0 AND b <> 0 THEN middle$ = "1" ELSE middle$ = "0"
  625.                 CASE "or": IF a <> 0 OR b <> 0 THEN middle$ = "1" ELSE middle$ = "0"
  626.                 CASE "not": IF b = 0 THEN middle$ = "1" ELSE middle$ = "0" 'use b as nothing should be left of not
  627.             END SELECT
  628.             s$ = wSubst$(s$, p - 1, p + 1, middle$)
  629.             'PRINT s$
  630.             p = wIn(s$, op$)
  631.         WEND
  632.     NEXT
  633.     IF debug THEN PRINT "evalW returns "; VAL(s$)
  634.     evalW = VAL(s$)
  635.  
  636.  
  637. 'return trimmed  source string s with one space between each word
  638. FUNCTION wPrep$ (ss$)
  639.     DIM s$, b$, c$
  640.     DIM p AS INTEGER, i AS INTEGER
  641.     s$ = LTRIM$(RTRIM$(ss$))
  642.     IF LEN(s$) = 0 THEN wPrep$ = "": EXIT FUNCTION
  643.  
  644.     'remove all double or more spaces
  645.     p = INSTR(s$, "  ")
  646.     WHILE p > 0
  647.         s$ = MID$(s$, 1, p) + MID$(s$, p + 2, LEN(s$) - p - 1)
  648.         p = INSTR(s$, "  ")
  649.     WEND
  650.     b$ = ""
  651.     FOR i = 1 TO LEN(s$)
  652.         c$ = MID$(s$, i, 1)
  653.         IF ASC(c$) > 31 THEN b$ = b$ + c$
  654.     NEXT
  655.     wPrep$ = b$
  656.  
  657. ' This duplicates JB word(string, wordNumber) base 1, space as default delimiter
  658. ' by returning the Nth word of source string s
  659. ' this function assumes s has been through wPrep
  660. FUNCTION Wrd$ (ss$, wNumber)
  661.     DIM s$, w$
  662.     DIM i AS INTEGER, c AS INTEGER
  663.     s$ = ss$ 'don't change ss$
  664.     IF LEN(s$) = 0 THEN Wrd$ = "": EXIT FUNCTION
  665.     w$ = "": c = 1
  666.     FOR i = 1 TO LEN(s$)
  667.         IF MID$(s$, i, 1) = " " THEN
  668.             IF c = wNumber THEN Wrd$ = w$: EXIT FUNCTION
  669.             w$ = "": c = c + 1
  670.         ELSE
  671.             w$ = w$ + MID$(s$, i, 1)
  672.         END IF
  673.     NEXT
  674.     IF c <> wNumber THEN Wrd$ = " " ELSE Wrd$ = w$
  675.  
  676. 'This function counts the words in source string s
  677. 'this function assumes s has been thru wPrep
  678. FUNCTION wCnt (s$)
  679.     DIM c AS INTEGER, p AS INTEGER, ip AS INTEGER
  680.     's = wPrep(s)
  681.     IF LEN(s$) = 0 THEN wCnt = 0: EXIT FUNCTION
  682.     c = 1: p = 1: ip = INSTR(p, s$, " ")
  683.     WHILE ip
  684.         c = c + 1: p = ip + 1: ip = INSTR(p, s$, " ")
  685.     WEND
  686.     wCnt = c
  687.  
  688. 'Where is word In source s, 0 = Not In source
  689. 'this function assumes s has been thru wPrep
  690. FUNCTION wIn (s$, wd$)
  691.     DIM wc AS INTEGER, i AS INTEGER
  692.     wc = wCnt(s$): wIn = 0
  693.     FOR i = 1 TO wc
  694.         IF Wrd$(s$, i) = wd$ THEN wIn = i: EXIT FUNCTION
  695.     NEXT
  696.  
  697. ' substitute string in s to replace section first to last words inclusive
  698. 'this function assumes s has been thru wPrep
  699. FUNCTION wSubst$ (s$, first, last, subst$)
  700.     DIM wc AS INTEGER, i AS INTEGER, subF AS INTEGER
  701.     DIM b$
  702.     wc = wCnt(s$): b$ = ""
  703.     FOR i = 1 TO wc
  704.         IF first <= i AND i <= last THEN 'do this only once!
  705.             IF subF = 0 THEN b$ = b$ + subst$ + " ": subF = 1
  706.         ELSE
  707.             b$ = b$ + Wrd$(s$, i) + " "
  708.         END IF
  709.     NEXT
  710.     wSubst$ = LTRIM$(RTRIM$(b$))
  711.  
  712. FUNCTION leftOf$ (source$, of$)
  713.     DIM posOf AS INTEGER
  714.     posOf = INSTR(source$, of$)
  715.     IF posOf > 0 THEN leftOf$ = MID$(source$, 1, posOf - 1)
  716.  
  717. FUNCTION rightOf$ (source$, of$)
  718.     DIM posOf AS INTEGER
  719.     posOf = INSTR(source$, of$)
  720.     IF posOf > 0 THEN rightOf$ = MID$(source$, posOf + LEN(of$))
  721.  

... And you can follow the link above for an example pong demo and the full help index.

To bump the number of working demos up by one - perhaps, because maybe this exists somewhere - here is a program that calculates the factorial of a number. Just compile the main code, save this file as facto SB.txt, and then drag+drop the txt onto the executable (or do the equivalent in linux).

Code: [Select]
n facto 6
n prod facto

: dofact
i facto = 1
    . prod
    z
f
i facto > 1
    n facto facto - 1
    n prod prod * facto
f
g dofact

.
.
.
.
.

For completeness, here is the list of commands and so on:

Code: [Select]
. 000 Help SB.txt FOR SB.exe (B+=MGA) rev 2018-09-14 Drag AND drop *B.txt file onto SB.exe TO RUN it.
. (All lines here are PRINT lines, drag AND drop this file onto SB.exe TO READ it without dots.)
. TO avoid punctuation, all executed lines start with keyword commands OR punctuation AS follows:
. ===========================================================================================================  VARIABLES
. Number variables are set st n IS first letter ON LINE, variable NAME IS NEXT, AND variable expression last.
. Use up TO 250 "words" FOR variable AND expression including previous number variables, operators: +-*/^%()<=>
. constants: e, pi, RND   trig functions (radians): COS(), SIN(), TAN(), atan(), conversion: rad(), deg(), INT()
. LOG(), EXP(), operators USING <, =, >, (NOT combinations >= <=) AND, OR, NOT, need TO be separated by spaces.
. example:  i = i + 1 becomes >>>>>   n i i+1
. angle = deg(atan(1.01) becomes >  n angle deg(atan(1.01))
. ===========================================================================================================  ARRAYS
. < arrayName index valueExpression - same AS arrayName(index) = valueExpression  (No DIM statement needed)
. > var arrayName index - same AS var = arrayName(index)
. ===========================================================================================================  OUTPUT
. FOR printing text:   . FOR PRINT with LINE feed,     , FOR PRINT AND TAB,      ; FOR PRINT AND STOP
. l row col    - FOR locating NEXT character cell FOR PRINT OR INPUT place
. a x y text   - FOR locating with graphic x, y pixel positions
. c  - TO CLEAR clutter
. variables in PRINT text will be replaced by their values, so be careful USING variable names in PRINT text.
. When there IS more than one parameter be careful NOT TO use a space in an expression FOR one of the parameters.
. =========================================================================================================== INPUT
. ? var prompt - syntax: ? IS keyword, variable NAME, use 250 words FOR prompt.
. ===========================================================================================================  EXECUTION FLOW
. : lineLabel - sets LINE label in program
. g lineLabel - redirects flow TO mark lineLabel ( DO NOT enter OR EXIT a SUB with go )
. s subLabel - marks start of GOSUB routine
. gs subLabel - redirects flow TO SUB routine
. r - signals EXIT back TO CALL POINT of SUB routine
. w - will pause the given amount of seconds
. z - will END program
. ===========================================================================================================  LOOPING
. [ - marks start of LOOP
. ] - marks the END of LOOP, required with DO
. x - commands EXIT from LOOP
. ===========================================================================================================  BOOLEAN BLOCKS
. i - starts one AND IS followed by Boolean expression TO evaluate
. e - optional, marks LINE TO GOTO IF Boolean evaluates false
. f - marks END of Boolean block
 
 
« Last Edit: March 07, 2020, 12:28:16 am by STxAxTIC »
You're not done when it works, you're done when it's right.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Shorthand Basic
« Reply #1 on: March 07, 2020, 07:15:51 pm »
Quote
He describes it nicely here:

https://www.qb64.org/forum/index.php?topic=16.msg115312#msg115312

I am moving that post here where it belongs:

SB - Shorthand Basic, renamed from BRUN2, originally Nano3. I thought I had updated the parser but no, same old Eval function as Nano, Plot I think got the updated Eval function here at QB64. Funny story, I renamed this to SB to piss off the ScriptBasic guy who wanted to own capital SB for his favorite Basic relegating "sb" to SmallBASIC for shorthand at Retro (maybe it's only funny to me). Also Simple Basic or Short Basic also work.

STxAxTIC already has the source SB.bas file upstairs and it will also be in the zip for the whole folder including a debugger of sorts.

You type up your code in a regular old txt file ending filename with " SB.txt"

Here is an example called "Infinite Pong the movie SB.txt"
Code: QB64: [Select]
  1. Infinite Pong the Movie (for SB by B+ 2018-09-19)
  2.  
  3. constants
  4. n p1y 2
  5. n p2y 43
  6. n pw 10
  7.  
  8. ball
  9. n bx 75
  10. n by 20
  11. n bdx 2
  12. n bdy 1
  13.  
  14. main
  15. [
  16.         c
  17.         gs P1
  18.         gs P2
  19.         gs B
  20.         w .1
  21. ]
  22.  
  23. s P1
  24.         n p1x bx - 5
  25.         l p1y p1x
  26.         ; 1111111111
  27. r
  28.  
  29. s P2
  30.         n p2x bx - 5
  31.         l p2y p2x
  32.         ; 2222222222
  33. r
  34.  
  35. s B
  36.         i bx + bdx < 7
  37.                 n bdx bdx * -1 + int(rnd * 3) - 1
  38.         f
  39.         i bx + bdx > 143
  40.                 n bdx bdx * -1 + int(rnd * 3) - 1
  41.         f
  42.         i by + bdy < 3
  43.                 n bdy bdy * -1
  44.                 n bdx bdx + int(rnd * 3) - 1
  45.         f
  46.         i by + bdy > 42
  47.                 n bdy bdy * -1
  48.                 n bdx bdx + int(rnd * 3) - 1
  49.         f
  50.         n bx bx + bdx
  51.         n by by + bdy
  52.         l by bx
  53.         ; O
  54. r
  55.  
  56.  
  57.  

You drag and drop (or copy and paste) the SB.txt file onto SB.exe and it runs it. There is no IDE or editor or File Mgt so everything is done in Windows Explorer in same folder.

Here is Infinite Pong the Movie in QB64 to compare:
Code: QB64: [Select]
  1. _TITLE "Infinite Pong the Movie.bas for QB64 B+ 2018-09-19"
  2. p1y = 1: p2y = 25 'paddle y
  3. bx = 30: by = 10: bdx = 2: bdy = 1 'ball x, y, dx, dy
  4.     CLS
  5.     p1x = bx - 5: _PRINTSTRING (p1x, p1y), "1111111111" ' draw paddle 1
  6.     p2x = bx - 5: _PRINTSTRING (p2x, p2y), "2222222222" ' draw paddle 2
  7.     IF bx + bdx < 6 THEN bdx = bdx * -1 + INT(RND * 3) - 1
  8.     IF bx + bdx > 74 THEN bdx = bdx * -1 + INT(RND * 3) - 1
  9.     IF by + bdy < 2 THEN bdy = bdy * -1: bdx = bdx + INT(RND * 3) - 1
  10.     IF by + bdy > 24 THEN bdy = bdy * -1: bdx = bdx + INT(RND * 3) - 1
  11.     bx = bx + bdx: by = by + bdy
  12.     _PRINTSTRING (bx, by), "O"
  13.     _LIMIT 10
  14.  
  15.  

Here is Help File for SB "000 Help SB.txt" (drag and drop on SB.exe or just read and ignore the . = Print":
Quote
. 000 Help SB.txt for SB.exe (B+=MGA) rev 2018-09-14 Drag and drop *B.txt file onto SB.exe to run it.
. (All lines here are print lines, drag and drop this file onto SB.exe to read it without dots.)
. To avoid punctuation, all executed lines start with keyword commands or punctuation as follows:
. ===========================================================================================================  VARIABLES
. Number variables are set st n is first letter on line, variable name is next, and variable expression last.
. Use up to 250 "words" for variable and expression including previous number variables, operators: +-*/^%()<=>
. constants: e, pi, rnd   trig functions (radians): cos(), sin(), tan(), atan(), conversion: rad(), deg(), int()
. log(), exp(), operators using <, =, >, (not combinations >= <=) and, or, not, need to be separated by spaces.
. example:  i = i + 1 becomes >>>>>   n i i+1
. angle = deg(atan(1.01) becomes >  n angle deg(atan(1.01))
. ===========================================================================================================  ARRAYS
. < arrayName index valueExpression - same as arrayName(index) = valueExpression  (No DIM statement needed)
. > var arrayName index - same as var = arrayName(index)
. ===========================================================================================================  OUTPUT
. For printing text:   . for print with line feed,     , for print and tab,      ; for print and stop
. l row col    - for locating next character cell for print or input place, l for locate
. @ x y text   - for locating with graphic x, y pixel positions, @ for at
. c  - to clear clutter, c for cls
. variables in print text will be replaced by their values, so be careful using variable names in print text.
. When there is more than one parameter be careful not to use a space in an expression for one of the parameters.
. =========================================================================================================== INPUT
. ? var prompt - syntax: ? is keyword, variable name, use 250 words for prompt. Input numbers only for var.
. ===========================================================================================================  EXECUTION FLOW
. : lineLabel - sets line label in program
. g lineLabel - redirects flow to mark lineLabel ( do not enter or exit a sub with go ), g for goto
. s subLabel - marks start of gosub routine, s for sub
. gs subLabel - redirects flow to sub routine, gs for gosub
. r - signals exit back to call point of sub routine, r for return
. w - will pause the given amount of seconds, w for wait
. z - will end program, z for last or end
. ===========================================================================================================  LOOPING
. [ - marks start of loop, think do
. ] - marks the end of loop, required with ], think loop
. x - commands exit from loop, think exit
. ===========================================================================================================  BOOLEAN BLOCKS
. i - starts one and is followed by Boolean expression to evaluate
. e - optional, marks line to goto if Boolean evaluates false
. f - marks end of Boolean block

38 line Manual, not bad!
It is now updated for this thread, before move and STxAxTIC's copy above had some artifacts left from last name change.

Here are some sample SB.txt programs that work last time I looked along with SB and SB debugger (see attached zip).

PS Oh hey! I did have something going for arrays, see Help < and > commands and "and one for the monkey problem" that was testing a string array.

PPS "Hello SB.txt" program testing ? = Input command symbol does not work for strings, it's expecting a number variable

PPPS SB is an anagram and palindrome of BS.
* SB - Shorthand Basic.zip (Filesize: 1.32 MB, Downloads: 165)
« Last Edit: March 07, 2020, 08:35:37 pm by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Shorthand Basic
« Reply #2 on: March 07, 2020, 07:43:54 pm »
Today I modified STxAxTIC's factorial app to test recursive property of gs command for GOSUB:

Code is more accurate in Quotes because it's in normal text:
Quote
try recursive calls to gosub (gs) for factorial b+ 2020-03-07
[
   ? factorialMe Enter a number to find it's factorial
   i factorialMe <> 0
      n Fac 1
      gs F!
      . Factorial = Fac
   e
      . Goodbye!
      z
   f
   .
]
s F!
   i factorialMe > 1
      n Fac Fac * factorialMe
      n factorialMe factorialMe - 1
      gs F!
   e
      r
   f
r

Yeah good, 10 is limit before e notation kicks in.
 
Recursive Factorial Test on SB.PNG
« Last Edit: March 07, 2020, 07:49:17 pm by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Shorthand Basic
« Reply #3 on: March 07, 2020, 08:06:26 pm »
Oh hey! and it looks like I did start on strings! Looky here from SB.bas
Code: QB64: [Select]
  1.             CASE "$" 'record literal strings to variables here
  2.                 es$ = rightOf$(p$(cl), "{")
  3.                 es$ = leftOf$(es$, "}")
  4.                 sRecord w$(2), es$
  5.             CASE "sf" 'string functions syntax: sf var sFunction parameters, according to function var will be string or number
  6.                 SELECT CASE w$(3)
  7.                     CASE "+" 'concant string varaible values
  8.                         temp$ = ""
  9.                         FOR i = 4 TO wc
  10.                             IF sLookUp%(w$(i), s$) > 0 THEN temp$ = temp$ + s$
  11.                         NEXT
  12.                         sRecord w$(2), temp$
  13.                     CASE "word"
  14.                         v = INT(Evaluate(w$(5)))
  15.                         OK% = sLookUp%(w$(4), s$)
  16.                         IF v > 0 AND OK% THEN
  17.                             sRecord w$(2), Wrd$(s$, v)
  18.                         ELSE
  19.                             PRINT "word error: could not get " + w$(5) + " word from variable " + w$(4)
  20.                         END IF
  21.                     CASE "spc"
  22.                         sRecord w$(2), SPACE$(INT(Evaluate(w$(4))))
  23.                     CASE "mid"
  24.                     CASE "instr"
  25.                     CASE "date"
  26.                 END SELECT
  27.  

And here is the some SB.txt test code for that:
Quote
test new string functions SB.txt B+ 2018-09-15
$ months {January February March April May June July August September October November December} < this is new string literal recorder
l 2*5 10/10  <I am just testing locate l here
[
   'c
   ? nMonth Enter month number to name >
   i nMonth > 0 and nMonth < 13
      sf xmonth word months nMonth  < sf stands for string function, xmonth is var to load word returns the nth word in string
      opps can't comment next lines because they are printing a formatted line
      ; The nMonth                 
      ; th Month of a year is xmonth
      next line adds period to end of formatted print line
      . .
   e
      x
   f
]

Run Output:
 
String test for SB.PNG


Is this boring like a proud parent yakking on and on about es child's first steps, first words.... ;)

« Last Edit: March 07, 2020, 08:09:04 pm by bplus »

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: Shorthand Basic
« Reply #4 on: March 07, 2020, 09:19:20 pm »
Ah, I didn't know this did recursion!

I remember a funny story regarding the recursion milestone with Sxript -  back in 2014, Luke blew my mind by writing its first recursive function, and I never explicitly told the parser to handle recursion. I was naive and I was shocked, but I became enlightened on that day.... So in this spirit I propose we turn "Luke" into a verb, roughly defined to say "the act of writing a factorial routine in your buddy's toy language". So in a sentence, I Luked Shorthand Basic in that post... Anyway, I ramble.

I like SB quite a bit - I'm gonna spend a minute combing through the examples and decide how to present this on a forum page. I designated a code box for the LISP code over at https://www.qb64.org/forum/index.php?topic=2290.0... Will do similar in this case.

Of course @bplus, you're welcome to post it yourself. It won't be seen as masturbatory. You've got a full set of keys to the library. Thanks so much for your service so far.

OH AND -

For code boxes on these forums containing non-QB64 code, you don't need to use a quote. You can click the "code" button anyway and then manually delete the QB64 tag within.
« Last Edit: March 07, 2020, 09:24:55 pm by STxAxTIC »
You're not done when it works, you're done when it's right.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Shorthand Basic
« Reply #5 on: March 07, 2020, 09:32:06 pm »
Thanks for your support STxAxTIC, I am going to see if I can get strings further along. If I decide I have to cave in to double quotes of bend over backwards to avoid them that will be time to hang it up.

I looked at SB code in QB64 code boxes, code boxes and quotes, quotes work best. QB64 code is doing caps in all wrong places and it looks ridiculous, code boxes are indenting way too far in but Quotes look just right. Don't worry for long stuff I will attach txt file or use code box, the manual quote is longest I will go in quote box.




Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: Shorthand Basic
« Reply #6 on: March 07, 2020, 09:36:39 pm »
Ah, understood about code boxes.

Say man, I went through the same issues with strings in Sxript, and decided to borrow from LaTeX with respect to bracketing. I open strings with a back-tick ( ` ) and close with a single quote ( ' ). Sxript ignores double quotes and treats them as joe-character like a Y or a 7. This way code can be embedded into other languages without getting tangled in *its* string regime. Of course, going down this road also involves escape characters, where I adopted the backslash as done in the rest of the world. All in all, a Sxript string might look like:

Quote
`Bplus\'s language is "very" excellent.'

... and renders to

Quote
Bplus's language is "very" excellent.


So anyway - that's what I went with.
You're not done when it works, you're done when it's right.

Offline luke

  • Administrator
  • Seasoned Forum Regular
  • Posts: 324
    • View Profile
Re: Shorthand Basic
« Reply #7 on: March 09, 2020, 08:35:08 am »
Though as we discovered on discord, the ` has problems itself if it get interpreted as Markdown.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Shorthand Basic
« Reply #8 on: March 09, 2020, 10:21:48 am »
I am leaning towards a special command that loads a string into a variable. As a variable, it is one clump of characters and I can maintain using only the space character as my parsing delimiter and no other punctuation goal.

I have reworked Eval that fixed problem of differentiation between - for minus and - for negative values and uses Split instead of Word tools for parsing just haven't installed it yet. It should deliver values from array immediately instead of counting down a string every time a value is needed.

Fellippe has me thinking Snake Game as next round of needed functions plus need an input for strings (another special command).

Special command looks like this:
$stringVarName and the rest of the line is the string

May do that with numbers too:
#numberVarName number or expression with previous #variables

so n = n + 1 is #n n+1

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: Shorthand Basic
« Reply #9 on: March 09, 2020, 06:32:02 pm »
Luke makes a valid point about backtick ` and Discord. My alternative is to have a function quote() that does the same thing as wrap in ` '.
You're not done when it works, you're done when it's right.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Shorthand Basic
« Reply #10 on: October 21, 2020, 10:08:25 pm »
Quote
I have reworked Eval that fixed problem of differentiation between - for minus and - for negative values and uses Split instead of Word tools for parsing just haven't installed it yet. It should deliver values from array immediately instead of counting down a string every time a value is needed.

Finally got around to installing new Eval tools and after a little fix all the old programs seem to be working bad news is its 100 lines longer and my interpreter is closer to 1 K LOC than .5 K.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Shorthand Basic
« Reply #11 on: February 10, 2021, 12:20:41 pm »
I am reworking this from scratch (no Eval function) because of the way I want to handle strings.
Rework is under Simple Interpreter name but may keep SB name because allot of commands are same.

Stumped for some time about how to get away from double quotes identifier for string literals and then how to do functions with them. Once you get them contained in variable names no problem but who wants to make a variable for every letter or word you want to build into a string.

New Syntax for executable lines
cmd,arg1;arg2;arg3;...Chr$(10) or if presence of CR+LF detected in program string then parsed with that.

The comma alerts code that this might be a command line.
Only one type: variable length strings
The only way to tell a string literal from a variable is that variables start with ' mark.
So neither a string nor a variable can use ; and a string can't start with a '.
To clear tabs out from indented code from WP all chars <33 are filtered before exec.
hmm... pretty much assuming no chars < 32 in the lines after first parse and tabs cleared for cmd.

So now all cmds are followed by comma instead of a space, same amount of bytes as SB and bare text for literals (minus ;) and syntax using just a few non-shift keys , ;

So far, very hard to remember to tick a variable name and not type a space after a comma.
Ticking variables is bad but ticking literals including numbers, worse!

Oh! just got an idea how I might reinsert Eval while reviewing progress here. I am debating converting it to string math since all the variables are strings and I have string math basics worked out.
« Last Edit: February 10, 2021, 12:27:16 pm by bplus »

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Shorthand Basic
« Reply #12 on: February 10, 2021, 01:00:35 pm »
Well it's shorthand, but I wouldn't call it BASIC. I do get the fun factor in regard to manipulating code back into usable statements. There are a lot of condition hurdles to address. This reminds me of mennonite's Fig Basic project, bt with a totally different focus. Now if you will excuse me, I have to get back to my own rabbit hole.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Shorthand Basic
« Reply #13 on: February 10, 2021, 01:46:01 pm »
Well it's shorthand, but I wouldn't call it BASIC. I do get the fun factor in regard to manipulating code back into usable statements. There are a lot of condition hurdles to address. This reminds me of mennonite's Fig Basic project, bt with a totally different focus. Now if you will excuse me, I have to get back to my own rabbit hole.

Pete

You are right, not to be called BASIC nor Basic, only Basic inspired and coded under.

I just got a hint of how to do Subs and Functions, my GOSUB command gs, can carry any amount (within reason) of arguments with it! So use gs, cmd as an GOSUB call or as a psuedo Sub call, you will still use r, for Return come back from it. All Arguments are Global but you can name arguments with the sub's name to ignore them as needed in main code, or (man I get ideas when I write to you all) or use Local keyword with the variable name, so we know we can dump them whenever we are outside the subs. Something like that...


Update: Oh hey, how about !Basic, since ! is the symbol for NOT in C or some other PL's, I think.
Always the name is the hot topic for Interpreters ;-))
« Last Edit: February 10, 2021, 01:50:13 pm by bplus »

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: Shorthand Basic
« Reply #14 on: February 10, 2021, 02:06:08 pm »
I'm all for this.

Actually, I'm for both rabbitholes. Hear me out:

bplus: make your language as portable as humanly possible in the sense that I should be able to bootstrap a screen-0 kernel of it onto any other BAS project. Make something like MasterEval$(a$), where a$ is any valid code in your language, and MasterEval$ returns its evaluated result. Text in, text out.

Pete: make your text editor able to include bplus's language. (If done right, this surgery is less than 5 lines.) For instance, when I'm typing, I want to write expressions and evaluate them, and have the result is pasted in where I was typing.

(Even if you think this idea is extremely dumb, you should be designing for it's eventuality anyway.)
« Last Edit: February 10, 2021, 02:08:03 pm by STxAxTIC »
You're not done when it works, you're done when it's right.