1. Re: BASIC Interpreter
- Posted by David Cuny <dcuny at DSS.CA.GOV> Jan 22, 1998
- 629 views
Robert Craig wrote: > However, if we are lucky, I believe David Cuny was starting to > write a Basic interpreter in Euphoria. (He already did a Basic > to Euphoria *translator*). Yes, I do have an interpreter. It will run a BASIC-like language that I stopped working on when the Win32 version of Euphoria came out. It's not complete, but it does have: - complex expressions, including booleans - if ... else ... end if - for ... next | end for - while ... wend | end while - break, exit, and continue - built in procedures and functions - text window output - dialogs What is *hasn't* got is the ability to define user functions and procedures, which is pretty much critical for it having any utility. If people are interested, here are the Technical Details so you don't have to actually read the source code. :) The program first tokenizes the input into a LISP-like internal form. The parser is essentially a reworking of the EBASIC parser, based on an LL1 grammar. It's pretty sophisticated, and does not require backtracking. For example, the snippet: 3 + a would be tokenized as: { ADD, { NUMBER, 3 }, { VARIABLE, "a" } } This can be executed directly by the evaluation routine, winCode: ------------------------------------------------------------------------ ----- function winCode( sequence code ) if act[ code[1] ] = -1 then abort_error( "Null pointer to " & names[code[1]] & "." ) else return call_func( act[ code[1] ], {code} ) end if end function ------------------------------------------------------------------------ ----- As you can see, the head of the sequence is used as an index to an action array. Here's the definition for addition: ------------------------------------------------------------------------ ----- global function wAdd( sequence code ) object a,b -- addition -- evaluate remaining expression a = winCode( code[2] ) b = winCode( code[3] ) -- returned numeric literals? is_numeric( a ) is_numeric( b ) -- return result return a + b end function ------------------------------------------------------------------------ ----- Note the results are check for type, to prevent the user from adding together two strings. Once the functions are defined, they are plugged into an action array like this: act[ADD] = routine_id("wAdd" ) As you can see, the sub-expressions are evaluated recursively. Code execution is fast, even with all the error checking. That's pretty much the sum of it. Probably the most complex part is the LL1 grammar, but if you're going to write an interpreter, I suspect you'll want to write your own parser from scratch - they are pretty complex beasts, and the parser you choose very much determines the grammar you can handle. If people are interested, I'll try to put together some documentation and post all the code. Let me know. -- David Cuny