I've been thinking about it more and more, and I've pretty much thought of how I want to handle the script interface.
One of the goals of the interface is to have multiple front-ends which will compile the same code. The two ways I plan on handling this are:
1) Setting the default language as a subset of C (not the run-time stuff, but the logic operators, identifier structures, etc). Then creating a language "translator" in the default language.
[Example of script language front-end definition]: /********************/ /* PASCAL.SC */ /* */ /* Pascal front-end */ /********************/ ... tokenType getToken( char *curline ) { if( getFirstStringToken( curline ) = "BEGIN" ) return '{'; } ... int main( argc, argv[] ) { tokenType curToken; ... /* The following is shorthand for a line of source */ /* which can be a string variable */ curToken = getToken( "BEGIN END;" ); ...
return erNone; }
[Example of the Pascal library syntax to use the above script]: { Main program } ... { 1A } Script^.CompileScript( 'pascal.sc' ); ... { 1B } Script^.Run( 'pascal.vm', 'foobar.sp' ); Script^.CompileScript( 'foobar.sc' ); Script^.Run( 'foobar.vm', '' ); ...
In the above examples, 1A needs to be executed only once, to compile the pascal translator. In 1B 'foobar.sc' or 'foobar.sp' need to be compiled once, or after the script is significantly modified. Also, 'foobar.sp' is the script in Pascal, 'foobar.sc' is the result of the Pascal translator which converts Pascal code to the default script language.
2) Providing variables to "override" symbols.
[Pascal definitions]: CONST PascalKeywordDefs : TScrDef = 'b="BEGIN"' + 'e="END"' + 'i="IF"' + 't="THEN"' + 'l="ELSE"';
PascalGrammarRules : TRulesDef = 'CAPS="NONE"' + 'IF="i c t [b]..[e] [l [b]..[e]];"';
CKeywordDefs : TScrDef = 'b="{"' + 'e="}"' + 'i="IF"' + 't=""' + 'l="else"';
CGrammarRules : TRulesDef = 'CAPS="MIX"' + 'IF="i (c) [b]..[e] [l [b]..[e]];"'; ... { The following loads and parses Pascal values from memory } Script^.SetKeywordDefs( PascalKeywordDefs ); Script^.SetGrammarRules( PascalGrammarRules ); { OR } { The following loads and parses Pascal values from a file } Script^.LoadKeywordDefs( 'PAS.KWD' ); Script^.LoadGrammarRules( 'PAS.RUL' );
{ Compile Pascal script } Script^.Compile( 'foo.sp' );
{ The following loads and parses C values from memory } Script^.SetKeywordDefs( CKeywordDefs ); Script^.SetGrammarRules( CGrammarRules ); { OR } { The following loads and parses C values from a file } Script^.LoadKeywordDefs( 'C.KWD' ); Script^.LoadGrammarRules( 'C.RUL' );
{ Compile C script } Script^.Compile( 'foo.sc' ); ...
Note something about example 2, yes it might be better to use Lex/Yacc, but this allows the grammar rules and the syntax to be re-defined at run-time, and it makes it possible to load definitions from a file. The advantage to both of these examples (1 and 2) is that there is room for a user-defined language. I think that idea #1 would be easier on the programmer and user than idea #2, but that's me, I'd like to see if any of you have a good alternative if you're not comfortable with either of these ideas. Oh! One other thing, I've decided that pointers used carefully can't harm anyone as long as their addresses cannot be set. The reason I'm thinking of adding pointers is so that linked lists and/or binary trees can be implemented.
Thanks in advance!
See ya! Orlando Llanes
"Meine Damen und Herren, Elvis hat soeben das Gebaeude verlassen!"
"Look out fo' flyeeng feet" O__/ a010111t@bc.seflin.org /|____. O <__. /> / \ ____________|_________ http://ourworld.compuserve.com/homepages/Monkey414