'======================================================================
'   Cheesecake BASIC interpreter
'
'   Copyright (C) 1999  Ramon J. San Andres
'
'   Contact: mnitesoft@aol.com
'            http://members.aol.com/mnitesoft
'
'   This program is free software; you can redistribute it and/or
'   modify it under the terms of the GNU General Public License
'   as published by the Free Software Foundation; either version 2
'   of the License, or (at your option) any later version.
'
'   This program is distributed in the hope that it will be useful,
'   but WITHOUT ANY WARRANTY; without even the implied warranty of
'   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  See the
'   GNU General Public License for more details.
'
'   You should have received a copy of the GNU General Public License
'   along with this program; if not, write to the Free Software
'   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
'======================================================================
DECLARE SUB ArgMemGet(PTR AS INTEGER, Value AS ANY)
DECLARE SUB ArgMemSet(PTR AS INTEGER, Value AS ANY)
DECLARE SUB FactorStackInit()
DECLARE FUNCTION FactorStackPop! (Value AS ANY)
DECLARE FUNCTION FactorStackPush! (Value AS ANY)
DECLARE FUNCTION FuncStackGet!( FuncData AS ANY )
DECLARE FUNCTION FuncStackIsEmpty!()
DECLARE FUNCTION FuncStackPop! (FuncData AS ANY)
DECLARE FUNCTION FuncStackPush! (FuncData AS ANY)
DECLARE FUNCTION InKeyBufGet$()
DECLARE SUB InKeyBufSet(s AS STRING)
DECLARE FUNCTION KeyTrapTargetGet(PTR AS INTEGER)
DECLARE SUB KeyTrapTargetSet(PTR AS INTEGER, Target AS INTEGER)
DECLARE FUNCTION KeyOnGet(PTR AS INTEGER)
DECLARE SUB KeyOnSet(PTR AS INTEGER, Value AS INTEGER)
DECLARE SUB Init (InitFlag AS INTEGER)
DECLARE SUB LoopStackInit()
DECLARE FUNCTION LoopStackPop! (ls AS ANY)
DECLARE FUNCTION LoopStackPush! (ls AS ANY)
DECLARE FUNCTION LoopStackTopData!( LoopData AS ANY)
DECLARE SUB RetStackInit()
DECLARE FUNCTION RetStackPop! (PgmLoc AS ANY)
DECLARE FUNCTION RetStackPush! (PgmLoc AS ANY)
DECLARE SUB SetPgmCur (PgmPtr AS INTEGER)
DECLARE FUNCTION SymbolToDataType% (Symbol AS STRING)
DECLARE SUB SysDump (FileNum AS INTEGER)
'
'   Misc
'
DECLARE SUB CloseLoadFile ()
DECLARE SUB DoKeyTrapping ()
DECLARE SUB DoTimerTrapping ()
DECLARE SUB ErrorDisplay (Code AS INTEGER)
DECLARE SUB ErrorHit (Code AS INTEGER)
DECLARE FUNCTION ErrorText$ (Code AS INTEGER)
DECLARE SUB ListPgm (Dev AS INTEGER, FirstLine AS INTEGER, LastLine AS INTEGER)
DECLARE SUB LoadBrkData ()
'
'   Interpreter
'
DECLARE SUB InterpBrk (Tkn AS INTEGER)
DECLARE SUB InterpDebug ()
DECLARE SUB InterpDump ()
DECLARE SUB InterpGetLine ()
DECLARE SUB InterpLine ()
DECLARE SUB InterpList ()
DECLARE SUB InterpLoad ()
DECLARE SUB InterpNew ()
DECLARE SUB InterpRenum ()
DECLARE SUB Interpreter ()
DECLARE SUB InterpRun (Flag AS INTEGER)
DECLARE SUB InterpSave ()
DECLARE SUB InterpTrace ()
'
'   Lexer
'
DECLARE SUB LexAdvance (Count AS INTEGER)
DECLARE SUB LexAlpha ()
DECLARE FUNCTION LexGetInputToken! ()
DECLARE FUNCTION LexGetToken! ()
DECLARE SUB LexLiteral ()
DECLARE FUNCTION LexLookAhead$ (Count AS INTEGER)
DECLARE SUB LexNumeric ()
DECLARE SUB LexPreLex ()
DECLARE SUB LexRelop ()
DECLARE SUB LexSetToken (Tkn AS INTEGER, Value AS ANY)
DECLARE SUB LexSkipBlanks ()
DECLARE SUB LexSymbol (Symbol AS STRING)
DECLARE FUNCTION LexTokenStr$ ()
DECLARE SUB LexUngetToken ()
'
'   Parser
'
DECLARE FUNCTION ApplyOperator! (Cmd AS INTEGER, Tkn AS INTEGER, v1 AS ANY, v2 AS ANY, vRes AS ANY)
DECLARE FUNCTION ArgMemAlloc! (Size AS INTEGER)
DECLARE FUNCTION ArgMemDealloc! (Size AS INTEGER)
DECLARE SUB BreakPoint (s AS STRING)
DECLARE FUNCTION CastToReal! (Value AS ANY)
DECLARE FUNCTION CorrectOp! (Level AS INTEGER, Tkn AS INTEGER)
DECLARE FUNCTION EvalFunc! (SymPtr AS INTEGER, vArgs() AS ANY)
DECLARE FUNCTION EvalLoopCondition! (Execute AS INTEGER)
DECLARE FUNCTION ExecGoSub! (LineNumber AS INTEGER)
DECLARE FUNCTION ExecGoTo! (LineNumber AS INTEGER)
DECLARE FUNCTION GetReadData! (Buffer AS STRING, Offset AS INTEGER)
DECLARE FUNCTION ParseArgList! (Cmd AS INTEGER, MaxArg AS INTEGER, cArgs AS INTEGER, vArgs() AS ANY)
DECLARE FUNCTION ParseBlock! (Cmd AS INTEGER)
DECLARE FUNCTION ParseClose! (Cmd AS INTEGER)
DECLARE FUNCTION ParseCoLoc! (Cmd AS INTEGER, Token AS INTEGER)
DECLARE FUNCTION ParseColor! (Cmd AS INTEGER)
DECLARE FUNCTION ParseData! (Cmd AS INTEGER)
DECLARE FUNCTION ParseDef! (Cmd AS INTEGER)
DECLARE FUNCTION ParseDim! (Cmd AS INTEGER)
DECLARE FUNCTION ParseExp! (Cmd AS INTEGER)
DECLARE FUNCTION ParseFactor! (Cmd AS INTEGER)
DECLARE FUNCTION ParseField! (Cmd AS INTEGER)
DECLARE FUNCTION ParseFInstr! (Cmd AS INTEGER)
DECLARE FUNCTION ParseFMid! (Cmd AS INTEGER)
DECLARE FUNCTION ParseFor! (Cmd AS INTEGER)
DECLARE FUNCTION ParseFunc! (Cmd AS INTEGER, FuncName AS STRING)
DECLARE FUNCTION ParseGetPutSeek! (Cmd AS INTEGER, Tkn AS INTEGER)
DECLARE FUNCTION ParseGo! (Cmd AS INTEGER, Tkn AS INTEGER)
DECLARE FUNCTION ParseIf! (Cmd AS INTEGER)
DECLARE FUNCTION ParseInput! (Cmd AS INTEGER, Mode AS INTEGER)
DECLARE FUNCTION ParseIntExp! (Cmd AS INTEGER, IntValue AS INTEGER)
DECLARE FUNCTION ParseIntFStr! (Cmd AS INTEGER, Tkn AS INTEGER)
DECLARE FUNCTION ParseIntF! (Cmd AS INTEGER, Tkn AS INTEGER)
DECLARE FUNCTION ParseIntFNum! (Cmd AS INTEGER, Tkn AS INTEGER)
DECLARE FUNCTION ParseKeyTimer! (Cmd AS INTEGER, Tkn AS INTEGER)
DECLARE FUNCTION ParseLet! (Cmd AS INTEGER, Token AS INTEGER)
DECLARE FUNCTION ParseNext! (Cmd AS INTEGER)
DECLARE FUNCTION ParseNumFNum! (Cmd AS INTEGER, Tkn AS INTEGER)
DECLARE FUNCTION ParseOn! (Cmd AS INTEGER)
DECLARE FUNCTION ParseOnError! (Cmd AS INTEGER)
DECLARE FUNCTION ParseOnExp! (Cmd AS INTEGER)
DECLARE FUNCTION ParseOnKeyTimer! (Cmd AS INTEGER, Tkn AS INTEGER)
DECLARE FUNCTION ParseOpen! (Cmd AS INTEGER)
DECLARE FUNCTION ParsePrint! (Cmd AS INTEGER)
DECLARE FUNCTION ParseRandomize! (Cmd AS INTEGER)
DECLARE FUNCTION ParseRealExp! (Cmd AS INTEGER, RealValue AS SINGLE)
DECLARE FUNCTION ParseRealF! (Cmd AS INTEGER, Tkn AS INTEGER)
DECLARE FUNCTION ParseRealFNum! (Cmd AS INTEGER, Tkn AS INTEGER)
DECLARE FUNCTION ParseResRet! (Cmd AS INTEGER, Tkn AS INTEGER)
DECLARE FUNCTION ParseRestore! (Cmd AS INTEGER)
DECLARE FUNCTION ParseRValue! (Cmd AS INTEGER, Symbol AS STRING)
DECLARE FUNCTION ParseShell! (Cmd AS INTEGER, Tkn AS INTEGER)
DECLARE FUNCTION ParseSimple! (Cmd AS INTEGER, Tkn AS INTEGER)
DECLARE FUNCTION ParseStatement! (Cmd AS INTEGER)
DECLARE FUNCTION ParseStmt1Arg! (Cmd AS INTEGER, Tkn AS INTEGER)
DECLARE FUNCTION ParseStop! (Cmd AS INTEGER, Tkn AS INTEGER)
DECLARE FUNCTION ParseStrExp! (Cmd AS INTEGER, str AS STRING)
DECLARE FUNCTION ParseStrF! (Cmd AS INTEGER, Tkn AS INTEGER)
DECLARE FUNCTION ParseStrFNum! (Cmd AS INTEGER, Tkn AS INTEGER)
DECLARE FUNCTION ParseStrFStr! (Cmd AS INTEGER, Tkn AS INTEGER)
DECLARE FUNCTION ParseTerm! (Cmd AS INTEGER, Level AS INTEGER)
DECLARE FUNCTION ParseWend! (Cmd AS INTEGER)
DECLARE FUNCTION ParseWhile! (Cmd AS INTEGER)
DECLARE FUNCTION RenumPatch! (Offset AS INTEGER)
DECLARE FUNCTION SkipLoopBlock! ()
'
'   Memory
'
DECLARE FUNCTION MemAlloc (DataType AS INTEGER, Size AS INTEGER)
DECLARE SUB MemDump (FileNum AS INTEGER)
DECLARE FUNCTION MemGet (DataType AS INTEGER, MemPtr AS INTEGER, Value AS ANY)
DECLARE SUB MemInit ()
DECLARE FUNCTION MemSet (MemPtr AS INTEGER, Value AS ANY)
'
'   Symbol Table
'
DECLARE FUNCTION SymTabAdd! (Symbol AS STRING, SymbolType AS INTEGER, Flags AS INTEGER)
DECLARE FUNCTION SymTabAddField! (Symbol AS STRING, FileNumber AS INTEGER, Offset AS INTEGER, Length AS INTEGER)
DECLARE FUNCTION SymTabAddFunc! (Symbol AS STRING, FuncType AS INTEGER, cParam AS INTEGER, Param() AS STRING, FuncExp AS STRING)
DECLARE FUNCTION SymTabAddVar (Symbol AS STRING, SymbolType AS INTEGER, Flags AS INTEGER, DataType AS INTEGER, Dimensions AS INTEGER, Sizes() AS INTEGER)
DECLARE FUNCTION SymTabAlloc! ()
DECLARE SUB SymTabDump (FileNum AS INTEGER)
DECLARE SUB SymTabEntry(PTR AS INTEGER, SymData AS ANY)
DECLARE FUNCTION SymTabFind! (Symbol AS STRING)
DECLARE FUNCTION SymTabGet! (Symbol AS STRING, cArgs AS INTEGER, vArgs() AS ANY, Value AS ANY)
DECLARE SUB SymTabInit ()
DECLARE FUNCTION SymTabOffset! (PTR AS INTEGER, cArgs AS INTEGER, vArgs() AS ANY)
DECLARE FUNCTION SymTabSet! (Symbol AS STRING, cArgs AS INTEGER, vArgs() AS ANY, Value AS ANY)
DECLARE FUNCTION SymTabValidateSymbol! (Symbol AS STRING)
'
'   File handling
'
DECLARE FUNCTION FileAddFields! (FileNumber AS INTEGER, cFields AS INTEGER, FieldSizes() AS INTEGER, FieldNames() AS STRING)
DECLARE FUNCTION FileClean! (FileNumber AS INTEGER)
DECLARE FUNCTION FileFieldGet! (FileNumber AS INTEGER, Offset AS INTEGER, Length AS INTEGER, Value AS ANY)
DECLARE FUNCTION FileFieldSet! (FileNumber AS INTEGER, Offset AS INTEGER, Length AS INTEGER, Value AS ANY)
DECLARE FUNCTION FileIsOpen(FileNumber AS INTEGER)
DECLARE FUNCTION FileReadBuf(FileNumber AS INTEGER)
DECLARE FUNCTION FileSeek(FileNumber AS INTEGER, RecNum AS INTEGER)
DECLARE FUNCTION FileSet(FileNumber AS INTEGER, FileData AS ANY)
DECLARE FUNCTION FileWriteBuf(FileNumber AS INTEGER)
DECLARE FUNCTION FileValidateAccess! (FileNumber AS INTEGER, Mode AS INTEGER)
'
'   Program memory
'
DECLARE FUNCTION PgmMemAlloc! ()
DECLARE FUNCTION PgmMemBuf$(PTR AS INTEGER)
DECLARE FUNCTION PgmMemBufLen!(PTR AS INTEGER)
DECLARE SUB PgmMemDealloc (PTR AS INTEGER)
DECLARE SUB PgmMemDelete (PTR AS INTEGER)
DECLARE FUNCTION PgmMemFind! (LineNumber AS INTEGER)
DECLARE FUNCTION PgmMemFindPos! (LineNumber AS INTEGER, PrevPtr AS INTEGER)
DECLARE SUB PgmMemGet(PTR AS INTEGER, PgmData AS ANY)
DECLARE SUB PgmMemInit ()
DECLARE SUB PgmMemInsert (PTR AS INTEGER)
DECLARE FUNCTION PgmMemLineNum!(PTR AS INTEGER)
DECLARE FUNCTION PgmMemNext!(PTR AS INTEGER)
DECLARE FUNCTION PgmMemProgram!()
DECLARE SUB PgmMemSet(PTR AS INTEGER, PgmData AS ANY)


