Skip to content

Commit

Permalink
- Added argument exportAsCode to list
Browse files Browse the repository at this point in the history
  - This creates C-code that could be used to compile that part of the AST into an executable or library
  - But it is too large to be useful at the moment (a single 108MB expression for Modelica 3.1)
  - Could be changed to use more efficient C-code generation


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@13201 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Oct 5, 2012
1 parent e6a2c0c commit 41ec89c
Show file tree
Hide file tree
Showing 9 changed files with 251 additions and 57 deletions.
1 change: 1 addition & 0 deletions Compiler/FrontEnd/ModelicaBuiltin.mo
Original file line number Diff line number Diff line change
Expand Up @@ -1813,6 +1813,7 @@ function list "Lists the contents of the given class, or all loaded classes."
input TypeName class_ := $TypeName(AllLoadedClasses);
input Boolean interfaceOnly := false;
input Boolean shortOnly := false "only short class definitions";
input Boolean exportAsCode := false "true if we want a true unparsing of the program";
output String contents;
external "builtin";
annotation(Documentation(info="<html>
Expand Down
13 changes: 8 additions & 5 deletions Compiler/Script/CevalScript.mo
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,7 @@ algorithm
list<String> vars_1,args,strings,strs,strs1,strs2,visvars;
Real timeTotal,timeSimulation,timeStamp,val,x1,x2,y1,y2,r;
Interactive.Statements istmts;
Boolean have_corba, bval, b, b1, b2, externalWindow, legend, grid, logX, logY, gcc_res, omcfound, rm_res, touch_res, uname_res, extended, insensitive,ifcpp, sort, builtin, showProtected;
Boolean have_corba, bval, anyCode, b, b1, b2, externalWindow, legend, grid, logX, logY, gcc_res, omcfound, rm_res, touch_res, uname_res, extended, insensitive,ifcpp, sort, builtin, showProtected;
Env.Cache cache;
list<Interactive.LoadedFile> lf;
AbsynDep.Depends aDep;
Expand Down Expand Up @@ -1064,18 +1064,21 @@ algorithm
then
(cache,Values.TUPLE({Values.INTEGER(-1),v}),st);

case (cache,env,"list",{Values.CODE(Absyn.C_TYPENAME(Absyn.IDENT("AllLoadedClasses"))),Values.BOOL(false),Values.BOOL(false)},(st as Interactive.SYMBOLTABLE(ast = p)),_)
case (cache,env,"list",{Values.CODE(Absyn.C_TYPENAME(Absyn.IDENT("AllLoadedClasses"))),Values.BOOL(false),Values.BOOL(false),Values.BOOL(anyCode)},(st as Interactive.SYMBOLTABLE(ast = p)),_)
equation
str = Dump.unparseStr(p,false);
str = Debug.bcallret2(not anyCode, Dump.unparseStr, p, false, "");
str = Debug.bcallret1(anyCode, System.anyStringCode, p, str);
then
(cache,Values.STRING(str),st);

case (cache,env,"list",{Values.CODE(Absyn.C_TYPENAME(path)),Values.BOOL(b1),Values.BOOL(b2)},(st as Interactive.SYMBOLTABLE(ast = p)),_)
case (cache,env,"list",{Values.CODE(Absyn.C_TYPENAME(path)),Values.BOOL(b1),Values.BOOL(b2),Values.BOOL(anyCode)},(st as Interactive.SYMBOLTABLE(ast = p)),_)
equation
absynClass = Interactive.getPathedClassInProgram(path, p);
absynClass = Debug.bcallret1(b1,Absyn.getFunctionInterface,absynClass,absynClass);
absynClass = Debug.bcallret1(b2,Absyn.getShortClass,absynClass,absynClass);
str = Dump.unparseStr(Absyn.PROGRAM({absynClass},Absyn.TOP(),Absyn.TIMESTAMP(0.0,0.0)),false) ;
p = Absyn.PROGRAM({absynClass},Absyn.TOP(),Absyn.TIMESTAMP(0.0,0.0));
str = Debug.bcallret2(not anyCode, Dump.unparseStr, p, false, "");
str = Debug.bcallret1(anyCode, System.anyStringCode, p, str);
then
(cache,Values.STRING(str),st);

Expand Down
8 changes: 8 additions & 0 deletions Compiler/Util/System.mo
Original file line number Diff line number Diff line change
Expand Up @@ -971,4 +971,12 @@ public function gettext
external "C" msgstr = SystemImpl__gettext(msgid) annotation(Library = {"omcruntime"});
end gettext;

public function anyStringCode
"Takes any boxed input"
input Any any;
output String str;
replaceable type Any subtypeof Any;
external "C" str = anyStringCode(any);
end anyStringCode;

end System;
2 changes: 1 addition & 1 deletion Compiler/runtime/System_omc.c
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ extern void* System_regex(const char* str, const char* re, int maxn, int extende

extern char* System_escapedString(char* str, int nl)
{
char *res = SystemImpl__escapedString(str,nl);
char *res = omc__escapedString(str,nl);
if (res == NULL) return str;
return res;
}
Expand Down
9 changes: 8 additions & 1 deletion Compiler/runtime/System_rml.c
Original file line number Diff line number Diff line change
Expand Up @@ -1937,7 +1937,7 @@ RML_END_LABEL

RML_BEGIN_LABEL(System__escapedString)
{
char *str = SystemImpl__escapedString(RML_STRINGDATA(rmlA0),RML_UNTAGFIXNUM(rmlA1));
char *str = omc__escapedString(RML_STRINGDATA(rmlA0),RML_UNTAGFIXNUM(rmlA1));
if (str == NULL) {
RML_TAILCALLK(rmlSC);
} else {
Expand Down Expand Up @@ -2113,3 +2113,10 @@ RML_BEGIN_LABEL(System__gettext)
RML_TAILCALLK(rmlSC);
}
RML_END_LABEL

RML_BEGIN_LABEL(System__anyStringCode)
{
rmlA0 = mk_scon("You need to run the bootstrapped compiler in order to use anyStringCode");
RML_TAILCALLK(rmlSC);
}
RML_END_LABEL
50 changes: 0 additions & 50 deletions Compiler/runtime/systemimpl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1150,56 +1150,6 @@ extern char* SystemImpl__unescapedString(const char* str)
return res;
}

extern int SystemImpl__escapedStringLength(const char* str, int nl)
{
int i=0;
while (*str) {
switch (*str) {
case '"':
case '\\':
case '\a':
case '\b':
case '\f':
case '\v': i++;
case '\r': i++; if (nl && str[1] == '\n') str++;
case '\n': i++; if (nl && str[1] == '\r') str++;
default: i++;
}
str++;
}
return i;
}

/* "\b",_ => "\\b"
* "\n",true => "\\n"
*/
extern char* SystemImpl__escapedString(const char* str, int nl)
{
int len1,len2;
char *res;
int i=0;
len1 = strlen(str);
len2 = SystemImpl__escapedStringLength(str,nl);
if (len1 == len2) return NULL;
res = (char*) malloc(len2+1);
while (*str) {
switch (*str) {
case '"': res[i++] = '\\'; res[i++] = '"'; break;
case '\\': res[i++] = '\\'; res[i++] = '\\'; break;
case '\a': res[i++] = '\\'; res[i++] = 'a'; break;
case '\b': res[i++] = '\\'; res[i++] = 'b'; break;
case '\f': res[i++] = '\\'; res[i++] = 'f'; break;
case '\v': res[i++] = '\\'; res[i++] = 'v'; break;
case '\r': if (nl) {res[i++] = '\\'; res[i++] = 'n'; if (str[1] == '\n') str++;} else {res[i++] = *str;} break;
case '\n': if (nl) {res[i++] = '\\'; res[i++] = 'n'; if (str[1] == '\r') str++;} else {res[i++] = *str;} break;
default: res[i++] = *str;
}
str++;
}
res[i] = '\0';
return res;
}

extern void* SystemImpl__regex(const char* str, const char* re, int maxn, int extended, int sensitive, int *nmatch)
{
void *lst = mk_nil();
Expand Down
171 changes: 171 additions & 0 deletions SimulationRuntime/c/meta/meta_modelica.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,177 @@ void printAny(void* any)
fputs(anyStringBuf, stderr);
}

inline static int anyStringWorkCode(void* any, int ix)
{
mmc_uint_t hdr;
int numslots;
unsigned ctor;
int i;
void *data;
struct record_description *desc;
/* char buf[34] = {0}; */

if (MMC_IS_IMMEDIATE(any)) {
checkAnyStringBufSize(ix,40);
ix += sprintf(anyStringBuf+ix, "(void*)%ld", (signed long) any);
return ix;
}

if (MMC_HDR_IS_FORWARD(MMC_GETHDR(any))) {
checkAnyStringBufSize(ix,40);
ix += sprintf(anyStringBuf+ix, "#Forward");
return ix;
}

hdr = MMC_HDR_UNMARK(MMC_GETHDR(any));

if (hdr == MMC_NILHDR) {
checkAnyStringBufSize(ix,20);
ix += sprintf(anyStringBuf+ix, "mmc_mk_nil()");
return ix;
}

if (hdr == MMC_REALHDR) {
checkAnyStringBufSize(ix,50);
ix += sprintf(anyStringBuf+ix, "mmc_mk_rcon(%.7g)", (double) mmc_prim_get_real(any));
return ix;
}
if (MMC_HDRISSTRING(hdr)) {
MMC_CHECK_STRING(any);
checkAnyStringBufSize(ix,strlen(MMC_STRINGDATA(any))+40);
char *str = omc__escapedString(MMC_STRINGDATA(any), 1);
ix += sprintf(anyStringBuf+ix, "mmc_mk_scon(\"%s\")", str ? str : MMC_STRINGDATA(any));
if (str) free(str);
return ix;
}

numslots = MMC_HDRSLOTS(hdr);
ctor = MMC_HDRCTOR(hdr);

/* Ugly hack to "detect" function pointers. If these parameters are outside
* these bounds, then we probably have a function pointer. This is just to
* keep the debugger from crashing. */
if (numslots < 0 || numslots > 1024 || ctor > 255) {
checkAnyStringBufSize(ix, 100);
ix += sprintf(anyStringBuf+ix, "/* function pointer */");
return ix;
}

if (numslots>0 && ctor == MMC_FREE_OBJECT_CTOR) { /* FREE OBJECT! */
checkAnyStringBufSize(ix,100);
ix += sprintf(anyStringBuf+ix, "FREE(%u)", numslots);
return ix;
}
if (numslots>=0 && ctor == MMC_ARRAY_TAG) { /* MetaModelica-style array */
checkAnyStringBufSize(ix,40);
ix += sprintf(anyStringBuf+ix, "MetaArray(");
for (i=1; i<=numslots; i++) {
data = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),i));
ix = anyStringWorkCode(data, ix);
if (i!=numslots) {
checkAnyStringBufSize(ix,3);
ix += sprintf(anyStringBuf+ix, ", ");
}
}
checkAnyStringBufSize(ix,2);
ix += sprintf(anyStringBuf+ix, ")");
return ix;
}
if (numslots>0 && ctor > 1) { /* RECORD */
desc = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),1));
checkAnyStringBufSize(ix,strlen(desc->name)+100);
ix += sprintf(anyStringBuf+ix, "mmc_mk_box%d(%d, &%s__desc", numslots, ctor, desc->path);
for (i=2; i<=numslots; i++) {
checkAnyStringBufSize(ix,3);
ix += sprintf(anyStringBuf+ix, ", ");
data = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),i));
ix = anyStringWorkCode(data,ix);
}
checkAnyStringBufSize(ix,3);
ix += sprintf(anyStringBuf+ix, ")\n");
return ix;
}

