Author Topic: < 100 loc Interpreter and IDE  (Read 160 times)

B+

  • Sr. Member
  • ****
  • Posts: 436
    • View Profile
< 100 loc Interpreter and IDE
« on: 19. June 2017, 16:04:57 »
Smaller than Tinybasic.bas (450 lines), this SmallBASIC interpreter offers an in folder IDE in less than 100 lines of code! No punctuation is used for syntax (though . is command for print line ; is command print no CR + LF and ? is command for input). Variables are limited to lower case letters a-z. Notepad is used for editor in IDE but Linux users could change line to equivalent editor. Like Tinybasic, GOSUB is available. Unlike Tinybasic, no line numbers are needed but line labels are available for GO option. Also unlike Tinybasic, modern DO... LOOP and IF... ELSE... FI code blocks are available.
 
Code: [Select]
t="Nano3":color 11,1:for s=160 to 4 step -4:cls:w=window():w.setfont(s,"pt",0,0)
at(xmax-txtw(t))/2,(ymax-txth(t))/2:? t:delay 1:next:w.setfont(16,"pt",0,0)
label restart
color 0, 11:cls:anyfile=files("*nano3.txt"):sort anyfile:? "nano3 Files:":?
for i = 0 to ubound(anyfile):? i,anyfile(i):next
? : input "Enter file NUMBER (any else quits) >  ",flnm
if isnumber(flnm) then
if flnm >= 0 and flmn <=ubound(anyfile) then : getfile = anyfile(flnm) : tload getfile, p : else : end : fi
else : end : fi
color 7, 1 : cls: for i = 0 to ubound(p):? i, p(i) : next
?:? "n(New) e(Edit) r(Run) k(Kill) f(Files) q(Quits)":input cmd
select case left(cmd,1)
  case "n" : open "untitled nano3.txt" for output as #1
    print #1, "nano3.txt for Nano3.bas (B+=MGA) "+right(date,4)+"-"+mid(date,4,2)+"-"+left(date,2): close #1
    run "notepad untitled nano3.txt": goto restart 
  case "e" : run "notepad "+ getfile : goto restart
  case "f" : goto restart
  case "k" : kill getfile : goto restart
  case "q" : end
  case "r" : color 7, 0 : cls : dim v(25), w(250), stk() : cl = 0 : si = 0
label readline
w1 = word(p(cl), 1) : w2 = word(p(cl), 2)
for i = 2 to 250 : ws = word(p(cl), i) : cvtValue ws : w(i) = ws : next
if w1 = "go" then
  f = 0 : for i = 0 to ubound(p)
    if word(p(i), 1) = "mark"  and word(p(i), 2) = word(p(cl), 2) then cl = i : f = 1: exit for
  next
  if f = 0 then ? "Error: could not find go mark ";word(p(cl), 2) : goto fini
elif w1 = "cls":cls
elif w1 = "at":at val(w(2)), val(w(3))
elif w1 = "wait":delay val(w(2))
elif w1 = "solve":v(6)=v(0)*v(4)-v(1)*v(3):if v(6)<>0 then v(23)=(v(2)*v(4)-v(1)*v(5))/v(6):v(24)=(v(0)*v(5)-v(2)*v(3))/v(6)
elif w1 = "?":vn=asc(w2)-97:wn=3:while w(wn) <> "":? w(wn);" ";:wn++:wend:input "";temp:v(vn)=temp
elif w1 = "." or w1 = ";":wn=2:while w(wn)<>"":? w(wn);" ";:wn++:wend:if w1 = "." then ?
elif w1 = "loop" : c = 1 : f = 0
  for i = cl - 1 to 0 step -1 : fw = word(p(i), 1)
    if fw = "do" then
      c -- : if c = 0 then cl = i : f = 1 : exit for
    elif fw = "loop" : c ++ : fi
  next
  if f = 0 then ? "Error: could not find do to match loop on line ";cl : goto fini
elif w1 = "exit" : c = 1 : f = 0
  for i = cl + 1 to ubound(p)
    fw = word(p(i), 1)
    if fw = "loop" then
      c -- : if c = 0 then cl = i : f = 1 : exit for
    elif fw = "do" : c ++ : fi
  next
  if f = 0 then ? "Error: could not find loop to match exit on line ";cl : goto fini