'======================================================================
'
'   Constants
'
'======================================================================

CONST FALSE = 0
CONST TRUE = NOT FALSE
CONST NILPOINTER = -1           ' Invalid pseudo-pointer
'
' Version Information
'
CONST MyName = "Cheesecake BASIC"
CONST MyAuthor = "Ramon San Andres"
CONST MyEmail = "mnitesoft@aol.com"
CONST MyWeb = "http://members.aol.com/mnitesoft"
CONST MySource = "QB4.5"
CONST MyVersionMajor = 0
CONST MyVersionMinor = 1
CONST MyVersionRev = 0
'
' Supported data types
'
CONST TYPEINT = 1               '   Integer
CONST TYPEREAL = 2              '   Real (Single in QuickBasic)
CONST TYPESTR = 3               '   String
'
'   Interpreter limits
'
CONST MAXMEMINT = 500           '   Size of Integer memory
CONST MAXMEMREAL = 500          '   Size of Real memory
CONST MAXMEMSTR = 500           '   Size of String memory
CONST MAXSTRLEN = 128           '   Maximum string length
CONST MAXMEMPGM = 500           '   Size of Program memory
CONST MAXPGMBUFLEN = 168        '   Maximum size of Program memory buffer
CONST MAXSTACKRET = 10          '   Size of return stack
CONST MAXSTACKLOOP = 5          '   Size of loop stack
CONST MAXSTACKFACTOR = 10       '   Size of factor stack
CONST MAXFILES = 3              '   Maximum number of files
CONST MAXFILEREC = 3            '   Maximum record structures per file
CONST MAXFILEFIELD = 5          '   Maximum fields per record structure
CONST MAXFILEBUFLEN = 256       '   Maximum size of file buffer
CONST MAXRECORDS = (MAXFILES * MAXFILEREC)      ' Total number of records
CONST MAXFIELDS = (MAXRECORDS * MAXFILEFIELD)   ' Total number of fields
CONST MAXDIMENSIONS = 3         '   Maximum dimensions in array
CONST MAXSYMTABLE = 150         '   Size of symbol table
CONST MAXSYMLEN = 16            '   Maximum length of a symbol
CONST INKEYBUFLEN = 128         '   Size of INKEY$ Buffer
CONST MAXDEFPARAM = 4           '   Max parameters in a user function
CONST MAXSTACKFUNC = 4          '   Maximum nesting of user functions
CONST MAXMEMARG = (MAXSTACKFUNC * MAXDEFPARAM)    ' Total number of arguments
'
'   Errors
'
CONST ERRORINTERNAL = 100
CONST ERRORNOMEMORY = 101
CONST ERRORINVALIDMEMACCESS = 102
CONST ERRORINVALIDSUBSCRIPT = 103
CONST ERRORSUBSCRIPTOUTOFRANGE = 104
CONST ERRORSYNTAX = 105
CONST ERRORTYPEMISMATCH = 106
CONST ERRORUNDEFINEDSYMBOL = 107
CONST ERRORLABELNOTFOUND = 108
CONST ERRORINVALIDINCREMENT = 109
CONST ERRORINVALIDLOOPNESTING = 110
CONST ERRORINVALIDKEYNUMBER = 111
CONST ERRORKEYTRAPPINGNOTENABLED = 112
CONST ERRORINVALIDFILENUMBER = 113
CONST ERRORFILENOTOPEN = 114
CONST ERRORINVALIDACCESS = 115
CONST ERRORTOOMANYINPUT = 116
CONST ERRORINVALIDCOORDINATE = 117
CONST ERRORMAXFIELDS = 118
CONST ERRORBADRECORDLEN = 119
CONST ERRORTOOMANYRECORDS = 120
CONST ERRORTOOMANYFIELDS = 121
CONST ERRORBADNUMARG = 122
CONST ERRORSTACKOVERFLOW = 123
CONST ERRORSTACKEMPTY = 124
CONST ERRORNOMOREDATA = 125
CONST ERRORNOTIMERTRAP = 126
CONST ERRORSYMBOLDEFINED = 127
CONST ERRORFORNONEXT = 128
CONST ERRORWHILENOWEND = 129
CONST ERRORCANNOTCONT = 130
'
'   TOKENS
'
CONST TOKENBYE = 100            '   BYE
CONST TOKENDEBUG = 101          '   DEBUG
CONST TOKENDUMP = 102           '   DUMP
CONST TOKENLIST = 103           '   LIST
CONST TOKENLOAD = 104           '   LOAD
CONST TOKENNEW = 105            '   NEW
CONST TOKENRENUM = 106          '   RENUM
CONST TOKENRUN = 107            '   RUN
CONST TOKENSAVE = 108           '   SAVE
CONST TOKENTRACE = 109          '   TRACE
CONST TOKENBRK = 120            '   BRK
CONST TOKENCBRK = 121           '   CBRK
CONST TOKENCONT = 122           '   CONT

