Heater
Posts: 13083
Joined: Tue Jul 17, 2012 3:02 pm

Re: Why Avoid BASIC on RPi?

Tue Apr 16, 2019 8:00 pm

Ah yeah, perhaps I did not make that very clear.

Currently I'm tinkering with a RISC V core on a DE0 Nano FPGA board. 32 bit core, 100MHz (~50MIPS), integer only. Just now it only has 40K of RAM. I might manage to get the interface to a 32MB SDRAM chip on the board working one day. That will need some kind of run time. I was contemplating Javascript using the Espruino or Jerry script interpreters that are very small. Then I heard Smalltalk can run it such small spaces.
If some place to store images is required an SD card interface could be added pretty easily, no file system or anything mind.

That's kind of mixed up with my ongoing development of my own RISC V core design from the ground up. Which will likely always be even slower!

But currently I want to get a Smalltalk fibo(4784969) working on a Pi or in the Linux Subsytem for Windows on my PC. Then I can add a Smalltalk solution to the fibo(4784969) github repository: https://github.com/ZiCog/fibo_4784969

timrowledge
Posts: 1273
Joined: Mon Oct 29, 2012 8:12 pm
Location: Vancouver Island
Contact: Website

Re: Why Avoid BASIC on RPi?

Wed Apr 17, 2019 2:56 am

Heater wrote:
Tue Apr 16, 2019 8:00 pm
Ah yeah, perhaps I did not make that very clear.
Yah.
Heater wrote:
Tue Apr 16, 2019 8:00 pm
But currently I want to get a Smalltalk fibo(4784969) working on a Pi or in the Linux Subsytem for Windows on my PC. Then I can add a Smalltalk solution to the fibo(4784969) github repository: https://github.com/ZiCog/fibo_4784969
Okay, this makes it trivial. I’ll post an actual ‘.st’ file tomorrow that is the a appropriate way to pass around a Smalltalk code chunk. This runs in Squeak and would pretty much definitely run in any other non-gst Smalltalk. Squeak runs on Pi’s under Raspian etc, on x86s under linuxes, windows, Mac OS and used to even run under OS/2 or BeOS. Unless you choose not to trust my assertion that I have run it on my own Pi and my timings then you can simply stick that file in your github-thing. If you want to run it yourself then just download Squeak for Pi or Windows and just do it. It really isn’t that hard.
Why would you want to run it under this strange “Linux subsystem for windows”when it will perfectly happily run “native”? Other than a fairly understandable disgust with Windows I guess.
Making Smalltalk on ARM since 1986; making your Scratch better since 2012

ejolson
Posts: 3403
Joined: Tue Mar 18, 2014 11:47 am

Re: Why Avoid BASIC on RPi?

Wed Apr 17, 2019 5:45 am

Heater wrote:
Tue Apr 16, 2019 8:00 pm
But currently I want to get a Smalltalk fibo(4784969) working on a Pi or in the Linux Subsytem for Windows on my PC. Then I can add a Smalltalk solution to the fibo(4784969) github repository: https://github.com/ZiCog/fibo_4784969
One of the themes of this thread, aside from not adding the Visual Basic and BBC Basic Fibonacci codes to the GitHub repository, has been to compare how expressive each language might be for efficiently conveying complicated algorithms to a digital computer.

The model problem chosen for this comparison has been the computation of large Fibonacci numbers by means of the doubling formula and Karatsuba multiplication. An unfortunate drawback of using such classical algorithms is that, except for GNU Smalltalk, there are already well debugged and efficient big-number implementations available as built-in language features or subroutine libraries. As a result it is tempting to focus on computing the 4784969th Fibonacci number and forget the goal: Does knowing Basic provide a person the ability to express any new algorithm they might think up in a readable and efficient way? Which languages are more liberating in the sense of giving the programmer a greater freedom to implement a wide variety of original and newly developed ideas?

While there is certainly merit for scripting together well-known algorithms to solve new problems, this is not the only thing people do with computers. The creation of new algorithms is also an important and active area. Even for a task so simple and thoroughly studied as multiplication, it is possible that someday somebody will have the imagination to construct a new algorithm that is superior to all that came before. In fact, it is plausible such an accomplishment happened a few days ago.

If David Harvey and Joris Van Der Hoeven are correct, they have created a new O(n logn) big-number multiplication algorithm which improves upon the O(n logn loglogn) time complexity of the Schönhage–Strassen algorithm.

When there are so many new algorithms to code, why avoid Basic?
Last edited by ejolson on Wed Apr 17, 2019 6:21 am, edited 1 time in total.

User avatar
Gavinmc42
Posts: 3617
Joined: Wed Aug 28, 2013 3:31 am

Re: Why Avoid BASIC on RPi?

Wed Apr 17, 2019 6:19 am

Squeak, YAFL?
If I read the Squeak blurb right, Squeak plus baremetal C, perhaps Circle, could run the VM on baremetal Pi's with GUI?
If David Harvey and Joris Van Der Hoeven are correct...,
Er, I thought that was for numbers that had like 20Million+ digits?
Have not tried Squeak but if it was supposed to run on PDAs I'm interested ;)
Dynabook :o Wow another blast from the past.
When Kay proposed an extension as this research to Parc's board of directors, his design was well beyond the capabilities of computer hardware and software technology at the time.
Not any more?
I guess every Smartphone and Tablet would be instantly recognized as a Dynabook by Alan.
"The conglomeration of commercial and most open source software consumes in the neighborhood of several hundreds of millions of lines of code these days. We wonder: how small could be an understandable practical "Model T" design that covers this functionality? 1M lines of code? 200K LOC? 100K LOC? 20K LOC?"
I'm start to wonder that too.
STEPS Toward the Reinvention of Programming: A compact and Practical Model of Personal Computing as a Self-exploratorium.[
Isn't that what Pi's a really good for?
I'm dancing on Rainbows.
Raspberries are not Apples or Oranges

Heater
Posts: 13083
Joined: Tue Jul 17, 2012 3:02 pm

Re: Why Avoid BASIC on RPi?

Wed Apr 17, 2019 7:00 am

timrowledge,
Okay, this makes it trivial.
I'm glad to here that because just now nothing works, seems it's not trivial enough to explain in a forum post.

Here is what I have tried:

1) So I installed squeak to Debian. The LSW on my Win 10 PC that should make no odds.

