// C to C++ interface

#include "Symbol.h"
#include "Program.h"
#include <stdio.h>

Program *theProgram;

extern "C" {
    void *CppIntern(char *);
    void CppAddP(void *p);
    void CppAddL(long l);
    void CppSetL(long where, long l);
    void CppAddOp(int op);
    long CppEndProg(void);
    void *CppNewFunc(void);
    void CppDoneFunc(void *);
    void CppAddParam(void *);
    void CppFetchVar (int, void *);
}

void *CppIntern (char *c) { String s(c); return Intern(&s); }
void CppAddP (void *p) { theProgram->AddP(p); }
void CppAddL (long l) { theProgram->AddL(l); }
void CppSetL (long where, long l) { theProgram->SetL(where, l); }
void CppAddOp (int op) { theProgram->AddOp(op); }
long CppEndProg (void) { return theProgram->End(); }
void *CppNewFunc(void) { Program *p = theProgram; theProgram = new Program(p); return p; }
void CppAddParam(void *s) { theProgram->AddParam((Symbol *) s); }
void CppDoneFunc(void *pp)
{
    Program *p = (Program *) pp;
    p->AddOp(O_FUNC); p->AddP(theProgram);
    theProgram = p;
}

void CppFetchVar (int lvalue, void *var)
{
    Symbol *sym = (Symbol *) var;
    int levels, offset;
    if (theProgram->Params()->Lookup(sym, &levels, &offset)) {
	theProgram->AddOp(lvalue ? O_LOCALADDROF : O_LOCALVALUEOF);
	theProgram->AddS(levels);
	theProgram->AddS(offset);
    } else {
	theProgram->AddOp(lvalue ? O_ADDROF : O_VALUEOF);
	theProgram->AddP(sym);
    }
}
