Author Topic: Lisp in Basic  (Read 208279 times)

0 Members and 3 Guests are viewing this topic.

JRS

  • Guest
Re: Lisp in Basic
« Reply #405 on: August 13, 2014, 04:49:56 PM »
Much easier than that.

Code: [Select]
cmd = COMMAND()

SPLIT cmd BY " " TO DEBUG, filename

scriba lisp.sb -D fibonacci.scm

You would need some IF logic to see if there are more than 1 (filename) argument on the command line. The point was SPLIT will do the job.
« Last Edit: August 13, 2014, 04:59:32 PM by John »

Mike Lobanovsky

  • Guest
Re: Lisp in Basic
« Reply #406 on: August 13, 2014, 04:59:44 PM »
FBSL has also a special value Command(-1) that will return the raw command line, and an equivalent Split() function to parse a string into an array of tokens by any separator(s). We can use those for command line parsing thus making the code as unified as possible. :)

OK John, I guess it's time for me to go. (boose has taken its toll :) )

See you tomorrow.
« Last Edit: August 13, 2014, 05:09:01 PM by Mike Lobanovsky »

JRS

  • Guest
Re: Lisp in Basic
« Reply #407 on: August 13, 2014, 06:03:25 PM »
I have pushed the change to Bitbucket. Here is the main part of the change. (3 other one line changes done as well)

This version allows any order of the two options, extra spaces and lower case on the -D. Another SB feature that makes this work is that SPLITA / SPLIT only uses the first occurrence of the defined delimiter in case there is a string of them in a row.

Code: [Select]
cmdln = COMMAND()

SPLITA TRIM(cmdln) BY " " TO cmdlnargs
dbgflg = FALSE
FOR x = 0 TO UBOUND(cmdlnargs)
  IF TRIM(UCASE(cmdlnargs[x])) = "-D" THEN
    dbgflg = TRUE
  ELSE IF TRIM(cmdlnargs[x]) <> undef THEN
    cmdflg = TRUE
    cmdlnfn = TRIM(cmdlnargs[x])
  ELSE
    cmdflg = FALSE
  END IF
NEXT
« Last Edit: August 13, 2014, 09:47:48 PM by John »

JRS

  • Guest
Re: Lisp in Basic
« Reply #408 on: August 13, 2014, 10:07:02 PM »
Here is my first compile effort with ECL.

