03/15/2006: mutandiz

[allegrocl]
	    Generate wrappers for constants when in C++ or -cwrap mode.
	    Make -cwrap the default, since it is most correct. Users
	    can use the -nocwrap option to avoid the creation of a .cxx
	    file when interfacing to C code.

	    When in -nocwrap mode, improve the handling of converting
 	    infix literals to prefix notation for lisp. This is very
	    basic and not likely to be improved upon since this only
	    applies to the -nocwrap case. Literals we can't figure out
	    will result in a warning and be included in the generated
	    code.

	    validIdentifier now more closely approximates what may be
	    a legal common lisp symbol.

	    Fix typemap error in allegrocl.swg


git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@9009 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Mikel Bancroft 2006-03-16 18:11:25 +00:00
commit a82b71b328
3 changed files with 158 additions and 51 deletions

View file

@ -27,7 +27,7 @@ static File *f_cxx_wrapper=0;
const char *identifier_converter="identifier-convert-null";
static bool CWrap = false; // generate wrapper file for C code?
static bool CWrap = true; // generate wrapper file for C code by default. most correct.
static bool Generate_Wrapper = false;
static String *current_namespace=NewString("");
@ -43,7 +43,7 @@ static String *anon_type_name=NewString("anontype");
static int anon_type_count=0;
// stub
String * convert_literal(String *num_param, String *type);
String * convert_literal(String *num_param, String *type, bool try_to_split = true);
class ALLEGROCL : public Language {
public:
@ -832,26 +832,59 @@ String *strip_parens(String *string) {
int ALLEGROCL :: validIdentifier(String *s) {
char *c = Char(s);
if (*c && !isalpha(*c) && *c != '_') return 0;
bool got_dot = false;
bool only_dots = true;
/* Check that s is a valid common lisp symbol. There's a lot of leeway here.
A common lisp symbol is essentially any token that's not a number and
does not consist of only dots.
We are expressly not allowing spaces in identifiers here, but spaces
could be added via the identifier converter. */
while (*c) {
if (!isalnum(*c) && *c != '_') return 0;
if (*c == '.') {
got_dot = true;
} else {
only_dots = false;
}
if (!isgraph(*c)) return 0;
c++;
}
return 1;
return (got_dot && only_dots) ? 0 : 1;
}
String *infix_to_prefix(String *val, char split_op, const String *op, String *type) {
List *ored = Split(val, split_op, -1);
// some float hackery
if ( ((split_op == '+') || (split_op == '-')) && Len(ored) == 2 &&
(SwigType_type(type) == T_FLOAT || SwigType_type(type) == T_DOUBLE ||
SwigType_type(type) == T_LONGDOUBLE) ) {
// check that we're not splitting a float
String *possible_result = convert_literal(val, type, false);
if (possible_result) return possible_result;
}
// try parsing the split results. if any part fails, kick out.
bool part_failed = false;
if (Len(ored) > 1) {
String *result = NewStringf("(%s", op);
for (Iterator i = First(ored); i.item; i = Next(i)) {
String *converted = convert_literal(i.item, type);
Printf(result, " %s", converted);
Delete(converted);
if(converted) {
Printf(result, " %s", converted);
Delete(converted);
} else {
part_failed = true;
break;
}
}
Printf(result, ")");
Delete(ored);
return result;
return part_failed ? 0 : result;
}
else {
Delete(ored);
@ -859,39 +892,76 @@ String *infix_to_prefix(String *val, char split_op, const String *op, String *ty
return 0;
}
/* to be called by code generating the lisp interface */
String * convert_literal(String *num_param, String *type) {
/* To be called by code generating the lisp interface
Will return a containing the literal based on type.
Will return null if there are problems.
try_to_split defaults to true (see stub above).
*/
String * convert_literal(String *literal, String *type, bool try_to_split) {
String *num_param = Copy(literal);
String *trimmed = trim(num_param);
String *num=strip_parens(trimmed), *res=0;
char *s=Char(num);
String *ns = listify_namespace(current_namespace);
// very basic parsing of infix expressions.
if( (res = infix_to_prefix(num, '|', "logior", type)) ) return res;
if( (res = infix_to_prefix(num, '&', "logand", type)) ) return res;
if( (res = infix_to_prefix(num, '^', "logxor", type)) ) return res;
if( (res = infix_to_prefix(num, '*', "*", type)) ) return res;
if( (res = infix_to_prefix(num, '/', "/", type)) ) return res;
if( (res = infix_to_prefix(num, '+', "+", type)) ) return res;
if( (res = infix_to_prefix(num, '-', "-", type)) ) return res;
// if( (res = infix_to_prefix(num, '<<', "ash", type)) ) return res;
if(try_to_split) {
if( (res = infix_to_prefix(num, '|', "logior", type)) ) return res;
if( (res = infix_to_prefix(num, '&', "logand", type)) ) return res;
if( (res = infix_to_prefix(num, '^', "logxor", type)) ) return res;
if( (res = infix_to_prefix(num, '*', "*", type)) ) return res;
if( (res = infix_to_prefix(num, '/', "/", type)) ) return res;
if( (res = infix_to_prefix(num, '+', "+", type)) ) return res;
if( (res = infix_to_prefix(num, '-', "-", type)) ) return res;
// if( (res = infix_to_prefix(num, '<<', "ash", type)) ) return res;
}
if (SwigType_type(type) == T_FLOAT ||
SwigType_type(type) == T_DOUBLE ||
SwigType_type(type) == T_LONGDOUBLE) {
// Use CL syntax for float literals
String *oldnum = Copy(num);
int fsuffixes = Replaceall(num, "f", "") + Replaceall(num, "F", "");
int lsuffixes = Replaceall(num, "l", "") + Replaceall(num, "L", "");
char const *lisp_exp = fsuffixes ? "f" : (lsuffixes ? "l" : "d");
int exponents = Replaceall(num, "e", lisp_exp) +
Replaceall(num, "E", lisp_exp);
if ((fsuffixes + lsuffixes) > 1 || exponents > 1) {
Printf(stderr, "Weird!! number %s looks invalid.\n", oldnum);
SWIG_exit(EXIT_FAILURE);
// careful. may be a float identifier or float constant.
char *num_start = Char(num);
char *num_end = num_start + strlen(num_start) -1;
bool is_literal = isdigit(*num_start) || (*num_start == '.');
String *lisp_exp = 0;
if(is_literal) {
if (*num_end == 'f' || *num_end == 'F') {
lisp_exp = NewString("f");
} else {
lisp_exp = NewString("d");
}
if (*num_end == 'l' || *num_end == 'L' || *num_end == 'f' || *num_end == 'F') {
*num_end = '\0';
num_end--;
}
int exponents = Replaceall(num, "e", lisp_exp) +
Replaceall(num, "E", lisp_exp);
if (!exponents)
Printf(num, "%s0", lisp_exp);
if (exponents > 1 || (exponents + Replaceall(num,".",".") == 0)) {
// Printf(stderr, "Can't parse '%s' as type '%s'.\n", oldnum, type);
Delete(num);
num = 0;
}
} else {
String *id = NewStringf("#.(swig-insert-id \"%s\" %s :type :constant)",
num, ns);
Delete(num);
num = id;
}
if (!exponents)
Printf(num, "%s0", lisp_exp);
Delete(oldnum); Delete(trimmed);
Delete(oldnum); Delete(trimmed); Delete(ns);
return num;
}
else if (SwigType_type(type) == T_CHAR) {
@ -906,7 +976,6 @@ String * convert_literal(String *num_param, String *type) {
}
else if (allegrocl->validIdentifier(num)) {
/* convert C/C++ identifiers to CL symbols */
String *ns = listify_namespace(current_namespace);
res = NewStringf("#.(swig-insert-id \"%s\" %s :type :constant)", num, ns);
Delete(num); Delete(trimmed); Delete(ns);
return res;
@ -1247,11 +1316,17 @@ void emit_enum_type_no_wrap(Node *n) {
if(!Getattr(c,"error")) {
String *val = Getattr(c,"enumvalue");
if(!val) val = Getattr(c,"enumvalueex");
val = convert_literal(val,Getattr(c,"type"));
String *converted_val = convert_literal(val,Getattr(c,"type"));
String *valname = Getattr(c,"sym:name");
Printf(f_clhead,"(swig-defconstant \"%s\" %s)\n", valname, val);
if(converted_val) {
Printf(f_clhead,"(swig-defconstant \"%s\" %s)\n", valname, converted_val);
Delete(converted_val);
} else {
Swig_warning(WARN_LANG_DISCARD_CONST, Getfile(n), Getline(n),
"Unable to parse enum value '%s'. Setting to NIL\n", val);
Printf(f_clhead,"(swig-defconstant \"%s\" nil #| %s |#)\n", valname, val);
}
}
}
}
@ -2240,14 +2315,12 @@ int ALLEGROCL :: emit_defun(Node *n, File *f_cl) {
String *funcname = Getattr(n, "allegrocl:old-sym:name");
if (!funcname) funcname = Getattr(n, "sym:name");
String *mangled_name=mangle_name(n, "ACL", Getattr(n,"allegrocl:package"));
// SwigType *type=Copy(Getattr(n, "type"));
String *mangled_name = Getattr(n,"wrap:name");
ParmList *pl = parmlist_with_names(Getattr(n, "wrap:parms"));
// attach typemap info.
Wrapper *wrap = NewWrapper();
Swig_typemap_attach_parms("lin", pl, wrap);
// Swig_typemap_attach_parms("in", pl, wrap);
Swig_typemap_lookup_new("lout",n,"result",0);
// prime the pump, with support for OUTPUT, INOUT typemaps.
@ -2257,8 +2330,7 @@ int ALLEGROCL :: emit_defun(Node *n, File *f_cl) {
int largnum = 0, argnum=0, first=1;
// int varargs=0;
SwigType *result_type = Swig_cparse_type(Getattr(n,"tmap:ctype"));
if (CPlusPlus)
if (Generate_Wrapper)
{
String *extra_parms = id_converter_arguments(n)->noname_str();
if (Getattr(n, "sym:overloaded"))
@ -2659,8 +2731,19 @@ int ALLEGROCL :: constantWrapper(Node *n) {
#ifdef ALLEGROCL_DEBUG
Printf(stderr, "constant %s\n", Getattr(n, "name"));
#endif
if(Generate_Wrapper) {
// Setattr(n,"wrap:name",mangle_name(n, "ACLPP"));
Printf(f_cxx,"static const %s %s = %s;\n", Getattr(n,"type"),
Getattr(n,"sym:name"), Getattr(n,"value"));
SetFlag(n,"feature:immutable");
return variableWrapper(n);
}
String *type=Getattr(n, "type");
String *converted_value=convert_literal(Getattr(n, "value"), type);
String *value = Getattr(n,"value");
String *converted_value=convert_literal(value, type);
String *name=Getattr(n, "sym:name");
Setattr(n, "allegrocl:kind", "constant");
@ -2671,8 +2754,14 @@ int ALLEGROCL :: constantWrapper(Node *n) {
name, type, converted_value);
#endif
Printf(f_clwrap, "(swig-defconstant \"%s\" %s)\n",
name, converted_value);
if(converted_value) {
Printf(f_clwrap, "(swig-defconstant \"%s\" %s)\n",
name, converted_value);
} else {
Swig_warning(WARN_LANG_DISCARD_CONST, Getfile(n), Getline(n),
"Unable to parse constant value '%s'. Setting to NIL\n", value);
Printf(f_clwrap, "(swig-defconstant \"%s\" nil #| %s |#)\n", name, value);
}
Delete(converted_value);
@ -2716,14 +2805,15 @@ int ALLEGROCL :: variableWrapper(Node *n) {
Setattr(n, "allegrocl:old-sym:name", Getattr(n, "sym:name"));
// Let SWIG generate a get/set function pair.
if(CPlusPlus) return Language::variableWrapper(n);
if(Generate_Wrapper) return Language::variableWrapper(n);
/*
String *name = Getattr(n, "name");
SwigType *type = Getattr(n,"type");
SwigType *ctype;
SwigType *rtype = SwigType_typedef_resolve_all(type);
String *mangled_name = mangle_name(n);
int pointer_added = 0;
if(SwigType_isclass(rtype)) {
@ -2735,20 +2825,18 @@ int ALLEGROCL :: variableWrapper(Node *n) {
ctype = SwigType_str(type,0);
// EXPORT <SwigType_str> <mangled_name>;
// <SwigType_str> <mangled_name> = <name>;
// Printf(f_cxx, "EXPORT %s %s;\n%s %s = %s%s;\n", ctype, mangled_name,
// ctype, mangled_name, (pointer_added ? "&" : ""), name);
Printf(f_cxx, "EXPORT %s %s;\n%s %s = %s%s;\n", ctype, mangled_name,
ctype, mangled_name, (pointer_added ? "&" : ""), name);
Printf(f_cl, "(swig-defvar \"%s\" :type %s)\n",
Getattr(n,"sym:name"),
mangled_name,
((SwigType_isconst(type)) ? ":constant" : ":variable"));
*/
/*
Printf(f_cxx, "// swigtype: %s\n", SwigType_typedef_resolve_all(Getattr(n,"type")));
Printf(f_cxx, "// vwrap: %s\n", compose_foreign_type(SwigType_strip_qualifiers(Copy(rtype))));
*/
// Delete(mangled_name);
Delete(mangled_name);
return SWIG_OK;
}