CONST TOKENAS = 200             '   AS
CONST TOKENBEEP = 201           '   BEEP
CONST TOKENCHDIR = 202          '   CHDIR
CONST TOKENCLOSE = 203          '   CLOSE
CONST TOKENCLS = 204            '   CLS
CONST TOKENCOLOR = 205          '   COLOR
CONST TOKENDATA = 206           '   DATA
CONST TOKENDEF = 207            '   DEF
CONST TOKENDIM = 208            '   DIF
CONST TOKENELSE = 209           '   ELSE
CONST TOKENEND = 220            '   TOKENEND
CONST TOKENERROR = 221          '   ERROR
CONST TOKENFIELD = 222          '   FIELD
CONST TOKENFOR = 223            '   FOR
CONST TOKENGET = 224            '   GET
CONST TOKENGOSUB = 225          '   GOSUB
CONST TOKENGOTO = 226           '   GOTO
CONST TOKENIF = 227             '   IF
CONST TOKENINPUT = 228          '   INPUT
CONST TOKENKEY = 229            '   KEY
CONST TOKENLET = 240            '   LET
CONST TOKENLSET = 241           '   LSET
CONST TOKENRSET = 242           '   RSET
CONST TOKENLINE = 243           '   LINE
CONST TOKENLOCATE = 244         '   LOCATE
CONST TOKENNEXT = 245           '   NEXT
CONST TOKENON = 246             '   ON
CONST TOKENOFF = 247            '   OFF
CONST TOKENOPEN = 248           '   OPEN
CONST TOKENPRINT = 249          '   PRINT
CONST TOKENPUT = 260            '   PUT
CONST TOKENRANDOMIZE = 261      '   RANDOMIZE
CONST TOKENREAD = 262           '   READ
CONST TOKENREM = 263            '   REM
CONST TOKENRESTORE = 264        '   RESTORE
CONST TOKENRESUME = 265         '   RESUME
CONST TOKENRETURN = 266         '   RETURN
CONST TOKENSEEK = 267           '   SEEK
CONST TOKENSHELL = 268          '   SHELL
CONST TOKENSLEEP = 269          '   SLEEP
CONST TOKENSTEP = 280           '   STEP
CONST TOKENSTOP = 281           '   STOP
CONST TOKENTHEN = 282           '   THEN
CONST TOKENTIMER = 283          '   TIMER
CONST TOKENTO = 284             '   TO
CONST TOKENWEND = 285           '   WEND
CONST TOKENWHILE = 286          '   WHILE
CONST TOKENCONSTANT = 287       '   Constant
CONST TOKENVARIABLE = 288       '   Variable
CONST TOKENSYM = 289            '   SYM
CONST TOKENMEM = 290            '   MEM
CONST TOKENSYS = 291            '   SYS