Code: Select all

$ apt-cache search squeak
squeak-plugins-scratch - Squeak plugins for the Scratch programming environment
squeak-plugins-scratch-dbg - Squeak plugins for the Scratch programming environment - debug
squeak-vm - Unix Squeak virtual machine

$ sudo apt-get install squeak-vm squeak-plugins-scratch squeak-plugins-scratch-dbg
...
2) Then I run it:

Code: Select all

$ squeak
found gettext in path
$ squeak --version
found gettext in path
/mnt/c/Users/michael/Documents/fibo_4784969/smalltalk
squeak: could not find any display driver
/usr/bin/squeak: line 246: 14111 Aborted                 (core dumped) $VM
No luck there with -v -h --help etc either.

3) Check the man page:

Code: Select all

$ man squeak 
...
SYNOPSIS
       squeak squeak [image filename]  [project filename]
...
No luck there. I have no image or project. Time to give up with that.

4) Against my better judgement I download squeak for Windows from here: https://squeak.org/

Now I have a Squeak.exe. When I run it I get an IDE. I have no idea what to do with it.

Damn thing does not close when I hit the close button. Grrr....

What to do? Google is not helping.
Why would you want to run it under this strange “Linux subsystem for windows” when it will perfectly happily run “native”? Other than a fairly understandable disgust with Windows I guess.
The LSW may be strange but it actually works really well. It's the best feature of any Windows OS ever. Back in the day I used Cygwin to be able to get useful work done if I had to use a Windows box. LSW is much better.

I don't know much about Windows and don't want to know more than I have to. As Win 10 runs most of my usual favorites from the open source world with LSW I sometimes forget this is not A Linux machine.

The issue is not LSW. It's Smalltalk and the problem of running a trivial 10 line program...

jahboater
Posts: 4598
Joined: Wed Feb 04, 2015 6:38 pm

Re: Why Avoid BASIC on RPi?

Wed Apr 17, 2019 7:20 am

Heater wrote:
Wed Apr 17, 2019 7:00 am
The LSW may be strange but it actually works really well. It's the best feature of any Windows OS ever. Back in the day I used Cygwin to be able to get useful work done if I had to use a Windows box. LSW is much better.
I wish LSW was around when I had to use Windows. The mingw compiler was very good (GCC for windows), it supported recent standards and used the proper LP64 model.

But, something is surely wrong when "the best feature of any Windows OS ever" is the ability to run another OS.

Heater
Posts: 13083
Joined: Tue Jul 17, 2012 3:02 pm

Re: Why Avoid BASIC on RPi?

Wed Apr 17, 2019 7:26 am

ejolson,
One of the themes of this thread, aside from not adding the Visual Basic and BBC Basic Fibonacci codes to the GitHub repository, has been to compare how expressive each language might be for efficiently conveying complicated algorithms to a digital computer.
Yes. But not even a very complicated algorithm in this case. I'll get those BASICs into github, but not before Smalltalk is sorted out.
The model problem chosen for this comparison has been the computation of large Fibonacci numbers by means of the doubling formula and Karatsuba multiplication.
Yes. But the Karatuba multiplication was never part of the specification. It's not required if your language has big integer handling built in, like Python, Javscript, Haske, Smalltalk...
As a result it is tempting to focus on computing the 4784969th Fibonacci number and forget the goal: Does knowing Basic provide a person the ability to express any new algorithm they might think up in a readable and efficient way? Which languages are more liberating in the sense of giving the programmer a greater freedom to implement a wide variety of original and newly developed ideas?
Yes exactly. The Fibo is not the main point. It's just a "model" as you say. A problem that is small and easy to specify.
When there are so many new algorithms to code, why avoid Basic?
I don't know about new algorithms but after about 6 months of programming tuition at tech school, in BASIC, I was bored with putting numbers into DATA statements or getting them from the user with READ and crunching on them. No, I wanted for the user to be able to input expressions and then evaluate them. I needed an expression parser. This was a new and radical idea for me and demanded a new kind of algorithm. After thinking about it I concluded that writing such a thing in BASIC would be a horrible mess, it would be easier to write it in assembler.

Hmm... how about a new challenge: Create an expression parser and evaluate the expression in the language of your choice? Could be simple maths expressions like "x := (x + y) * (1 - sin(2 * π * t))". Assume x,y etc have values. Would have to have a somewhat weird syntax to stop people just using "eval" in their language.

Anyway, little story is why I have avoided BASIC since 1976.
Last edited by Heater on Wed Apr 17, 2019 7:45 am, edited 1 time in total.

Heater
Posts: 13083
Joined: Tue Jul 17, 2012 3:02 pm

Re: Why Avoid BASIC on RPi?

Wed Apr 17, 2019 7:44 am

jahboater,
...something is surely wrong when "the best feature of any Windows OS ever" is the ability to run another OS.
Ha! Yes.