if (numslots>0 && ctor == 0) { /* TUPLE */
checkAnyStringBufSize(ix,40);
ix += sprintf(anyStringBuf+ix, "mmc_mk_box%d(0", numslots);
for (i=0; i<numslots; i++) {
checkAnyStringBufSize(ix,3);
ix += sprintf(anyStringBuf+ix, ", ");
ix = anyStringWorkCode(MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),i+1)),ix);
}
checkAnyStringBufSize(ix,2);
ix += sprintf(anyStringBuf+ix, ")");
return ix;
}

if (numslots==0 && ctor==1) /* NONE() */ {
checkAnyStringBufSize(ix,40);
ix += sprintf(anyStringBuf+ix, "mmc_mk_none()");
return ix;
}

if (numslots==1 && ctor==1) /* SOME(x) */ {
checkAnyStringBufSize(ix,40);
ix += sprintf(anyStringBuf+ix, "mmc_mk_some(");
ix = anyStringWorkCode(MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),1)),ix);
checkAnyStringBufSize(ix,2);
ix += sprintf(anyStringBuf+ix, ")");
return ix;
}

if (numslots==2 && ctor==1) { /* CONS-PAIR */
int i = 0;
while (!MMC_NILTEST(any)) {
checkAnyStringBufSize(ix,40);
ix += sprintf(anyStringBuf+ix, "mmc_mk_cons(");
ix = anyStringWorkCode(MMC_CAR(any),ix);
checkAnyStringBufSize(ix,4);
ix += sprintf(anyStringBuf+ix, "\n,");
any = MMC_CDR(any);
i++;
}
checkAnyStringBufSize(ix,40);
ix += sprintf(anyStringBuf+ix, "mmc_mk_nil()");
while (i--) {
checkAnyStringBufSize(ix,2);
ix += sprintf(anyStringBuf+ix, ")");
}
return ix;
}