CONST TOKENAND = 300            '   AND
CONST TOKENOR = 301             '   OR
CONST TOKENNOT = 302            '   NOT
CONST TOKENPLUS = 303           '   +
CONST TOKENMINUS = 304          '   -
CONST TOKENSTAR = 305           '   *
CONST TOKENSLASH = 306          '   /
CONST TOKENBSLASH = 307         '   \
CONST TOKENCARET = 308          '   ^
CONST TOKENEQ = 309             '   =
CONST TOKENNEQ = 310            '   <>
CONST TOKENLT = 311             '   <
CONST TOKENGT = 312             '   >
CONST TOKENLEQ = 313            '   <=
CONST TOKENGEQ = 314            '   >=
CONST TOKENMOD = 315            '   MOD

CONST TOKENOPENPAREN = 400      '   (
CONST TOKENCLOSEPAREN = 401     '   )
CONST TOKENPOUND = 402          '   #
CONST TOKENSEP = 403            '   :
CONST TOKENQUOTE = 404          '   "
CONST TOKENCOMMA = 405          '   ,
CONST TOKENSEMICOLON = 406      '   ;
CONST TOKENEOL = 450            '   End of line

CONST TOKENOUTPUT = 500         '   OUTPUT
CONST TOKENAPPEND = 501         '   APPEND
CONST TOKENRANDOM = 502         '   RANDOM

