LISP in QBASIC

General discussion for topics related to the FreeBASIC project or its community.
Post Reply
TmX
Posts: 24
Joined: Apr 19, 2006 4:58

LISP in QBASIC

Post by TmX »

Found this during random Googling session. It's a very simple LISP interpreter written in QBASIC.
Yes, FB is able to compile this.
This is a LISP (Scheme) interpreter written in QBASIC. It implements linked lists using arrays. It supports optimized proper tail recursion if and only if your BASIC compiler optimizes tail calls (so no for Microsoft QBASIC, yes for FreeBASIC). It does not have garbage collection, and integers are BASIC INTEGERS, not bignums. Why does this exist? I wanted to write an interpreter and was stuck on a Windows XP laptop without Internet. It turned out that QBASIC.EXE was saved somewhere, so I used that.
https://www.ma.utexas.edu/users/dmenezes/lisp.html
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: LISP in QBASIC

Post by counting_pine »

Cool.
(I didn't know we supported tail call optimisation though!)
fxm
Moderator
Posts: 12106
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: LISP in QBASIC

Post by fxm »

counting_pine wrote:I didn't know we supported tail call optimisation though!
Neither do I!
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: LISP in QBASIC

Post by dodicat »

Does -gen gcc optimize this way?
from http://stackoverflow.com/questions/3109 ... timization

The second answer down on the site, -- I messed about with this factorial, made it all strings and generally complicated it.
-gen gcc about 1.7 seconds

-gen gcc -Wc O3 about .7 seconds.

The silly factorial:

Code: Select all



Dim shared As integer _Mod(0 To 99),_Div(0 To 99)
For z As Integer=0 To 99:_Mod(z)=(z Mod 10+48):_Div(z)=z\10:next
        
function Qmult(a as string,b as string) as string
      var flag=0,la = len(a),lb = len(b)
      If Len(b)>Len(a) Then flag=1:swap a,b:swap la,lb
dim as ubyte n,carry,ai
    var c =string(la+lb,"0")
    for i as integer =la-1 to 0 step -1
        carry=0:ai=a[i]-48
        for j as integer =lb-1 to 0 step -1
			 n = ai * (b[j]-48) + (c[i+j+1]-48) + carry
            
              carry =_Div(n):c[i+j+1]=_Mod(n)
            next j
        c[i]+=carry
    next i
 if flag then swap a,b
	return ltrim(c,"0")
end function

function dec(s As String,counts as integer=0) as string
    if s="1" then return"0"
    Var ls=Len(s)
    while ls
        If  s[ls-counts-1]=48 Then
            counts+=1
        Else
            return Ltrim(Left(s,ls-counts-1)+Str(s[ls-counts-1]-49)+String(counts,"9"),"0")
        End If
    wend
End function

'========================== TEST ===================================
    
    function fact_h(n as string,acc as string) as string
        if n="0" then return acc
        return fact_h(dec(n),Qmult(acc,n))
    end function
    
    function factorial(n as string) as string
        return fact_h(n,"1")
        end function
    dim as double t=timer,t2
    
    var f= factorial("4000")
    t2=timer
    print f
    print "Time ";t2-t
    sleep
    
            
            
             
anonymous1337
Posts: 5494
Joined: Sep 12, 2005 20:06
Location: California

Re: LISP in QBASIC

Post by anonymous1337 »

Here was some LISP I wanted to test:

Code: Select all

(define (recursion-test x)
  (cond 
    (< x (* 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000))
    (recursion-test (+ x 1))))
But < was an unrecognized operator. Frowny face...

Not bad source at all. LISP is simple, but I still wouldn't know how to implement it in QBASIC :)
Post Reply