The Linux Subsystem for Windows is badly named. It does not actually have a Linux kernel in it. It's a loader and kernel adapter for Linux application binaries.

This all works very well but means many things that are kernel dependent are missing. For example one cannot get core dumps in LSW.

When I hit these problems a while back it occurred to me that what MS needs to do is swap out their NT kernel for a Linux kernel in their OS. Then they could create an "adapter" to run all the legacy Windows cruft on it. I'm sure they could do a great job of getting wine runing perfectly.

I thought this was just another of my daft ideas. But amazingly Bryan Lunduke, an ex MS guy, also had that idea in one of his videos a few days ago and has sound reasons why MS should do it: "What is the future of various Operating Systems? Possible dumpster fire?": https://www.youtube.com/watch?v=0aYSLWpt65Y&t=898s

jahboater
Posts: 4598
Joined: Wed Feb 04, 2015 6:38 pm

Re: Why Avoid BASIC on RPi?

Wed Apr 17, 2019 7:55 am

Heater wrote:
Wed Apr 17, 2019 7:26 am
Hmm... how about a new challenge: Create an expression parser and evaluate the expression in the language of your choice? Could be simple maths expressions like "x := (x + y) * (1 - sin(2 * π * t))". Assume x,y etc have values. Would have to have a somewhat weird syntax to stop people just using "eval" in their language.
I suppose using yacc or bison is frowned upon :)

Here is a really simple expression parser in C that I wrote.
It only supports left associativity, so the parentheses are required in "a = (b = c)" and "a = (p ? b : c)".
Otherwise it accepts all of the C language expression syntax apart from casts.
The constant π is given as "pi", your test expression "x = (x + y) * (1 - sin(2 * pi * t))" executes fine.
Unary operators have the highest priority so that -2 ** 2 returns 4 and unary minus is part of an integer literal so
that the INT_MIN nightmare is avoided. Sadly both sides of && and || are evaluated.
Functions are treated as named unary operators followed by an expression so sin(0.5) or sin 0.5 both work.
I've not included all the boring lex stuff and the execution functions which are large.

Code: Select all

/*
 *  Simple 'C' expression parser.
 */
static TOKEN *
parse( TOKEN *tok, VALUE * const retval, const char endtok )
{
  TOKEN *result, *dstack = NULL, *ostack = NULL, *pstack = NULL;

  /*
   *  Clear the operator stack by execution.
   */
  void clear_stack( void )
  {
    while( ostack )
    {
      binary( dstack, ostack );
      pop(dstack);
      pop(ostack);
    }
    if( dstack == NULL )
    {
      if( pstack )
        error( MISSING_OP, pstack->erp );
      return;
    }
    *retval = dstack->opval;
    dstack = NULL;
  }

  /*
   *  Skip unused part of conditional expression.
   */
  bool match( const char target )
  {
    for( tok = tok->next; tok && tok->type != target; tok = tok->next )
    {
      if( tok->type == OPEN_PAR && match(CLOSE_PAR) )
        error( MISSING_BRA, result->erp );
      if( tok->type == QUERY && match(COLON) )
        error( SYNTAX, result->erp );
    }
    return !tok;
  }

  /*
   *  The conditional operator.
   *  Include the GCC extension "q ? : n" that returns q if q is non-zero.
   */
  bool ternary( void )
  {
    clear_stack();
    if( tok->next == NULL )
      error( BAD_TERNARY, tok->erp );
    result = tok;
    if( retval->type == FP ? retval->r == 0.0 : retval->i == 0 )
    {
      if( match(COLON) )
        error( BAD_TERNARY, result->erp );
      return no;
    }
    tok = tok->next;
    if( tok->type == COLON )
      result->opval = *retval;
    elif( (tok = parse( tok, &result->opval, COLON )) == NULL )
      error( BAD_TERNARY, result->erp );
    push( result, dstack );
    return match(endtok) || tok->type == endtok;
  }

  do
    switch( tok->type )
    {
      case OPEN_PAR:
        if( tok->next == NULL || tok->next->type == CLOSE_PAR )
          error( MISSING_EXP, tok->erp );
        result = tok;
        if( (tok = parse( tok->next, &tok->opval, CLOSE_PAR )) == NULL )
          error( MISSING_BRA, result->erp );
        push( result, dstack );
        while( pstack )
        {
          unary( dstack, pstack, yes );
          pop(pstack);
        }
        break;

      case OPERAND:
        push( tok, dstack );
        get_value(dstack);
        while( pstack )
        {
          unary( dstack, pstack, yes );
          pop(pstack);
        }
        break;

      case PREFIX:
        push( tok, pstack );
        break;

      case POSTFIX:
        unary( dstack, tok, no );
        break;

      case BINARY:
        while( ostack && tok->priority <= ostack->priority )
        {
          binary( dstack, ostack );
          pop(dstack);
          pop(ostack);
        }
        push( tok, ostack );
        break;

      case SEMI:  // and COMMA
        clear_stack();
        break;

      case QUERY:
        if( ternary() )
          goto done;
        break;

      default:  // COLON, CLOSE_PAR
        if( tok->type != endtok )
          error( SYNTAX, tok->erp );
        goto done;
    }
  while( (tok = tok->next) != NULL );

done:
  clear_stack();
  return tok;
}
Last edited by jahboater on Wed Apr 17, 2019 9:40 am, edited 1 time in total.

Heater
Posts: 13083
Joined: Tue Jul 17, 2012 3:02 pm

Re: Why Avoid BASIC on RPi?

Wed Apr 17, 2019 9:08 am

jahboater,

O oh, here we go...