CONST TOKENFABS = 600           '   ABS
CONST TOKENFASC = 601           '   ASC
CONST TOKENFATN = 602           '   ATN
CONST TOKENFCHR = 603           '   CHR$
CONST TOKENFCINT = 604          '   CINT
CONST TOKENFCOS = 605           '   COS
CONST TOKENFCVI = 606           '   CVI
CONST TOKENFCVS = 607           '   CVS
CONST TOKENFDATE = 608          '   DATE$
CONST TOKENFEOF = 609           '   EOF
CONST TOKENFERL = 620           '   ERL
CONST TOKENFERR = 621           '   ERR
CONST TOKENFERT = 622           '   ERT
CONST TOKENFEXP = 623           '   EXP
CONST TOKENFFIX = 624           '   FIX
CONST TOKENFINKEY = 625         '   INKEY$
CONST TOKENFINSTR = 626         '   INSTR
CONST TOKENFINT = 627           '   INT
CONST TOKENFLCASE = 628         '   LCASE$
CONST TOKENFLEFT = 629          '   LEFT$
CONST TOKENFLEN = 640           '   LEN
CONST TOKENFLOC = 641           '   LOC
CONST TOKENFLOF = 642           '   LOF
CONST TOKENFLOG = 643           '   LOG
CONST TOKENFLTRIM = 644         '   LTRIM$
CONST TOKENFMID = 645           '   MID$
CONST TOKENFMKI = 646           '   MKI$
CONST TOKENFMKS = 647           '   MKS$
CONST TOKENFRIGHT = 648         '   RIGHT$
CONST TOKENFRND = 649           '   RND
CONST TOKENFRTRIM = 660         '   RTRIM$
CONST TOKENFSEEK = 661          '   SEEK
CONST TOKENFSIN = 662           '   SIN
CONST TOKENFSQR = 663           '   SQR
CONST TOKENFSTR = 664           '   STR$
CONST TOKENFTIME = 665          '   TIME
CONST TOKENFUCASE = 667         '   UCASE$
CONST TOKENFVAL = 668           '   VAL
CONST TOKENFUSERDEF = 669       '   User-defined function
CONST TOKENFCURSORY = 670       '   CURSORY
CONST TOKENFCURSORX = 671       '   CURSORX

