I'm a Scheme programmer, and I'm attempting to use Guile to call Scheme functions from C++ code within a Bison specification. The documentation concerning Guile and C is great; however, I haven't found much relevant, up-to-date information about Guile and C++. Because every C program is technically a C++ program, calling Scheme functions from C++ via Guile should be easy enough. Alas, I'm not a C/C++ programmer, so I was hoping some of the C++ gurus on here could help me out. Here is some of my code:
%{
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;
#include "List.h"
#include "paslex.h"
#include "paspar.h"
#include <libguile.h>
extern "C" {
#include "symtable.h"
}
void yyerror(char* m);
extern ofstream tfs;
extern int line;
extern int col;
extern "C" {
// Create namespace stack and lexical level 0 with built-in types.
SCM namespace_stack;
SCM namespace0;
SCM real_type;
SCM real_type_sym;
SCM integer_type;
SCM integer_type_sym;
// errors begin here
namespace_stack = make_name_stack();
namespace0 = make_namespace();
real_type = make_type_attr(64, 64);
real_type_sym = make_type_sym("real", real_type);
integer_type = make_type_attr(32, 32);
integer_type_sym = make_type_sym("integer", integer_type);
insert_symbol(real_type_sym, namespace0);
insert_symbol(integer_type_sym, namespace0);
push(namespace0, namespace_stack);
}
%}
My wrapper functions for the Scheme code are in symtable.c. Using these same functions from pure C works just fine. Calling them from C++ generates the following compiler error:
paspar.y:33: error: expected constructor, destructor, or type conversion before ‘=’ token
...and a similar error for lines 34 through 42. I'm using GCC 4.4.5 and Guile 1.6.8 on Ubuntu 10.10. I've tried moving the libguile.h include inside and outside the extern "C" block, but the result is the same. I'm sure this is a newbie mistake, but help with this problem would be greatly appreciated. Let me know if more information is needed. I've included symtable.h below:
// Description: API to translator symbol table, including namespaces,
// namespace stacks, and descriptors.
// Constants used by descriptors.
#define CONSTANT_ID 0
#define FUNCTION_ID 1
#define PROCEDURE_ID 2
#define VARIABLE_ID 3
#define TYPE_SYM_ID 4
#define TYPE_ATTR_ID 5
#define TYPE_ENUM_ID 6
#define TYPE_RANGE_ID 7
#define TYPE_ARRAY_ID 8
#define TYPE_RECORD_ID 9
#define TYPE_POINTER_ID 10
#define TYPE_SET_ID 11
//------------------------------------NAMESPACE STACK--------------------------------------
SCM make_name_stack();
// Create and return a namespace stack.
void push(SCM namspace, SCM stack);
// Places a namespace on the stack.
// @param stack The stack to place value on.
// @param namspace The namespace to place on the stack.
// @return None
SCM pop(SCM stack);
// Returns namespace on top of stack.
// @param stack The stack to return value from.
// @return The namespace on top of stack.
void sremove(SCM stack);
// Removes the top value on stack.
// @param stack The stack to remove top value from.
// @return None
int empty(SCM stack);
// A predicate for determining if a stack is empty.
// @param Stack The stack to test.
// @return 1 if the stack is empty, 0 if it is not.
SCM find_stack_symbol(char* name, SCM stack);
// Finds the symbol descriptor for the given identifier.
// @param name The symbol name.
// @param stack The stack to search.
// @return The symbol descriptor or 0 if the symbol could not be found.
int lexical_level(char* name, SCM stack);
// Find the lexical level of the identifier.
// @param name The symbol name.
// @param stack The stack to search.
// @return The lexical level or -1 if the symbol could not be found.
int current_level(SCM stack);
// Find lexical level of the top namespace.
// @param stack The stack to search.
// @return The lexical level or -1 if stack is empty.
//------------------------------------NAMESPACE--------------------------------------
SCM make_namespace();
// Create and return a namespace.
void insert_symbol(SCM symbol, SCM namspace);
// Insert descriptor into namespace
// @param descriptor The descriptor to insert.
// @param namspace The namespace to insert the descriptor into.
// @return Nothing.
SCM find_symbol(SCM symbol, SCM namspace);
// Search for symbol in target namespace.
// @param symbol The symbol to search for.
// @param namspace The namespace to search for symbol.
// @return A symbol descriptor, or 0 if symbol not found.
int get_lex(SCM namspace);
// Get lexical level of target namespace.
// @param namspace The namespace whose lexical level to get.
// @return Lexical level, or -1 if namespace has not yet been assigned one.
// ------------------------------SYMBOL DESCRIPTORS-------------------------------
SCM make_constant(char* name, SCM type, char* value);
// Makes a constant symbol descriptor.
// @param identifier Name of the constant.
// @param type The constant's type descriptor.
// @param value String representation of the constant.
// @return A constant symbol descriptor.
SCM make_var(char* name, SCM type, double address);
// Makes a variable symbol descriptor.
// @param identifier Name of the variable.
// @param type Address of the variable's type descriptor.
// @param address Starting address of the variable itself.
// @return A variable symbol descriptor.
SCM make_function(char* name, SCM params, double address);
// Makes a function symbol descriptor.
// @param identifier Name of the function.
// @param params A list of function parameters. The first element should
// always be the return type.
// @param address Address of the first function instruction.
// @return A function symbol descriptor.
SCM make_procedure(char* name, SCM params, double address);
// Makes a procedure symbol descriptor.
// @param identifier Name of the procedure.
// @param params A list of procedure parameters. Does not include a return type.
// @param address Address of the first procedure instruction.
// @return A procedure symbol descriptor.
SCM make_type_sym(char* name, SCM type);
// Make a type symbol descriptor.
// @param identifer Name of the type.
// @param type Address of the type's attributes.
// @return A type symbol descriptor.
int get_id(SCM descriptor);
// Return descriptor id.
void get_name(SCM descriptor, char* name);
// Return descriptor name.
// @param descriptor Target descriptor.
// @param name Output parameter for descriptor name.
int get_value(SCM descriptor, char* value);
// Get string representation of a constant symbol descriptor.
// @param descriptor Target descriptor.
// @param value Output parameter for descriptor value.
// @return 0 if not a constant, 1 if a constant.
double get_address(SCM descriptor);
// Get address of descriptor.
// @param descriptor Target descriptor.
// @return address, or -1 if descriptor does not possess an address.
SCM get_params(SCM descriptor);
// Get parameter list of descriptor.
// @param descriptor Target descriptor.
// @return parameter list, or 0 if descriptor does not possess a parameter list.
SCM get_type(SCM descriptor);
// Get type referenced by descriptor.
// @param descriptor Target descriptor.
// @return type, or 0 if descriptor does not reference a type.
int set_type(SCM descriptor, SCM type);
// Set type referenced by descriptor.
// @param descriptor Target descriptor.
// @param type Target type.
// @return 1 if type set successfully, or 0 if it failed.
// -------------------------------TYPE DESCRIPTORS-------------------------------
SCM make_type_attr(double size, int align);
// Make a type symbol attribute descriptor.
// @param size Size of the type in bits.
// @param align Type alignment in bits.
// @return A type attribute descriptor.
SCM make_type_enum(double size, int align, SCM syms);
// Make an enumerated type descriptor.
// @param size Size of the type in bits.
// @param align Alignment of the type in bits.
// @param syms A Scheme list of symbol type descriptors.
// @return An enumerated type descriptor.
SCM make_type_range(double size, int align, SCM low, SCM high);
// Make a ranged type.
// @param size Size of the type in bits.
// @param align Alignment of the type in bits.
// @param low Low value in the range (a symbol descriptor).
// @param high High value in the range (a symbol descriptor).
// @return A ranged type descriptor.
SCM make_type_array(double size, int align, SCM index, SCM element);
// Make an array type.
// @param size Size of the type in bits.
// @param align Alignment of the type in bits.
// @param index The type of allowable index values (a symbol descriptor).
// @param element The type of allowable element values (a symbol descriptor).
// @return An array type descriptor.
SCM make_type_record(double size, int align, SCM vars);
// Make a record type.
// @param size Size of the type in bits.
// @param align Alignment of the type in bits.
// @param vars A Scheme list of variable type descriptors.
// @return A record type descriptor.
SCM make_type_pointer(double size, int align, SCM type);
// Make a pointer type.
// @param size Size of the type in bits.
// @param align Alignment of the type in bits.
// @param type The type pointer is referencing.
// @return A pointer type.
SCM make_type_set(double size, int align, SCM enum_type);
// Make a set type.
// @param size Size of the type in bits.
// @param align Alignment of the type in bits.
// @param enum The enumerated type used by this set.
// @return A set type.
SCM make_type_null();
// Make a null type for use when the descriptor type is not known
// at creation time.
int check_null(SCM type);
// Checks if a type is null.
// Returns 1 if null, or 0 if not null.
double get_size(SCM descriptor);
// Return size of type in bits.
int get_align(SCM descriptor);
// Return alignment of type in bits.
SCM get_vars(SCM descriptor, int* boolean);
// Return variable list from record descriptor.
// @param descriptor Target descriptor.
// @param boolean Output parameter returns 0 if not record descriptor.
// @return A variable list.
SCM get_index(SCM descriptor, int* boolean);
// Return index type from array descriptor.
// @param descriptor Target descriptor.
// @param boolean Output parameter returns 0 if not array descriptor.
// @return Index type.
SCM get_element(SCM descriptor, int* boolean);
// Return element type from array descriptor.
// @param descriptor Target descriptor.
// @param boolean Output parameter returns 0 if not array descriptor.
// @return Element type.
SCM get_low(SCM descriptor, int* boolean);
// Return low type from range descriptor.
// @param descriptor Target descriptor.
// @param boolean Output parameter returns 0 if not range descriptor.
// @return Low type.
SCM get_high(SCM descriptor, int* boolean);
// Return high type from range descriptor.
// @param descriptor Target descriptor.
// @param boolean Output parameter returns 0 if not range descriptor.
// @return High type.
SCM get_syms(SCM descriptor, int* boolean);
// Return symbol list from enumerated descriptor.
// @param descriptor Target descriptor.
// @param boolean Output parameter returns 0 if not enumerated descriptor.
// @return Symbol list.
You're attempting to perform work outside a function, which is not allowed in C and only with great limitations in C++. The statements starting with
should not be at top-level, but inside a function (e.g.,
main
). Why do you use anextern "C"
block, btw.?