TIP: Click on subject to list as thread! ANSI
echo: c_echo
to: CHRIS CRANFORD
from: Jasen Betts
date: 2004-05-08 08:46:48
subject: RE: Scripting/Basic Compiler/Interpreter

Hi CHRIS.

17-Apr-04 14:59:48, CHRIS CRANFORD wrote to JASEN BETTS

 CC> Dim x as Integer = 2
 CC> Dim s as String  = "Text"
 CC> Print s; " #"; x

 CC> The above results in "Test #2" being pushed to the VM's
stdout device.

->> am I close?
->> what's the road-block?

 CC> The roadblock is understanding how I am suppose to handle variables by
 CC> defining them on the stack and representing their sizes so that when the
 CC> code
 CC> runs through a VM, the VM knows to:

 CC>   Allocate a 4-byte memory space for variable X and assign it value 2.
 CC>   Allocate a 5-byte memory space for variable S and assign it
"Test\0".

Don't do that, unless you want your basic-looking language to have C-style
strings...

OTOH you can build your stack any way you want too. instead of a rigid
structure it could be a linked list carrying random-sized objects.

many basics represent a string as (a pointer to) a struct something like,

struct stringheader
  { size_t strlen;
    size_t maxlen;
    char*  data;
  }

so there's two numbers follwed by an array holding the actual characters....
that way if the string gets too long (longer than maxlen) data can be
realloc()-ed and maxlen can be updated to the new size.

obvoiusly you need to free the data on exiting the string's scope...

 CC> If we were talking about a calculation application like:

 CC>   2+3*5

 CC> I know for sure that (assuming the stack is just integer based), I would:

stacks are easier than my register example in the previous message...

 CC>   PUSH 3
 CC>   PUSH 5
 CC>   MULTI
 CC>   PUSH 2
 CC>   ADD

push 2, push 3, push 5, multiply, add.

 CC> This leaves the top of the stack with a value of 17 assuming normal math
 CC> operations and precedence occurs right.

 CC> But it's going from something simple like the math example to the use of
 CC> variables that is killing me.  Something even like:

 CC>   Dim x as Integer                   Dim x as Integer = 2
 CC>   Dim y as Integer                   Dim y as Integer = 5
 CC>   x = 2                    or        x = x + 3 * y
 CC>   y = 5
 CC>   x = x + 3 * y

when you hit dim  and know the size allocate the space and store the
address in the symbol table, assuming you're putting intgers on the machine
stack it'll have to represent it as some sort of offset from "bp"

the assignment is then easy,

  // calculate the value

    push [bp + offset_for_x]       //  I've used a different op-code order
    push 3                         //  here than the one you had.
    push [bp + offset_for_y]       //  I feel this order more acurately
    multiply                       //  represent the expression x+3*y
    add                            //  (yours was 3*y+x)

// then store it

    store_to [bp + offset_for_x]

in the above the offset_for_x etc will come from the symbol table...
global variables will need to be stored off the stack.

 CC> In both of the examples above, the stack should contain the value 17 for
 CC> X,
 CC> but it's slightly different because X isn't located at the very top of
 CC> the
 CC> stack any longer, right?  Its moreover SP+offset on the stack?

if your byte-code only allows sp-offset stack addressing you'll need to
track the depth of the stack and add that in as well

->> is the design of the byte-code under your control?
->> do you have the byte-code interpreter working?

 CC> Yes, the entire system is at my control which means I can create as many
 CC> or
 CC> any special OPCODEs I need or want, but within reason of course because I
 CC>
 CC> need my VM to be as blazing fast as possible :-).

doing away with BP could help here as it'll be one less value you need to
track, if you track the expected value of SP as you compile figuring out
which SP offset to use is easy...

given a C variable and some helper functions
you'll want to add error checking below especiallt to pushvaruable and
popvariable.

 int sp_offset=0;

 struct symbol_data
    {
    int flags ;
    int offset;
    }

 void newlocalsymbol(char * name)
   {
   addnewsymbol(name, SYM_ISSTACK, sp_offset);
   }

 void pushvalue(int v)
  { // code here to emit bytecodes to push the value onto the stack
   sp_offset += 4;
  }

 void multiply (void)
   { // code here to emit bytecode(s) to multiply the two top stack entries
    sp_offset -= 4;
   }

 void add (void)
   { // code here to emit bytecode(s) to add the two top stack entries
    sp_offset -= 4;
   }

  void pushvariable( char * name);
  {
  struct symtab *s = seek_symbol(name)
  if (s->flags & SYM_ISSTACK == SYM_ISSTACK)
    { /* it's a local variable stack-offset */
    // emit bytecode to do    push [ (sp_offset - s->offset) ]
    }
  else
    { /* it's a global variable: fixed offset */
    // emit bytecode to do    push [s->offset]
    }

    sp_offset += 4;
  }

 void popvariable( char * name ); // inverse of the above
   // emits bytecode to take the stack content and store it where specified
   // probaly (as above but (pop,-=) instead of (push,+=)

here's your example again with the c finction calls it should produce to
compile.

 CC>  Dim x as Integer = 2

      pushvalue(2);
      newstacksymbol("x" , 4);

 CC>  Dim y as Integer = 5

      pushvalue(5);
      newstacksymbol("y" , 4);

 CC>  x = x + 3 * y

      pushvariable("x");
      pushvalue(3);
      pushvariable("y");
      multiply();
      add();
      popvariable("x");


now here's the trick if you do all this in c++ instead of in c
you can have the language elements,

assignment_statement  number_valued_expression  multiplication
additiom, variable_reference, each being subclasses classes that
have a method which causes them to emit the apropriate byte-code

I'm very inexpreienced in c++ so probably can't help much wiuth that.

 CC> I don't think at this point I'm at a place where I can work on getting
 CC> the
 CC> BYTECODE interpreter to work or coded until I get over the hurdle I'm
 CC> at right now, no?

seems fine...

 -=> Bye <=-

---
* Origin: Black Holes were created when God divided by zero! (3:640/1042)
SEEN-BY: 633/267 270
@PATH: 640/1042 531 954 774/605 123/500 106/2000 633/267

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.