CONST TOKENUNKNOWN = 1000       '   Unknown
'
'   Init flags
'
CONST INITFILES = 1
CONST INITSTACKS = 2
CONST INITTRAP = 4
CONST INITDATA = 8
CONST INITSYMTAB = 16
CONST INITALLSYM = 32
CONST INITPGM = 64
CONST INITRUN = (INITFILES + INITSTACKS + INITTRAP + INITDATA)
CONST INITCLEAR = (INITRUN + INITSYMTAB)
CONST INITNEW = (INITCLEAR + INITALLSYM + INITPGM)
'
'   PGM Flags
'
CONST PGMFLAGDATA = 1                           '   Line has DATA
CONST PGMFLAGBRK = 2                            '   Line has breakpoint
'
'   Symbol table flags
'
CONST SYMFLAGARRAY = 1                          '   Symbol is an array
CONST SYMFLAGFIELD = 2                          '   Symbol is a file field
                                                '       NOTE:   If symbol is a file field, then
                                                '               MemPtr has the file number
CONST SYMFLAGFUNC = 4                           '   User-defined function
'
'   Loop Flags
'
CONST LOOPKINDFOR = 1                           '   FOR loop
CONST LOOPKINDWHILE = 2                         '   While loop
'
'   File constants
'
CONST FIRSTFILENUMBER = 1                           '   First file #
CONST LOADFILENUMBER = FIRSTFILENUMBER + MAXFILES   '   File # for LOAD
CONST SAVEFILENUMBER = LOADFILENUMBER               '   File # for SAVE
CONST DUMPFILENUMBER = LOADFILENUMBER               '   File # for DUMP
'
'   File access
'
CONST FILEACCESSINPUT = 1                       '   Input
CONST FILEACCESSOUTPUT = 2                      '   Output
CONST FILEACCESSAPPEND = 3                      '   Append
CONST FILEACCESSRANDOM = 4                      '   Random
'
'   Default file record length
'
CONST DEFAULTRECORDLEN = 128                    '   Default record length
'
'   Parser execution indicators
'
CONST CMDPARSE = 0                              '   Parse - do not execute
CONST CMDINTERPRET = 1                          '   Execute
CONST CMDSKIPLOOP = 2                           '   Skip LoopCount loop bodies
CONST CMDIFBLOCK = 3                            '   Skip IF block
CONST CMDEVALFUNC = 4                           '   Evaluate User-defined function
CONST CMDRENUM = 5                              '   Renumber
'
'   Interpreter: InterpSrc values
'
CONST DEVCONSOLE = 1                            '   Read commands from console
CONST DEVFILE = 2                               '   Read commands from file
'
'   Input modes
'
CONST INPUTNORMAL = 1                           '   INPUT
CONST INPUTLINE = 2                             '   LINE INPUT
CONST INPUTREAD = 3                             '   READ
'
'   Run modes
'
CONST RUNSTART = 1                              '   RUN from start
CONST RUNCONT = 2                               '   RUN continue after STOP/BRK
'
'   Key trapping
'
CONST FIRSTKEY = 1
CONST LASTKEY = 12



