#include "m.h" #define PROGSIZE 8192 Inst prog[PROGSIZE]; /* the machine */ Instptr pc; /* program counter during execution */ Instptr pp = prog; /* next free spot for code generation */ // conversion between Inst (function pointer) and data (void *) // typedef union { void *v; Inst i; } U; Inst d2i( void *v) // data to Inst { U u; u.v = v; return u.i; } void *i2d( Inst i) // Inst to data { U u; u.i = i; return u.v; } void initcode( void) { pp = prog; sp = stack; fp = frame; fpush(); got_return = got_break = got_continue = 0; inmat = instmt = inloop = insw = indef = 0; } Instptr code( Inst f) /* install one instruction or operand */ { Instptr opp = pp; if( pp >= prog + PROGSIZE) error("program too big",""); *pp++ = f; return opp; } Instptr code2( Inst f1, Inst f2) { Instptr opp; opp = code(f1); code(f2); return opp; } Instptr code3( Inst f1, Inst f2, Inst f3) { Instptr opp; opp = code(f1); code(f2); code(f3); return opp; } Instptr code4( Inst f1, Inst f2, Inst f3, Inst f4) { Instptr opp; opp = code(f1); code(f2); code(f3); code(f4); return opp; } /* * copy program, from prog[0] to *(pp-1), for FUNCTION or PROCEDURE */ void define( Symbolptr a, int narg) { int size = pp - prog; if( (a->u.fptr = (Instptr) malloc(size*sizeof(Inst))) == NULL) error("malloc() failed in define()",""); prog[0] = d2i( defn()); /* pointer to fn source code */ memcpy( a->u.fptr, prog, size*sizeof(Inst)); NARG(a) = narg; SIZE(a) = size; } Instptr varpush( Symbolptr a) { if( a->class == AUTO) return code2( local_push, (Inst)OFFSET(a)); else return code2( sympush, d2i(a)); } static void dup_check( Symbolptr a) /* check for duplicates */ { Symbolptr *s; for( s = stack; s < sp; ++s) if( strcmp( (*s)->name, a->name) == 0) dprint("warning: redeclaration of variable %s\n", a->name); } void mklocal( Symbolptr a, int class, Instptr init) { dup_check(a); if( class == STATIC || class == AUTO) { if( a->class == NEW) a->class = class; else a = install( a->name, UNDEF, class, 0, 0); } else if( class == EXTERN) { if( a->class != NEW && a->class != EXTERN) a = install( a->name, UNDEF, EXTERN, 0, 0); } else error("unrecognized class in mklocal()",""); if( class == AUTO) { OFFSET(a) = sp - stack; code( m_install); } if( init) { if( class == AUTO) code( m_copy); else if( class == STATIC) { code2( sympush, d2i( a)); code3( m_copy, (Inst)pop, NULL); #ifdef DEBUG if( prog_debug) { dprint("\n"); disasm(init,pp); } #endif execute( init); pp = init; a->class = STATIC; } else { code( (Inst)pop); yyerror("initialization ignored in extern declaration"); } } push(a); } void fnarg( int type, Symbolptr a) { dup_check(a); if( a->class == NEW) a->class = AUTO; else a = install( a->name, UNDEF, AUTO, 0, 0); OFFSET(a) = sp - stack; push(a); code( (Inst)type); }