elif w1 = "if" : es = "" : for i = 2 to 250 : es = es + w(i) : next : if eval(es) = 0 then cl = find(cl)
elif w1 = "else" : cl = find(cl)
elif len(w1) = 1 and asc(w1) > 96 and asc(w1) < 123 and w2 = "="
  es = "" : for i = 3 to 250 : es = es + w(i) : next : v(asc(w1) - 97) = eval(es)
elif w1 = "end" : goto fini
elif w1 = "sub" : f = 0 : for i = cl + 1 to ubound(p) : if word(p(i), 1) = "return" then cl = i : : f = 1 : exit for
  next : if f = 0 then goto fini
elif w1 = "gosub" : f = 0
  for i = 0 to ubound(p) : if word(p(i), 1) = "sub"  and word(p(i), 2) = word(p(cl), 2) then f = 1: exit for
  next : if f = 0 then ? "Error: could not find sub ";word(p(cl), 2) : goto fini else insert stk, si, cl : cl = i : si++
elif w1 = "return"
  si-- : cl = stk(si) : delete stk, si
elif w1 = "ra" : ra
fi : cl += 1 : if cl > ubound(p) then goto fini
goto readline
label fini
?:? getFile;" run is done." :?:input " Press enter to continue...";again:goto restart
case else : goto restart
end select
sub cvtValue(byref wrd)
  if len(wrd) = 1 and asc(wrd) > 96 and asc(wrd) < 123 then wrd = v(asc(wrd)-97)
end
func find(ln)
  local i, fw, c
  c = 1
  for i = ln+1 to ubound(p) : fw = word(p(i), 1)
    if fw = "fi" then
      c --
      if c = 0 then find = i : exit func
    elif fw = "if"
      c ++
    elif fw = "else" and c = 1
      find = i : exit func
    fi
  next
  ? "Error: could not find fi to match line ";ln : goto fini
end
func word(byref source, wnumber) 'base 0, but word(s, 1) is first word if any
  local w, p : source = trim(source) : if len(source) = 0 then word = "" : exit func
  p = instr(source, "  ")
  while  p > 0 : source = mid(source, 1, p) + mid(source, p + 2, len(source) - p - 1) : p = instr(source, "  ") : wend
  split source, " ", w : if wnumber > 0 and ubound(w) + 1 >= wnumber then word = w(wnumber - 1) else word = ""
end
func eval(s) 'thanks shian!
  chain "env " + enclose("EVAL=") + " + str(" + s + ")" : eval = env("EVAL")
end
sub ra() 'set x, y to origin, set a to rad angle, set r to length if p QB color draw ray
  local x,y:x=v(23)+v(17)*cos(v(0)):y=v(24)+v(17)*sin(v(0))
  if 0<=v(15) and v(15)<16 then:line v(23),v(24),x,y,v(15):fi:v(23)=x:v(24)=y
end
##################################################################################
# The MIT License (MIT)
# Copyright (c) 2017 B+=MGA
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
##################################################################################

BTW, ' or REM or # or whatever are not needed for comments. To make a comment in a Nano3 program, just don't start the line with a command.
If you make a comment on an IF line after the Boolean expression, it will likely be ignored unless mistaken as part of the expression.

Do not use the lower case a as a word in a print line or input prompt unless you intend the a to be replaced by it's value displayed on screen.

Below is pictured the entire manual for Nano3-2 that is accessible from IDE files listing.
« Last Edit: 19. June 2017, 16:52:21 by B+ »

B+

  • Sr. Member
  • ****
  • Posts: 436
    • View Profile
Re: < 100 loc Interpreter and IDE
« Reply #1 on: 19. June 2017, 16:09:41 »
Hi lo Game in Nano:
Code: [Select]
'Hi lo game for do loop nest test nano3.txt for Run Nano3.bas (B+=MGA) 2017-06-07 update now with else
do
r = int(rnd * 100) + 1
c = 0
do
? g Guess my number from 1 to 100, (0 quits)
if  g >= 1
c = c + 1
if  g >  r
. Too High!
else
if  g < r
. Too Low!
else
. You guessed in c guesses!
exit
fi
fi
else
. You signaled quit, goodbye!
end
fi
loop
loop