'======================================================================
'
'   Types
'
'======================================================================

'
'   String Type
'
TYPE STRTYPE
    StrLen AS INTEGER               ' Length of string
    StrBuf AS STRING * MAXSTRLEN    ' String buffer
END TYPE
'
'   Value type
'
TYPE VALUETYPE
    DataType AS INTEGER             '   Data type
    ValueInt AS INTEGER             '   Value if type is TYPEINT
    ValueReal AS SINGLE             '   Value if type is TYPEREAL
    ValueStr AS STRTYPE             '   Value if type is TYPESTR
END TYPE
'
'   Program Location
'
TYPE PGMLOCTYPE
    PgmPtr AS INTEGER               '   Pointer into PgmMem
    Offset AS INTEGER               '   Offset within buffer
END TYPE
'
'   Program Memory
'
TYPE PGMMEMTYPE
    LineNumber AS INTEGER                       '   Line number
    Flags AS INTEGER                            '   Flags
    Renum AS INTEGER                            '   RENUM number
    PrevPtr AS INTEGER                          '   Previous in chain
    NextPtr AS INTEGER                          '   Next in chain
    Offset AS INTEGER                           '   For misc. uses
    BufLen AS INTEGER                           '   Length of buffer
    Buffer AS STRING * MAXPGMBUFLEN             '   Buffer
END TYPE
'
'   Symbol Table
'
TYPE SYMTABTYPE
    Symbol AS STRING * MAXSYMLEN                '   Symbol
    SymbolType AS INTEGER                       '   Symbol type
    Flags AS INTEGER                            '   Flags
    Dimensions AS INTEGER                       '   Dimensions
    Size1 AS INTEGER                            '   Dimension 1
    Size2 AS INTEGER                            '   Dimension 2
    Size3 AS INTEGER                            '   Dimension 3
    DataType AS INTEGER                         '   data type
    MemPtr AS INTEGER                           '   Pointer to value
    Offset AS INTEGER                           '   Offset if field
    Length AS INTEGER                           '   Length if field