Compile
Code: [Select]
(compile-file "fibonacci.lsp" :system-p t)
(c:build-program "fibonacci" :lisp-files '("fibonacci.o"))

jrs@laptop:~/gcl$ time ./fibonacci
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, ...

real   0m0.166s
user   0m0.140s
sys   0m0.020s
jrs@laptop:~/gcl$ ls -l fibonacci
-rwxrwxr-x 1 jrs jrs 43860 Aug 13 23:02 fibonacci
jrs@laptop:~/gcl$

JRS

  • Guest
Re: Lisp in Basic
« Reply #409 on: August 13, 2014, 10:41:02 PM »
Here we have a C recursive Fibonacci series.

Code: [Select]
#include<stdio.h>

int Fibonacci(int);

int main()
{
int n = 24, i = 0, c;
printf("Fibonacci series\n");
for ( c = 1 ; c <= n + 1 ; c++ )
{
printf("%d\n", Fibonacci(i));
i++;
}
return 0;
}

int Fibonacci(int n)
{
if ( n == 0 )
return 0;
else if ( n == 1 )
return 1;
else
return ( Fibonacci(n-1) + Fibonacci(n-2) );
}

jrs@laptop:~/ecl/examples/jrs$ time ./fibonacci
Fibonacci series
0
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
10946
17711
28657
46368

real   0m0.004s
user   0m0.000s
sys   0m0.000s
jrs@laptop:~/ecl/examples/jrs$
 

JRS

  • Guest
Re: Lisp in Basic
« Reply #410 on: August 13, 2014, 11:02:45 PM »
It seems no matter where I go, I always end up back where I started.

Code: [Select]
FUNCTION Fibonacci(n)
  IF n = 0 THEN
    Fibonacci = 0
  ELSE IF n = 1 THEN
    Fibonacci = 1
  ELSE
    Fibonacci = Fibonacci(n - 1) + Fibonacci(n - 2)
  END IF
END FUNCTION

PRINT "Fibonacci series\n"
FOR x = 1 TO 24
  PRINT Fibonacci(x),"\n"
NEXT

jrs@laptop:~/sb/sb22/sblisp$ time scriba fibonacci.sb
Fibonacci series
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
10946
17711
28657
46368

real   0m0.430s
user   0m0.428s
sys   0m0.004s
jrs@laptop:~/sb/sb22/sblisp$
« Last Edit: August 14, 2014, 08:11:12 AM by John »

Mike Lobanovsky

  • Guest
Re: Lisp in Basic
« Reply #411 on: August 14, 2014, 12:31:58 AM »
Hi,

It looks as follows here, exe load and bytecode/JIT compilation overhead included: (therefore not very informative for such a low number of iterations, especially in DynC)

.

JRS

  • Guest
Re: Lisp in Basic
« Reply #412 on: August 14, 2014, 06:47:54 AM »
Thanks Mike for the post.

I had a lot of fun working with you and getting Arthur's Lisp interpreter going in SB. I'm willing to keep improving the SBLisp version as time permits as a educational tool. Learning Lisp by building an interpreter isn't a bad way to get there. (just like new BASIC programmers learning the language, creating a new variation is a prerequisite)

SB works for me and I need to get back to that effort. (SB 2.2 release)

« Last Edit: August 14, 2014, 06:58:06 AM by John »

RobbeK

  • Guest
Re: Lisp in Basic -- a good survey
« Reply #413 on: August 14, 2014, 09:39:12 AM »
Hi all,  John , Mike :

http://common-lisp.net/~dlw/LispSurvey.html

best Rob

JRS

  • Guest
Re: Lisp in Basic
« Reply #414 on: August 14, 2014, 09:49:11 AM »
Thanks Rob!

Great resource.

JRS

  • Guest
Re: Lisp in Basic
« Reply #415 on: August 14, 2014, 05:48:44 PM »
Mike,

Any ideas how we might add support for printing spaces and other non-standard characters?

I think this would be the next thing if you have any interest in improving on our version of LISP in BASIC.

John

Mike Lobanovsky

  • Guest
Re: Lisp in Basic
« Reply #416 on: August 14, 2014, 09:46:41 PM »
Hi John,

Assuming we do not want to change the current behavior of either XBLisp '-literals, or its (print) command (which I don't like at all BTW), or its (eval) rules, we may safely overwrite the existing GetSymbol: with the following code:

Code: [Select]
GetSymbol:
  total = 0
  opos = ipos
  smb = 1
  slength = FALSE
  GetHashNumLoop:
  IF ipos = LEN(ibuf) + 1 THEN GOTO CheckExistance
  curchar = UCASE(MID(ibuf, ipos, 1))
  IF slength = TRUE THEN
    IF curchar = "\"" THEN
      ipos += 1
      GOTO CheckExistance
    ELSE
      GOTO DoStrLiteral
    END IF
  ELSE
    IF curchar = "\"" THEN
      ipos += 1
      opos = ipos
      slength = TRUE
    END IF
  END IF
  IF INSTR(" ()'", curchar) THEN GOTO CheckExistance
DoStrLiteral:
  temp = ASC(curchar) * smb + total
  total = temp - (INT(temp / maxsymboltablesize) * maxsymboltablesize)
  temp = smb * 256
  smb = temp - (INT(temp / maxsymboltablesize) * maxsymboltablesize)
  ipos += 1
  GOTO GetHashNumLoop
  CheckExistance:
  IF symbols[total] = "" THEN GOTO PutInTable
  temp = symbols[total]
  IF temp = UCASE(MID(ibuf, opos, ipos - opos + slength)) THEN
    ctype = symbol
    cvalue = total
    bsd -= 1
    RETURN
  END IF
  temp = total * total
  total = temp - (INT(temp / maxsymboltablesize) * maxsymboltablesize)
  GOTO CheckExistance
  PutInTable:
  IF slotsfilled = maxsymboltablesize THEN
    PRINT "ERROR: Symbol table full.\n"
    END
  END IF
  symbols[total] = UCASE(MID(ibuf, opos, ipos - opos + slength))
  ctype = symbol
  cvalue = total
  slotsfilled += 1
  bsd -= 1
  RETURN