That is cool but yeah, having code generators write the code for you is would be cheating.

jahboater
Posts: 4598
Joined: Wed Feb 04, 2015 6:38 pm

Re: Why Avoid BASIC on RPi?

Wed Apr 17, 2019 9:26 am

Heater wrote:
Wed Apr 17, 2019 9:08 am
That is cool but yeah, having code generators write the code for you is would be cheating.
Just to be clear, the code above was written by me long ago, before I learned about yacc!

EdDavis
Posts: 2
Joined: Wed Apr 17, 2019 11:40 am

Re: Why Avoid BASIC on RPi?

Wed Apr 17, 2019 11:57 am

Heater wrote:
Wed Apr 17, 2019 7:26 am
I don't know about new algorithms but after about 6 months of programming tuition at tech school, in BASIC, I was bored with putting numbers into DATA statements or getting them from the user with READ and crunching on them. No, I wanted for the user to be able to input expressions and then evaluate them. I needed an expression parser. This was a new and radical idea for me and demanded a new kind of algorithm. After thinking about it I concluded that writing such a thing in BASIC would be a horrible mess, it would be easier to write it in assembler.

Hmm... how about a new challenge: Create an expression parser and evaluate the expression in the language of your choice? Could be simple maths expressions like "x := (x + y) * (1 - sin(2 * π * t))". Assume x,y etc have values. Would have to have a somewhat weird syntax to stop people just using "eval" in their language.
Below is a simple expression parser in BASIC, specifically QB64.

It uses QB64/QBASIS precedence rules

Supports all QB64 numeric/logical operators, plus the following functions:

abs, atn, cos, exp, fix, int, log, rnd, sgn, sin, sqr, tan

Uses Precedence Climbing algorithm

Operator Precedence in BASIC

Highest to Lowest:
  • ^
  • + - (unary negation)
  • * /
  • \ (integer division)
  • MOD
  • + -
  • = <> < > <= >=
  • NOT (unary)
  • AND
  • OR
  • XOR
  • EQV

Code: Select all

OPTION _EXPLICIT

$screenhide
$console
_console on
_dest _console

'Simple numeric calculator - uses BASIC precedence rules
'
'Supports all QB numeric/logical operators, plus the following functions:
'
'abs, atn, cos, exp, fix, int, log, rnd, sgn, sin, sqr, tan
'
'Uses Precedence Climbing algorithm
'
'Operator Precedence in BASIC
'
'Highest:   ^
'           + - (unary negation)
'           *  /
'           \ (integer division)
'          MOD
'           +  -
'           =  <>  <  >  <=  >=
'          NOT (unary)
'          AND
'          OR
'          XOR
'          EQV
'Lowest:   IMP
'

dim shared input_st as string   'the string to evaluate

dim shared tok as integer       ' set by the scanner - one of the values listed below
dim shared id_name as string    ' set by the scanner, if tok is an ID or NUMBER

dim shared prec(20) as integer  'array of precedences

CONST false = 0
CONST true = not false

' Values for tok - also indexes into prec array - code below depends on this ordering
const POWER     =   1
const NEGATE    =   2
const MULTIPLY  =   3
const DIVIDE    =   4
const INT_DIV   =   5
const MODULUS   =   6
const ADD       =   7
const SUBTRACT  =   8
const EQUAL     =   9
const NOT_EQUAL =  10
const LSS_T     =  11
const GTR_T     =  12
const LSS_T_EQL =  13
const GTR_T_EQL =  14
const NOT_T     =  15
const AND_T     =  16
const OR_T      =  17
const XOR_T     =  18
const EQV_T     =  19
const IMP_T     =  20

const ID        = 100
const NUMBER    = 101
const LPAREN    = 102
const RPAREN    = 103

' populate the precedence array - these conicide with the constants above
' we use the operator constants (above) as indexes into the precedence array
'
prec(POWER)    = 13
prec(NEGATE)   = 12
prec(DIVIDE)   = 11: prec(MULTIPLY) = 11
prec(INT_DIV)  = 10
prec(MODULUS)  = 9
prec(SUBTRACT) = 8: prec(ADD) = 8
prec(GTR_T_EQL)=7:prec(LSS_T_EQL)=7:prec(GTR_T)=7:prec(LSS_T)=7:prec(NOT_EQUAL)=7:prec(EQUAL)=7
prec(NOT_T)    = 6
prec(AND_T)    = 5
prec(OR_T)     = 4
prec(XOR_T)    = 3
prec(EQV_T)    = 2
prec(IMP_T)    = 1

input_st = "-1 - 2 - 3 - 4"
print input_st + " = "; eval#

input_st = "3 + 6 / 12 * 3 - 2"
print input_st + " = "; eval#

input_st = "4 ^ - 2"
print input_st + " = "; eval#

input_st = "4 ^ 3 ^ 2"
print input_st + " = "; eval#

input_st = "32 / 2 / 2"
print input_st + " = "; eval#

input_st = "atn(1) * 4"
print "PI = " + input_st + " = "; eval#

while 1
    input "Enter a string to evaluate > "; input_st
    if input_st = "" then end
    print "Expression = "; eval#
    ?
wend

function eval#
    next_tok
    eval# = evalr#(0)
end function