END TYPE
'
'   Loop stack
'
'
TYPE LOOPSTKTYPE
    LoopKind AS INTEGER                         '   Kind of loop
    Flags AS INTEGER                            '   Flags
    Id AS STRING * MAXSYMLEN                    '   Counter
    FirstValue AS INTEGER                       '   First value
    LastValue AS INTEGER                        '   Last value
    Increment AS INTEGER                        '   Increment
    PgmBegin AS PGMLOCTYPE                      '   Loop begins
    PgmEnd AS PGMLOCTYPE                        '   Loop ends
END TYPE
'
' Function evaluation stack
'
TYPE FUNCSTKTYPE
    cParam AS INTEGER                           '   Number of parameters
    ParamPtr AS INTEGER                         '   Pointer into StrMem
    ArgPtr AS INTEGER                           '   pointer into ArgMem
END TYPE
'
'   File structures
'
TYPE FIELDTYPE
    FieldId AS STRING * MAXSYMLEN               '   ID
    FieldLen AS INTEGER                         '   Length
    NextPtr AS INTEGER                          '   Next in chain
END TYPE

TYPE RECTYPE
    RecordLen AS INTEGER                        '   Record length
    FieldPtr AS INTEGER                         '   Field list
    NextPtr AS INTEGER                          '   Next in chain
END TYPE

TYPE FILETYPE
    FileName AS STRING * MAXSTRLEN              '   File name
    FileAccess AS INTEGER                       '   Access
    RecordLen AS INTEGER                        '   Record length
    RecordPtr AS INTEGER                        '   Record list
    SeekPos AS INTEGER                          '   Seek position
    Buffer AS STRING * MAXFILEBUFLEN            '   Buffer
END TYPE
'
'   Lexer
'
TYPE TOKENTYPE
    Tkn AS INTEGER                              '   The Token
    Value AS VALUETYPE                          '   Value
    TokenBegin AS INTEGER                       '   Token begins
END TYPE
'
'   Information saved after a STOP/BREAK
'
TYPE BRKSAVETYPE
    Lc AS PGMLOCTYPE
    ErrTrapEnabled AS INTEGER
    TimerTrapEnabled AS INTEGER
    KeyTrapEnabled AS INTEGER
END TYPE

'======================================================================
'
'   COMMON Variables
'
'======================================================================
'
'   PGM
'
COMMON SHARED PgmCur AS PGMLOCTYPE                 '   Currently executing
COMMON SHARED PgmMemImm AS INTEGER                 '   Used for immediate cmds
COMMON SHARED PgmMemInp AS INTEGER                 '   For INPUT
COMMON SHARED StmtCur AS INTEGER                   '   Offset of current stmt
COMMON SHARED PgmData AS PGMLOCTYPE                '   Start looking for DATA statements here
'
'   Lexer
'
COMMON SHARED LexToken AS TOKENTYPE                '   Last token
COMMON SHARED LexError AS INTEGER                  '   Lex error
'
' Interpreter
'
COMMON SHARED InterpSrc AS INTEGER                 '   Interpreter source (DEVCONSOLE etc)
COMMON SHARED TraceOn AS INTEGER                   '   Trace on flag
COMMON SHARED LoopCount AS INTEGER                 '   Number of loops to skip
'
'   BRK saved data
'
COMMON SHARED BrkSaveData AS BRKSAVETYPE           '   BRK saved information
'
'   Error trapping
'
COMMON SHARED ErrTrapEnabled AS INTEGER            '   Error trapping enabled
COMMON SHARED ErrTrapTarget AS INTEGER             '   PgmPtr
COMMON SHARED LastErr AS INTEGER                   '   ERR
COMMON SHARED LastErl AS INTEGER                   '   ERL
COMMON SHARED LastErt AS STRING                    '   ERT
'
'   Key Trapping
'
COMMON SHARED KeyTrapEnabled AS INTEGER            '   Key trapping enabled
'
'   Timer trapping
'
COMMON SHARED TimerTrapEnabled AS INTEGER          '   Timer trapping enabled
COMMON SHARED TimerTrapTarget AS INTEGER           '   PgmPtr
COMMON SHARED TimerInterval AS INTEGER             '   Timer interval
COMMON SHARED TimerStamp AS LONG                   '   Timestamp
'
'   INKEY$ support
'
COMMON SHARED InKeyChars AS INTEGER                '   Characters in buffer