fprintf(stderr, "%s:%d: %d slots; ctor %d - FAILED to detect the type\n", __FILE__, __LINE__, numslots, ctor);
/* fprintf(stderr, "object: %032s||", ltoa((int)hdr, buf, 2)); */
checkAnyStringBufSize(ix,5);
ix += sprintf(anyStringBuf+ix, "UNK(");
for (i=1; i<=numslots; i++)
{
ix = anyStringWorkCode(MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),i)),ix);
data = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),i));
/* fprintf(stderr, "%032s|", ltoa((int)data, buf, 2)); */
}
checkAnyStringBufSize(ix,2);
ix += sprintf(anyStringBuf+ix, ")");
fprintf(stderr, "\n"); fflush(NULL);
/* EXIT(1); */
return ix;
}

void* mmc_anyStringCode(void* any)
{
initializeStringBuffer();
anyStringWorkCode(any,0);
return mmc_mk_scon(anyStringBuf);
}

const char* anyStringCode(void* any)
{
initializeStringBuffer();
anyStringWorkCode(any,0);
fprintf(stderr, "%s", anyStringBuf);
return anyStringBuf;
}

void printTypeOfAny(void* any) /* for debugging */
{
mmc_uint_t hdr;
Expand Down
50 changes: 50 additions & 0 deletions SimulationRuntime/c/util/modelica_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,53 @@ modelica_string_const cat_modelica_string(modelica_string_const s1, modelica_str
return dest;
}

extern int omc__escapedStringLength(const char* str, int nl)
{
int i=0;
while (*str) {
switch (*str) {
case '"':
case '\\':
case '\a':
case '\b':
case '\f':
case '\v': i++;
case '\r': i++; if (nl && str[1] == '\n') str++;
case '\n': i++; if (nl && str[1] == '\r') str++;
default: i++;
}
str++;
}
return i;
}

/* "\b",_ => "\\b"
* "\n",true => "\\n"
*/
extern char* omc__escapedString(const char* str, int nl)
{
int len1,len2;
char *res;
int i=0;
len1 = strlen(str);
len2 = omc__escapedStringLength(str,nl);
if (len1 == len2) return NULL;
res = (char*) malloc(len2+1);
while (*str) {
switch (*str) {
case '"': res[i++] = '\\'; res[i++] = '"'; break;
case '\\': res[i++] = '\\'; res[i++] = '\\'; break;
case '\a': res[i++] = '\\'; res[i++] = 'a'; break;
case '\b': res[i++] = '\\'; res[i++] = 'b'; break;
case '\f': res[i++] = '\\'; res[i++] = 'f'; break;
case '\v': res[i++] = '\\'; res[i++] = 'v'; break;
case '\r': if (nl) {res[i++] = '\\'; res[i++] = 'n'; if (str[1] == '\n') str++;} else {res[i++] = *str;} break;
case '\n': if (nl) {res[i++] = '\\'; res[i++] = 'n'; if (str[1] == '\r') str++;} else {res[i++] = *str;} break;
default: res[i++] = *str;
}
str++;
}
res[i] = '\0';
return res;
}

4 changes: 4 additions & 0 deletions SimulationRuntime/c/util/modelica_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ extern modelica_string_const copy_modelica_string(modelica_string_const source);

/* Concatenate strings */
extern modelica_string_const cat_modelica_string(modelica_string_const s1, modelica_string_const s2);

/* Escape string */
extern char* omc__escapedString(const char* str, int nl);

#endif

#endif

0 comments on commit 41ec89c

Please sign in to comment.