function evalr#(pr as integer)
    dim n as double

    n = primary#

    do while is_binary%(tok) 'need short circuit for this: and prec(tok) >= pr
        if prec(tok) < pr then exit do
        dim op as integer
        op = tok
        next_tok
        select case op
            case IMP_T     : n = n imp evalr#(prec(op) + 1)
            case EQV_T     : n = n eqv evalr#(prec(op) + 1)
            case XOR_T     : n = n xor evalr#(prec(op) + 1)
            case OR_T      : n = n or  evalr#(prec(op) + 1)
            case AND_T     : n = n and evalr#(prec(op) + 1)
            case GTR_T     : n = n >   evalr#(prec(op) + 1)
            case GTR_T_EQL : n = n >=  evalr#(prec(op) + 1)
            case LSS_T_EQL : n = n <=  evalr#(prec(op) + 1)
            case LSS_T     : n = n <   evalr#(prec(op) + 1)
            case NOT_EQUAL : n = n <>  evalr#(prec(op) + 1)
            case EQUAL     : n = n =   evalr#(prec(op) + 1)
            case SUBTRACT  : n = n -   evalr#(prec(op) + 1)
            case ADD       : n = n +   evalr#(prec(op) + 1)
            case MODULUS   : n = n mod evalr#(prec(op) + 1)
            case INT_DIV   : n = n \   evalr#(prec(op) + 1)
            case DIVIDE    : n = n /   evalr#(prec(op) + 1)
            case MULTIPLY  : n = n *   evalr#(prec(op) + 1)
            case POWER     : n = n ^   evalr#(prec(op) + 1)
            case else: print "Expecting an binary operator": evalr# = 0: exit do
        end select
        if is_relational(op) and is_relational(tok) then
            print "consecutive relational operators not allowed"
            evalr# = 0
        end if
    loop
    evalr# = n
end function

function is_binary%(op as integer)
    is_binary% = false
    if op >= MULTIPLY and op <= IMP_T then is_binary% = true: exit function
    if op = POWER then is_binary% = true: exit function
end function

function is_relational%(op as integer)
    is_relational% = false
    if op >= EQUAL and op <= GTR_T_EQL then is_relational% = true
end function

function primary#
    dim n as double
    dim fun as string

    select case tok
        case NUMBER:   n = val(id_name): next_tok
        case ADD:      next_tok: n =     evalr#(prec(NEGATE))
        case SUBTRACT: next_tok: n =    -evalr#(prec(NEGATE))
        case NOT_T:    next_tok: n = not evalr#(prec(NOT_T))
        case LPAREN
            next_tok
            n = evalr#(0)
            call expect(RPAREN, ")")
        case ID
            fun = id_name
            next_tok
            call expect(LPAREN, "(")
            n = evalr#(0)
            call expect(RPAREN, ")")
            n = builtin(fun, n)
        case else: print "Expecting a primary": n = 0
    end select
    primary# = n
end function

function builtin#(fun as string, arg as double)
    dim n as double

    select case lcase$(fun)
        case "abs": n = abs(arg)
        case "atn": n = atn(arg)
        case "cos": n = cos(arg)
        case "exp": n = exp(arg)
        case "fix": n = fix(arg)
        case "int": n = int(arg)
        case "log": n = log(arg)
        case "rnd": n = rnd(arg)
        case "sgn": n = sgn(arg)
        case "sin": n = sin(arg)
        case "sqr": n = sqr(arg)
        case "tan": n = tan(arg)
        case else: n = 0: print "Expecting a function, found: "; fun
    end select
    builtin# = n
end function

sub expect(n as integer, s as string)
    if tok = n then next_tok: exit sub
    print "Expecting: "; s
end sub

sub next_tok
    id_name = ""
    tok = 0

    ' skip spaces
    input_st = ltrim$(input_st)

    if input_st = "" then exit sub

    ' pick off a few multichar operators
    select case lcase$(left$(input_st, 2))
        case ">=": input_st = mid$(input_st, 3): tok = GTR_T_EQL
        case "<=": input_st = mid$(input_st, 3): tok = LSS_T_EQL
        case "<>": input_st = mid$(input_st, 3): tok = NOT_EQUAL
        case else
            ' now do the rest, based on first letter
        select case lcase$(left$(input_st, 1))
            case "0" to "9"
                do
                    id_name = id_name + left$(input_st, 1)
                    input_st = mid$(input_st, 2)
                loop while (left$(input_st, 1) >= "0" and left$(input_st, 1) <= "9") or left$(input_st, 1) = "."
                tok = NUMBER
            case "a" to "z"
                do
                    id_name = id_name + left$(input_st, 1)
                    input_st = mid$(input_st, 2)
                loop while left$(input_st, 1) >= "a" and left$(input_st, 1) <= "z"
                select case lcase$(id_name)
                    case "mod": tok = MODULUS:
                    case "not": tok = NOT_T:
                    case "and": tok = AND_T:
                    case "or" : tok = OR_T:
                    case "eqv": tok = EQV_T:
                    case "imp": tok = IMP_T:
                    case "xor": tok = XOR_T:
                    case else:  tok = ID:
                end select

            case "^": input_st = mid$(input_st, 2): tok = POWER
            case "*": input_st = mid$(input_st, 2): tok = MULTIPLY
            case "/": input_st = mid$(input_st, 2): tok = DIVIDE
            case "\": input_st = mid$(input_st, 2): tok = INT_DIV
            case "+": input_st = mid$(input_st, 2): tok = ADD
            case "-": input_st = mid$(input_st, 2): tok = SUBTRACT
            case "=": input_st = mid$(input_st, 2): tok = EQUAL
            case "(": input_st = mid$(input_st, 2): tok = LPAREN
            case ")": input_st = mid$(input_st, 2): tok = RPAREN
            case ">": input_st = mid$(input_st, 2): tok = GTR_T
            case "<": input_st = mid$(input_st, 2): tok = LSS_T
            case else: print "Unknown token encountered"
        end select
    end select
end sub

