• Welcome to Jose's Read Only Forum 2023.
 

O2 compile problem

Started by Ed Davis, July 19, 2022, 02:21:53 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Ed Davis

I'm using co2.exe from: https://github.com/Charles-Pegge/OxygenBasic/blob/master/OxygenBasic040.zip

I have a program that seems to work fine.  However, when I delete a commented out line, I get a syntax error:

ERROR:  undefined type for u
WORD:   string
LINE:
FILE:   "main source"


Here are the code diffs:

Comparing files int.bas and save\int8.bas
***** int.bas
  255:    thech = " ": intch = asc(thech)
  256:    nexttok()
***** save\int8.bas
  255:    thech = " ": intch = asc(thech)
  256:    'print "initlex2: " thelin cr
  257:    nexttok()
*****


int8.bas compiles and runs ok.  int.bas generates the compiler error shown above.  The only difference in the files is the removal of the commented out line, line 256 in int8.bas.

Below is the complete code of the one that does not compile.  For me, simply adding the following:

    'print "initlex2: " thelin cr

after line 255 allows it to compile.

'Ed Davis. Tiny Basic that can play Star Trek
'Supports: end, list, load, new, run, save
'gosub/return, goto, if, input, print, multi-statement lines (:)
'a single numeric array: @(n), and rnd(n)

'$Filename "int.exe"
includepath "$\inc\"
include "console.inc"

#lookahead

const as integer c_maxlines = 7000, c_maxvars = 26, c_at_max = 1000, c_g_stack = 100, false = 0, true = 1

dim pgm(c_maxlines) as string         ' program stored here
dim vars(c_maxvars) as integer        ' variable store
dim gstackln(c_g_stack) as integer    ' gosub line stack
dim gstacktp(c_g_stack) as integer    ' gosub textp stack
dim gsp as integer                    ' gosub stack index
dim atarry(c_at_max) as integer       ' the @ array

dim tok as string, toktype as string    ' current token, and it's type
dim thelin as string, thech as string   ' current program line, current character
dim intch as integer
dim curline as integer, textp as integer ' position in current line
dim num as integer   ' last number read by scanner
dim errors as boolean

dim timestart as double

call main()

sub main()
  gsp = 0
  do
    errors = false
    print("> ")
    pgm(0) = myinput()
    if pgm(0) <> "" then
      initlex(0)
      if toktype = "number" then
        validlinenum()
        pgm(num) = mid(pgm(0), textp, len(pgm(0)) - textp + 1)
      else
        if not docmd() then exit sub
      end if
    end if
  loop
end sub

function docmd() as boolean
  do
    if accept("bye") or accept("quit") then
      return false
    elseif accept("end") or accept("stop") then
      return true
    elseif accept("list")    then
      liststmt(): return true
    elseif accept("run")     then
      runstmt()
    elseif accept("goto")    then
      gotostmt()
    elseif accept("if")      then
      ifstmt()
    elseif accept("print") or accept("?") then
      call printstmt()
    elseif accept("@") then
      arrassn()
    elseif accept(":") then
      ' just continue
    elseif toktype = "ident" then
      assign()
    elseif tok = "" then
      ' handled below
    else
      print "unknown command: " tok cr: return true
    end if
    if errors then return true
    if curline > c_maxlines then return true
    while tok = ""
      if curline = 0 or curline >= c_maxlines then return true
      initlex(curline + 1)
    end while
  loop
end function

sub assign()
  dim var as integer
  var = getvarindex(): nexttok()
  expect("=")
  vars(var) = expression(0)
end sub

sub arrassn()   ' array assignment: @(expr) = expr
  dim n as integer, atndx as integer

  atndx = parenexpr()
  if tok <> "=" then
    print "Array Assign: Expecting '=', found: " & tok & cr: errors = true
  else
    nexttok()     ' skip the "="
    n = expression(0)
    atarry(atndx) = n
  end if
end sub

sub ifstmt()
  dim b as boolean
  if expression(0) = 0 then skipx(): exit sub
  b = accept("then")      ' "then" is optional
  if toktype = "number" then gotostmt()
end sub

sub liststmt()
  dim i as integer
  for i = 1 to c_maxlines
    if pgm(i) <> "" then print i & " " & pgm(i) & cr
  next i
  print cr
end sub

sub printstmt
  dim printnl as boolean

  printnl = true
  while tok <> ":" and tok <> ""
    printnl = true

    if toktype = "string" then
      print mid(tok, 2)
      nexttok()
    else
      print ltrim(str(expression(0)))
    end if

    if accept(",") then
      print " "
      printnl = false
    elseif accept(";") then
      printnl = false
    else
      exit do
    end if
  end while

  if printnl then print " " cr
end sub

sub runstmt()
  clearvars()
  initlex(1)
end sub

sub gotostmt()
  num = expression(0)
  validlinenum()
  initlex(num)
end sub

sub validlinenum()
  if num <= 0 or num > c_maxlines then print "Line number out of range" & cr: errors = true
end sub

sub clearvars()
  dim i as integer

  for i = 1 to c_maxvars
    vars(i) = 0
  next i
  gsp = 0
end sub

function parenexpr() as integer
  dim n as integer

  expect("("): if errors then return 0
  n = expression(0)
  expect(")")
  return n
end function