B+

  • Sr. Member
  • ****
  • Posts: 436
    • View Profile
Re: < 100 loc Interpreter and IDE
« Reply #2 on: 19. June 2017, 16:15:25 »
Calculator almost 2 times as long as Nano3-2!

Code: [Select]
calculator nano3.txt for Nano3.bas (B+=MGA) 2017-06-10

z = space(100)
.
i = -1
at 0 80
. Command Menu:
do
i = i + 1
if i > 22
exit
fi
x = ( i % 5)*160
y = int( i /5)*50+120
at x y
if i = 0
; i = +
fi
if i = 1
; i = -
fi
if i = 2
; i = *
fi
if i = 3
; i = /
fi
if i = 4
; i = ^
fi
if i = 5
; i = pi
fi
if i = 6
; i = rad
fi
if i = 7
; i = cos
fi
if i = 8
; i = sin
fi
if i = 9
; i = tan
fi
if i = 10
; i = acos
fi
if i = 11
; i = asin
fi
if i = 12
; i = atan
fi
if i = 13
; i = deg
fi
if i = 14
; i = mod
fi
if i = 15
; i = ln
fi
if i = 16
; i = exp
fi
if i = 17
; i = mIn
fi
if i = 18
; i = m+
fi
if i = 19
; i = mOut
fi
if i = 20
; i = mClear
fi
if i = 21
; i = # start
fi
if i = 22
; i = quit
fi
loop
.
sub getC
mark cStart
at 0 40
? c Enter command number
if c >=0
if c < 23
go cEnd
else
go cStart
fi
else
go cStart
fi
mark cEnd
return
at 0 0
? r "Enter number for starting."
at 0 0
. z
at 0 0
; r
do
gosub getC
at 180 0
if c = 0
? s + Enter number to add.
r = r + s
fi
if c = 1
? s - Enter number to subtract.
r = r  - s
fi
if c = 2
? s * Enter number to multiply.
r = r * s
fi
if c = 3
? s / Enter divisor.
if s <> 0
r = r / s
else
. Oops, can't divide by 0.
fi
fi
if c = 4
? s ^ Enter power.
r = r ^ s
fi
if c = 5
r = pi
fi
if c = 6
r = r *pi/180
fi
if c = 7
r = cos( r )
fi
if c = 8
r = sin( r )
fi
if c = 9
r = tan( r )
fi
if c = 10
r = acos( r )
fi
if c = 11
r = asin( r )
fi
if c = 12
r = atan( r )
fi
if c = 13
r = deg( r )
fi
if c = 14
? s Enter modulus.
r = r % s
fi
if c = 15
r = log( r )
fi
if c = 16
r = exp( r )
fi
if c = 17
m = r
fi
if c = 18
m = m + r
fi
if c = 19
r = m
fi
if c = 20
m = 0
fi
if c = 21
? r Enter new start number.
fi
if c = 22
at 0 400
end
fi
at 0 0
. z
at 0 0
; r
loop


B+

  • Sr. Member
  • ****
  • Posts: 436
    • View Profile
Re: < 100 loc Interpreter and IDE
« Reply #3 on: 19. June 2017, 16:20:13 »
Code: [Select]
secret rays nano3.txt for Nano3.bas (B+=MGA) 2017-06-06

h = xmax/2
g = ymax/2
l = 300
p = 12
do
a = a + pi/720
if a > 2*pi
exit
else
x = h
y = g
if  a >=pi/2
if a <= 3*pi/2
r = 1.4* l *sin( a )*cos( a )
else
r = l *sin( a )*cos( a )
fi
else
r = l *sin( a )*cos( a )
fi
ra
fi
loop
p = 0
x = h
y = g
a = 3*pi/2
r = l
ra
a = 0
ra
p = 14
r = l * 2
do
i = i + 1
if i > 10
exit
fi
x = x - 2
y = y + 2
p = 12*(( i +1)%2)+9*( i %2)
r = r - 4
a = 0
gosub box
loop
sub box
do
a = a + pi/2
if a > 5*pi/2
exit
fi
ra
loop
return