Heater
Posts: 13083
Joined: Tue Jul 17, 2012 3:02 pm

Re: Why Avoid BASIC on RPi?

Wed Apr 17, 2019 12:05 pm

Even more cool. We might have to tighten up the spec a bit for a challenge.

Single character variable names. Number types/sizes. Operator precedence. Some built in functions, sin(), cos(), sqrt() etc. Nothing that will make it overly long code wise.

Hmmm... perhaps it should use big integers.... :)

Meanwhile that Squeak thing for Windows does not work. Crashes all the time.

And this online GNU Smalltalk has the same problem as mine : https://www.tutorialspoint.com/execute_ ... online.php

Code: Select all

a := 100000000000000000000 * 1000000000000000000.
a printNl.
b := 1000000000000000000 * 1000000000000000000.
b printNl.
c := 1000000000000000000 * 100000000000000000.
c printNl.
d := 100000000000000000 * 100000000000000000.
d printNl.
e := 10000000000000000 * 100000000000000000.
e printNl.
f := 1000000000000000 * 100000000000000000.
f printNl.
Produces:

Code: Select all

$gst main.gst
100000000000000000000000000000000000000
1000000000000000000000000000000000000
3136633892082024448
4003012203950112768
4089650035136921600
100000000000000000000000000000000

ejolson
Posts: 3403
Joined: Tue Mar 18, 2014 11:47 am

Re: Why Avoid BASIC on RPi?

Wed Apr 17, 2019 5:51 pm

Heater wrote:
Wed Apr 17, 2019 12:05 pm
Even more cool. We might have to tighten up the spec a bit for a challenge.

Single character variable names. Number types/sizes. Operator precedence. Some built in functions, sin(), cos(), sqrt() etc. Nothing that will make it overly long code wise.
After 40 pages we have returned to a simpler version of this original counter challenge:
DavidS wrote:
Sat Dec 08, 2018 6:30 pm
Now for the Counter challenge (just a quick one):
If actually carried out, such a challenge would result in an ARMful of new Basic languages. As those languages might require additional efforts to avoid, I would recommend a different plan of action. Instead of an O(n logn) implementation of the new Harvey–Van Der Hoeven big-number multiplication algorithm in Basic, how about coding a game?

Since some people have gone to great effort for food safety to keep the mice away from their pies, I now suggest the game require only a terminal interface to play. My only concern is how to render an orange cat as ASCII art.

Heater
Posts: 13083
Joined: Tue Jul 17, 2012 3:02 pm

Re: Why Avoid BASIC on RPi?

Wed Apr 17, 2019 6:24 pm

EdDavis,

Sorry, missed your post. That's a neat parser.

I gave up the expression parser idea as being too messy to do in BASIC. Mind you back in 1975 BASIC was BASIC. It had line numbers FOR..NEXT, GOSUB and GOTOs, none of this structured functions, DO..WHILE, SELECT and so on of modern languages that have BASIC in their name.

Is there a QB64 for the Raspberry Pi?

Heater
Posts: 13083
Joined: Tue Jul 17, 2012 3:02 pm

Re: Why Avoid BASIC on RPi?

Wed Apr 17, 2019 6:27 pm

ejolson,
After 40 pages we have returned to a simpler version of this original counter challenge:
Wow, so we did. Didn't think about it much at the time as I though a whole compiler would be a bit too much.
If actually carried out, such a challenge would result in an ARMful of new Basic languages. As those languages might require additional efforts to avoid, I would recommend a different plan of action.
Oh my God. What have we done?

timrowledge
Posts: 1273
Joined: Mon Oct 29, 2012 8:12 pm
Location: Vancouver Island
Contact: Website

Re: Why Avoid BASIC on RPi?

Wed Apr 17, 2019 8:31 pm

Gavinmc42 wrote:
Wed Apr 17, 2019 6:19 am
If I read the Squeak blurb right, Squeak plus baremetal C, perhaps Circle, could run the VM on baremetal Pi's with GUI?

Have not tried Squeak but if it was supposed to run on PDAs I'm interested ;)
Dynabook :o Wow another blast from the past.
When Kay proposed an extension as this research to Parc's board of directors, his design was well beyond the capabilities of computer hardware and software technology at the time.
Not any more?
I guess every Smartphone and Tablet would be instantly recognized as a Dynabook by Alan.
Yes, Squeak has been run on baremetal devices many times in the past. As have other related Smalltalk systems. Remember the Active Book? (http://www.computinghistory.org.uk/det/ ... it-Boards/ is the only relvant web page I can find right now) That was Smalltalk, as was the contemporaneous Momenta 'tablet'. Back in 1990.
Amongst other things I did a version for the DEC (remember them?) 'itsy' proto-pda that became the Journada etc.

Sadly most modern tablets etc do not really count as dynabooks in any useful way; Alan is not impressed with the way they have become predominantly consumption funnels instead of creation and self-realisation facilitators. I knada gree, though I'd be lost without my iPad.
Making Smalltalk on ARM since 1986; making your Scratch better since 2012

timrowledge
Posts: 1273
Joined: Mon Oct 29, 2012 8:12 pm
Location: Vancouver Island
Contact: Website

Re: Why Avoid BASIC on RPi?

Wed Apr 17, 2019 9:25 pm

Heater wrote:
Wed Apr 17, 2019 7:00 am

1) So I installed squeak to Debian. The LSW on my Win 10 PC that should make no odds.

Code: Select all

$ apt-cache search squeak
Oh, yuck. We really have to get this removed from Debian or make them actually include it properly. They completely and utterly failed to .. .oh, never mind. It's rubbish. Don't use that route.
Download from squeak.org.
Heater wrote:
Wed Apr 17, 2019 7:00 am
4) Against my better judgement I download squeak for Windows from here: https://squeak.org/