The only difference between FBSL and SB/O2 will be the sign of variable slength in the two MID() statements because FBSL has TRUE = 1 while SB/O2 have TRUE = -1. The above code is valid for SB and O2.

Long string literals will be stored in the hash table together with all other literals as SYMBOLs and they will behave in the exact same way as their single-word counterparts. You can use whatever escapes SB's PRINT would normally understand in between the double quotes.

Please see also the attached picture.



.

JRS

  • Guest
Re: Lisp in Basic
« Reply #417 on: August 14, 2014, 10:09:25 PM »
Sweet!

I should have a treat for you as well soon.


JRS

  • Guest
Re: Lisp in Basic
« Reply #418 on: August 15, 2014, 12:22:10 AM »
I restructured SBLisp to look and work like a standard BASIC program without the (legal but hard to follow) shortcuts. GetSymbol is now a SUB so I slightly modified your new routine. It just hangs SBLisp and the old converted one works fine. I can't see the difference between them.  :-[

Bitbucket has been updated with the new version of the code. PLEASE TEST !!!

Mike's Version
Code: [Select]
SUB GetSymbol
  total = 0
  opos = ipos
  smb = 1
  slength = FALSE
  GetHashNumLoop:
  IF ipos = LEN(ibuf) + 1 THEN GOTO CheckExistance
  curchar = UCASE(MID(ibuf, ipos, 1))
  IF slength = TRUE THEN
    IF curchar = "\"" THEN
      ipos += 1
      GOTO CheckExistance
    ELSE
      GOTO DoStrLiteral
    END IF
  ELSE
    IF curchar = "\"" THEN
      ipos += 1
      opos = ipos
      slength = TRUE
    END IF
  END IF
  IF INSTR(" ()'", curchar) THEN GOTO CheckExistance
DoStrLiteral:
  temp = ASC(curchar) * smb + total
  total = temp - (INT(temp / maxsymboltablesize) * maxsymboltablesize)
  temp = smb * 256
  smb = temp - (INT(temp / maxsymboltablesize) * maxsymboltablesize)
  ipos += 1
  GOTO GetHashNumLoop
  CheckExistance:
  IF symbols[total] = "" THEN GOTO PutInTable
  temp = symbols[total]
  IF temp = UCASE(MID(ibuf, opos, ipos - opos + slength)) THEN
    ctype = symbol
    cvalue = total
    bsd -= 1
    EXIT SUB
  END IF
  temp = total * total
  total = temp - (INT(temp / maxsymboltablesize) * maxsymboltablesize)
  GOTO CheckExistance
  PutInTable:
  IF slotsfilled = maxsymboltablesize THEN
    PRINT "ERROR: Symbol table full.\n"
    END
  END IF
  symbols[total] = UCASE(MID(ibuf, opos, ipos - opos + slength))
  ctype = symbol
  cvalue = total
  slotsfilled += 1
  bsd -= 1
END SUB

Here is Fibonacci 24 with the new version.

jrs@laptop:~/sb/sb22/sblisp$ time scriba lisp.sb fibonacci.scm
SBLisp - Scheme BASIC Lisp

(define fibonacci (lambda (n)
  (if (< n 2)
      n
      (+ (fibonacci (- n 1))
         (fibonacci (- n 2)))))
)
FIBONACCI
(fibonacci 24)
46368
(quit)
Bye!

real   1m47.182s
user   1m47.043s
sys   0m0.048s
jrs@laptop:~/sb/sb22/sblisp$
« Last Edit: August 15, 2014, 01:02:39 AM by John »

RobbeK

  • Guest
Re: Lisp in Basic
« Reply #419 on: August 15, 2014, 01:12:28 AM »
Hi,

At this moment  next is also getting tempting   i.o.    (construct lisp basic (john mike))   ->   (construct basic lisp (rob))

..  there are modules in lisp setting up the infix notation and the rest is a question of writing macro's   , the whole thiing can be compiled into native code or bytecode  (those Lisps run on almost any system ).
But keeping the words of (one of Mike's mentors ?) in mind :    "   try ? no try ...   do or not do "   I have to consider things first .

best Rob