function expression(minprec as integer) as integer
  dim n as integer

  ' handle numeric operands - numbers and unary operators
  if accept("-") then
    n = -expression(4)
  elseif accept("+") then
    n =  expression(4)
  elseif tok = "("  then
    n =  parenexpr()
  elseif accept("rnd") then
    n = rnd() * parenexpr()
  elseif toktype = "number" then
    n = num: nexttok()
  elseif toktype = "ident"  then
    n = vars(getvarindex()): nexttok()
  elseif accept("@")  then
    n = atarry(parenexpr())
  else
    print "syntax error: expecting an operand, found: " tok & cr: errors = true: return 0
  end if

  do  ' while binary operator and precedence of tok >= minprec
    if minprec <= 1 and tok = "="  then
      nexttok(): n = Convert.ToInt32(n =  expression(2))
    elseif minprec <= 1 and tok = "<"  then
      nexttok(): n = Convert.ToInt32(n <  expression(2))
    elseif minprec <= 1 and tok = ">"  then
      nexttok(): n = Convert.ToInt32(n >  expression(2))
    elseif minprec <= 1 and tok = "<>" then
      nexttok(): n = Convert.ToInt32(n <> expression(2))
    elseif minprec <= 1 and tok = "<=" then
      nexttok(): n = Convert.ToInt32(n <= expression(2))
    elseif minprec <= 1 and tok = ">=" then
      nexttok(): n = Convert.ToInt32(n >= expression(2))
    elseif minprec <= 2 and tok = "+"  then
      nexttok(): n = n +  expression(3)
    elseif minprec <= 2 and tok = "-"  then
      nexttok(): n = n -  expression(3)
    elseif minprec <= 3 and tok = "*"  then
      nexttok(): n = n *  expression(4)
    elseif minprec <= 3 and tok = "/"  then
      nexttok(): n = n \  expression(4)
    else
      exit do
    end if
  loop

  return n
end function

function getvarindex() as integer
  if toktype <> "ident" then print "Not a variable:" & tok cr: errors = true: return 0
  return asc(left(tok, 1)) - asc("a")
end function

sub expect(s as string)
  if accept(s) then exit sub
  print "expected: " s cr: errors = true
end sub

function accept(s as string) as boolean
  if tok = s then nexttok(): return true
  return false
end function

sub initlex(n as integer)
  curline = n
  textp = 1
  initlex2()
end sub

sub initlex2()
  thelin = pgm(curline)
  thech = " ": intch = asc(thech)
  nexttok()
end sub

sub skipx()
'print "in skip" cr: getkey()
  tok = "": toktype = "": thech = "": intch = -1
  textp = len(thelin) + 1
  'print "skipping " cr
end sub

sub nexttok()
'print "nexttok, thelin:" thelin cr
  tok = "": toktype = ""
  do
    if thech = "" then exit sub
    if intch > asc(" ") then exit do
    getch()
  loop

  toktype = "punct"
  tok = thech + mid(thelin, textp, 1)
  if tok = ">=" or tok = "<=" or tok = "<>" then
    getch(): getch(): exit sub
  end if

  'print "nexttok before instr: " tok cr

  tok = left(tok, 1)
  if instr("()*+,-/:;<=>?@", tok) > 0 then getch(): exit sub

  if tok = chr(34) then readstr(): exit sub    ' double quote

  'print "nexttok before ident: " tok cr

  if (intch >= asc("a") and intch <= asc("z")) or (intch >= asc("A") and intch <= asc("Z")) then
    readident()
    if tok = "rem" then skipx()
    exit sub
  end if

  'print "nexttok before readint: " tok cr

  if intch >= asc("0") and intch <= asc("9") then readint(): exit sub

  'print "nexttok before chr(39): " tok cr

  if tok = chr(39) then skipx(): exit sub  'single quote

  toktype = ""
  print "What?" chr(intch) thelin cr: getch(): errors = true
  getkey()
end sub

' leave the " as the beginning of the string, so it won't get confused with other tokens
' especially in the print routines
sub readstr()
  toktype = "string"
  getch()
  do
    if thech = "" then print "String not terminated" cr: errors = true: exit sub
    if thech = chr(34) then exit do
    tok = tok + thech
    getch()
  loop
  getch()
  'print "readstr: " tok cr
end sub

sub readint()
  tok = "": toktype = "number"
  do
    if intch = -1 then exit do
    if intch >= asc("0") and intch <= asc("9") then
      tok = tok + thech
      getch()
    else
      exit do
    end if
  loop
  num = val(tok)
  'print "readint: " tok " " num cr
end sub

sub readident()
'print "in readident:" cr
  tok = "": toktype = "ident"
  do
    if intch = -1 then exit do
    if (intch >= asc("a") and intch <= asc("z")) or (intch >= asc("A") and intch <= asc("Z")) then
      tok = tok + lcase(thech)
      'print "readident - concat: " tok
      'getkey(): print cr
      getch()
    else
      exit do
    end if
  loop
  'print "readident: " tok
  'print cr
end sub

sub getch()
'print("in getch")
  ' Any more text on this line?
  if textp > len(thelin) then thech = "": intch = -1: exit sub
  thech = mid(thelin, textp, 1)
  intch = asc(thech)
  textp = textp + 1
end sub

function myinput() as string
  string s
'  print "myinput" cr
'  getkey()
  s = input()
  s = left(s, len(s) - 2)
  return s
end function

function rnd() as integer
  return 42
end function


Thanks for any help!

Charles Pegge

Hi Ed,

could you try using equates or defs instead of consts and see if that makes any difference:


''const as integer c_maxlines = 7000, c_maxvars = 26, c_at_max = 1000, c_g_stack = 100, false = 0, true = 1
% c_maxlines = 7000
% c_maxvars  = 26
% c_at_max   = 1000
% c_g_stack  = 100
% false      = 0
% true       = 1


I'm currently reviewing constants for version 050. They give me a semantic headache. Are they like equates or are they like immutable variables which have a one time assignment at run-time ?


Ed Davis

Quote from: Charles Pegge on July 19, 2022, 12:22:53 PM
could you try using equates or defs instead of consts and see if that makes any difference:

Yep, that fixed it!  Thanks!