Now I have a Squeak.exe. When I run it I get an IDE. I have no idea what to do with it.
If you run visualC++, or eclipse, or any of the python IDEs.... you get the IDE. Why is this a surprise?
Heater wrote:
Wed Apr 17, 2019 7:00 am
Damn thing does not close when I hit the close button. Grrr....
And yet it has a very typical looking menu bar at the top, with a fairly common logo item at the left top corner, that provides a menu which allows saving and exiting. If one uses a tool it is often useful to RTFM at least a little. Even the worst manuals usually manage to give at least some clue about how to quit the system.

I think a part of the problem is that you are wanting to use a well equipped toolbox as a hammer to saw some case-hardened steel. There are easier ways to get use out of the tools...

So anyway, I loaded a karatsuba multiply method someone had kindly written a decade or so ago and it works quite nicely. I see on your gihub repo that the C version with 'hand code karatsuba multiplication' runs the fib(4784969) test in 62secs or thereabouts on a Pi. Was that a Pi 3 or 3b+? Because Squeak runs it in 14secs on my Pi3b+.

In order to ease the pain you obviously suffer from with those nasty windows, try this simple commandline incantation, which requires that you actually have
a) a squeak VM that will be found in your path or whatever mechanism is used
b) a squeak image file which will probably be names something like 'Squeak5.2b-18255-32bit.image'
c) the atttached bigFib.cs Smalltalk chunk file

Then, with any filename substitutions required, run
squeak Squeak5.2b-18255-32bit.image bigFib.cs
It will start up, open the window, load the big fibonacci code and run 4784969 fastDoublingFib and print the time taken to stdout.
bigFib.cs.zip
(3.44 KiB) Downloaded 13 times
I hope that helps.
Making Smalltalk on ARM since 1986; making your Scratch better since 2012

jahboater
Posts: 4598
Joined: Wed Feb 04, 2015 6:38 pm

Re: Why Avoid BASIC on RPi?

Wed Apr 17, 2019 9:56 pm

timrowledge wrote:
Wed Apr 17, 2019 9:25 pm
So anyway, I loaded a karatsuba multiply method someone had kindly written a decade or so ago and it works quite nicely. I see on your gihub repo that the C version with 'hand code karatsuba multiplication' runs the fib(4784969) test in 62secs or thereabouts on a Pi. Was that a Pi 3 or 3b+? Because Squeak runs it in 14secs on my Pi3b+.
The hand coded C version runs in 16 seconds on a Pi3B+ including the printout.
That's including hand written big int stuff in decimal!! (because the printout part is hard if its done in binary).

The C library function (that anyone in their right mind would use) takes:-
$ ./fibo >/dev/null
Calculate: 39ms
Print: 148ms

ejolson
Posts: 3403
Joined: Tue Mar 18, 2014 11:47 am

Re: Why Avoid BASIC on RPi?

Thu Apr 18, 2019 12:07 am

jahboater wrote:
Wed Apr 17, 2019 9:56 pm
timrowledge wrote:
Wed Apr 17, 2019 9:25 pm
So anyway, I loaded a karatsuba multiply method someone had kindly written a decade or so ago and it works quite nicely. I see on your gihub repo that the C version with 'hand code karatsuba multiplication' runs the fib(4784969) test in 62secs or thereabouts on a Pi. Was that a Pi 3 or 3b+? Because Squeak runs it in 14secs on my Pi3b+.
The hand coded C version runs in 16 seconds on a Pi3B+ including the printout.
That's including hand written big int stuff in decimal!! (because the printout part is hard if its done in binary).

The C library function (that anyone in their right mind would use) takes:-
$ ./fibo >/dev/null
Calculate: 39ms
Print: 148ms
This post shows that the time to load, dynamically link, execute the C code and then write the output to a file on a Pi Zero is about 24 seconds. If I have time, I'll try it again on a Pi 3B.

Heater
Posts: 13083
Joined: Tue Jul 17, 2012 3:02 pm

Re: Why Avoid BASIC on RPi?

Thu Apr 18, 2019 12:21 am

Do I have to update the README's in the github repo? I get much better timing fibo(4784969) in C and C++ on a Pi 3. Between 1.1 and 3.6 seconds. Note that we all do karatsuba using arrays of decimal numbers to save the bother of writing code to convert binary big integers to decimal for display. This must be a few times slower than using arrays of binary integers.

Code: Select all

$ cd ../c
[email protected]:~/fibo_4784969/c$ time ./serial | tail -c 32
Using 1 cores.
4856539211500699706378405156269

real    0m3.614s
user    0m3.600s
sys     0m0.020s
[email protected]:~/fibo_4784969/c$ time ./parallel | tail -c 32
Using 4 cores.
4856539211500699706378405156269

real    0m1.143s
user    0m3.673s
sys     0m0.027s
[email protected]:~/fibo_4784969/c$ cd ../c++
$ time ./fibo_karatsuba | tail -c 32
4856539211500699706378405156269

real    0m4.248s
user    0m4.216s
sys     0m0.037s
[email protected]:~/fibo_4784969/c++$ time ./fibo_karatsuba-n-core | tail -c 32
4856539211500699706378405156269

real    0m1.587s
user    0m4.765s
sys     0m0.067s
Last edited by Heater on Thu Apr 18, 2019 3:41 am, edited 1 time in total.

ejolson
Posts: 3403
Joined: Tue Mar 18, 2014 11:47 am

Re: Why Avoid BASIC on RPi?

Thu Apr 18, 2019 2:32 am

Heater wrote:
Thu Apr 18, 2019 12:21 am
Do I have to update the README's in the github repo? I get much better timing fibo(4784969) in C and C++ on a Pi 3. Between 1.1 and 3.6 seconds. Note that we all do karatsuba using arrays of decimal numbers to save the bother of writing code to convert binary big integers to decimal for display. This must be a few times slower than using arrays of binary integers.

Code: Select all

$ cd ../c
[email protected]:~/fibo_4784969/c$ time ./serial | tail -c 32
Using 1 cores.
4856539211500699706378405156269

real    0m3.614s
user    0m3.600s
sys     0m0.020s
[email protected]:~/fibo_4784969/c$ time ./parallel | tail -c 32
Using 4 cores.
4856539211500699706378405156269

real    0m1.143s
user    0m3.673s
sys     0m0.027s
[email protected]:~/fibo_4784969/c$ cd ../c++
[email protected]:~/fibo_4784969/c++$ time ./fibo_karatsuba | tail -c 32
4856539211500699706378405156269

real    0m1.530s
user    0m4.787s
sys     0m0.062s
[email protected]:~/fibo_4784969/c++$ time ./fibo_karatsuba-n-core | tail -c 32
4856539211500699706378405156269

real    0m1.537s
user    0m4.784s
sys     0m0.062s
Both fibo_karatsuba and fibo_karatsuba-n-core appear to be running on all four cores.

Heater
Posts: 13083
Joined: Tue Jul 17, 2012 3:02 pm

Re: Why Avoid BASIC on RPi?

Thu Apr 18, 2019 3:43 am

Well spotted, recompiled, re-timed and corrected above to 4.248 and 1.587 seconds respectively.

Heater
Posts: 13083
Joined: Tue Jul 17, 2012 3:02 pm

Re: Why Avoid BASIC on RPi?

Thu Apr 18, 2019 3:56 am

Tim,
Oh, yuck. We really have to get this removed from Debian or make them actually include it properly. They completely and utterly failed to .. .oh, never mind. It's rubbish. Don't use that route.
Download from squeak.org.
OK, noted.

So I downloaded from squeak.org. It's a bit worrying that their latest source code is from 2012 !!!
From here: http://squeakvm.org/unix/

Never mind, let's continue:

Code: Select all

$ tar -xvzf Squeak-4.10.2.2614-src.tar.gz
$ cd Squeak-4.10.2.2614-src
$ vim README
$ mkdir bld
$ cd bld/
$ cmake/configure --help
$ sudo mkdir /opt/squeak
$ sudo chown pi:pi /opt/squeak
$ ../unix/cmake/configure --prefix=/opt/squeak --without-gl --image64
$ make
$ ./squeakvm64
$ squeak: could not find any display driver
Aborted (core dumped)
No go there.
If you run visualC++, or eclipse, or any of the python IDEs.... you get the IDE.
Well of course, if you use an IDE you get the IDE. Not sure how it's possible any other way.

As it happens I do not use visualC++, or eclipse, or any of the python IDEs. I rarely use any IDE, they are all some combination of huge, slow, complex, non-portable, inconvenient and annoying. I certainly don't have any projects that require an IDE to just build them from source.
Why is this a surprise?
The big surprise is that it seems to be impossible to turn 10 lines of Smalltalk into a running program and get a result without an IDE. Except possibly for GNU Smalltalk which seems to be broken.
And yet it has a very typical looking menu bar at the top, with a fairly common logo item at the left top corner, that provides a menu which allows saving and exiting.
Yes it does. Except none of that shows up or if it does it does not respond after Squeak has crashed. Which has done pretty quickly on every run so far. Requiring it be killed from the Task Manager.
If one uses a tool it is often useful to RTFM at least a little....
You think I haven't done that? Perhaps more on the Smalltalk/Squeak documentation later..
Even the worst manuals usually manage to give at least some clue about how to quit the system.
Yes. But they don't usually tell you what to do when their application has locked up.
I think a part of the problem is that you are wanting to use a well equipped toolbox as a hammer to saw some case-hardened steel.
No, I'm trying to run 10 lines of code on a computer. I don't want a tool box, I just want to run that code from the source I have.
There are easier ways to get use out of the tools...
I'm glad to hear it. Still looking for that easier way...
I see on your gihub repo that the C version with 'hand code karatsuba multiplication' runs the fib(4784969) test in 62secs or thereabouts on a Pi. Was that a Pi 3 or 3b+? Because Squeak runs it in 14secs on my Pi3b+.
That sound like good timing for Squeak. The C/C++ versions are a bit faster, see my post above. But speed is not the primary concern here. Getting my code to run is...

I'll try running your .cs file from the command line after morning coffee.

hippy
Posts: 5765
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Why Avoid BASIC on RPi?

Thu Apr 18, 2019 9:10 am

Heater wrote:
Wed Apr 17, 2019 12:05 pm
Even more cool. We might have to tighten up the spec a bit for a challenge.

Single character variable names. Number types/sizes. Operator precedence. Some built in functions, sin(), cos(), sqrt() etc. Nothing that will make it overly long code wise.
I am not sure how any expression evaluating code would be anything but overly long. I would argue for string and multi-argument functions - Int(Left$(Date$,4)) and the like - to prove it is a capable evaluation engine.

But I must admit I have lost track as to what the actual intent is or how any of this relates to the gist of the original post which appears to be that people shouldn't be avoiding basic.

It seems to have devolved into 'how about this ... ?' with no rhyme or reason.

Return to “Off topic discussion”