summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2014-11-05 10:52:54 -0500
committerAdrian Thurston <thurston@complang.org>2014-11-05 10:52:54 -0500
commitcfdd44324daaa9bf761dff771f37b5f795c03b9e (patch)
tree4a0082f8b51c42105232d152114a894cc37afd82
parent20327ecf9c6055f884e92a5eefbf801701904f31 (diff)
downloadcolm-cfdd44324daaa9bf761dff771f37b5f795c03b9e.tar.gz
the stream type is now a pointer-to-stream
-rw-r--r--src/bytecode.c110
-rw-r--r--src/codegen.cc3
-rw-r--r--src/compiler.cc6
-rw-r--r--src/declare.cc8
-rw-r--r--src/input.c42
-rw-r--r--src/input.h1
-rw-r--r--src/loadcolm.cc4
-rw-r--r--src/loadinit.cc1
-rw-r--r--src/pdarun.c12
-rw-r--r--src/resolve.cc8
-rw-r--r--src/synthesis.cc22
-rw-r--r--src/tree.c5
-rw-r--r--src/tree.h1
13 files changed, 141 insertions, 82 deletions
diff --git a/src/bytecode.c b/src/bytecode.c
index 3a987700..29a37b91 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -155,7 +155,7 @@ Word streamAppend( Program *prg, Tree **sp, Tree *input, StreamImpl *is )
length = collect.length;
strCollectDestroy( &collect );
}
- else if ( input->id == LEL_ID_STREAM ) {
+ else if ( input->id == LEL_ID_PTR ) {
treeUpref( input );
is->funcs->appendStream( is, input );
}
@@ -167,6 +167,23 @@ Word streamAppend( Program *prg, Tree **sp, Tree *input, StreamImpl *is )
return length;
}
+void undoStreamAppend( Program *prg, Tree **sp, StreamImpl *is, Tree *input, long length )
+{
+ if ( input->id == LEL_ID_STR )
+ is->funcs->undoAppendData( is, length );
+ else if ( input->id == LEL_ID_PTR )
+ is->funcs->undoAppendStream( is );
+ else {
+ Tree *tree = is->funcs->undoAppendTree( is );
+ treeDownref( prg, sp, tree );
+ }
+}
+
+StreamImpl *streamToImpl( Stream *ptr )
+{
+ return ((Stream*) ((Pointer*)ptr)->value->tree)->in;
+}
+
long parseFrag( Program *prg, Tree **sp, Parser *parser, long stopId, long entry )
{
switch ( entry ) {
@@ -175,7 +192,8 @@ case PcrStart:
if ( ! parser->pdaRun->parseError ) {
parser->pdaRun->stopTarget = stopId;
- long pcr = parseLoop( prg, sp, parser->pdaRun, parser->input->in, entry );
+ long pcr = parseLoop( prg, sp, parser->pdaRun,
+ streamToImpl( parser->input ), entry );
while ( pcr != PcrDone ) {
@@ -185,7 +203,8 @@ case PcrGeneration:
case PcrPreEof:
case PcrReverse:
- pcr = parseLoop( prg, sp, parser->pdaRun, parser->input->in, entry );
+ pcr = parseLoop( prg, sp, parser->pdaRun,
+ streamToImpl( parser->input ), entry );
}
}
@@ -198,14 +217,17 @@ break; }
long parseFinish( Tree **result, Program *prg, Tree **sp,
Parser *parser, int revertOn, long entry )
{
+ StreamImpl *si;
switch ( entry ) {
case PcrStart:
if ( parser->pdaRun->stopTarget <= 0 ) {
- parser->input->in->funcs->setEof( parser->input->in );
+ si = streamToImpl( parser->input );
+ si->funcs->setEof( si );
if ( ! parser->pdaRun->parseError ) {
- long pcr = parseLoop( prg, sp, parser->pdaRun, parser->input->in, entry );
+ si = streamToImpl( parser->input );
+ long pcr = parseLoop( prg, sp, parser->pdaRun, si, entry );
while ( pcr != PcrDone ) {
@@ -215,7 +237,8 @@ case PcrGeneration:
case PcrPreEof:
case PcrReverse:
- pcr = parseLoop( prg, sp, parser->pdaRun, parser->input->in, entry );
+ si = streamToImpl( parser->input );
+ pcr = parseLoop( prg, sp, parser->pdaRun, si, entry );
}
}
}
@@ -223,7 +246,7 @@ case PcrReverse:
/* FIXME: need something here to check that we are not stopped waiting for
* more data when we are actually expected to finish. This check doesn't
* work (at time of writing). */
- //assert( (parser->pdaRun->stopTarget > 0 && parser->pdaRun->stopParsing) || parser->input->in->eofSent );
+ //assert( (parser->pdaRun->stopTarget > 0 && parser->pdaRun->stopParsing) || streamToImpl( parser->input )->eofSent );
if ( !revertOn )
commitFull( prg, sp, parser->pdaRun, 0 );
@@ -241,7 +264,6 @@ break; }
long undoParseFrag( Program *prg, Tree **sp, Parser *parser, long steps, long entry )
{
- StreamImpl *is = parser->input->in;
PdaRun *pdaRun = parser->pdaRun;
debug( prg, REALM_PARSE, "undo parse frag, target steps: %ld, pdarun steps: %ld\n", steps, pdaRun->steps );
@@ -259,7 +281,7 @@ case PcrStart:
pdaRun->triggerUndo = 1;
/* The parse loop will recognise the situation. */
- long pcr = parseLoop( prg, sp, pdaRun, is, entry );
+ long pcr = parseLoop( prg, sp, pdaRun, streamToImpl(parser->input), entry );
while ( pcr != PcrDone ) {
return pcr;
@@ -268,7 +290,7 @@ case PcrGeneration:
case PcrPreEof:
case PcrReverse:
- pcr = parseLoop( prg, sp, pdaRun, is, entry );
+ pcr = parseLoop( prg, sp, pdaRun, streamToImpl(parser->input), entry );
}
/* Reset environment. */
@@ -919,18 +941,19 @@ again:
Tree *arg[n];
for ( i = n-1; i >= 0; i-- )
arg[i] = vm_pop();
- Stream *stream = (Stream*)vm_pop();
+ Pointer *ptr = (Pointer*)vm_pop();
+ StreamImpl *si = streamToImpl( (Stream*)ptr );
for ( i = 0; i < n; i++ ) {
- if ( stream->in->file != 0 )
- printTreeFile( prg, sp, stream->in->file, arg[i], false );
+ if ( si->file != 0 )
+ printTreeFile( prg, sp, si->file, arg[i], false );
else
- printTreeFd( prg, sp, stream->in->fd, arg[i], false );
+ printTreeFd( prg, sp, si->fd, arg[i], false );
}
for ( i = 0; i < n; i++ )
treeDownref( prg, sp, arg[i] );
- treeDownref( prg, sp, (Tree*)stream );
+ treeDownref( prg, sp, (Tree*)ptr );
break;
}
case IN_PRINT_XML_AC: {
@@ -2125,27 +2148,31 @@ again:
case IN_INPUT_APPEND_WC: {
debug( prg, REALM_BYTECODE, "IN_INPUT_APPEND_WC \n" );
- Stream *accumStream = (Stream*)vm_pop();
+ Pointer *sptr = (Pointer*) vm_pop();
Tree *input = vm_pop();
- streamAppend( prg, sp, input, accumStream->in );
- vm_push( (Tree*)accumStream );
+ StreamImpl *si = streamToImpl( (Stream*)sptr );
+ streamAppend( prg, sp, input, si );
+
+ vm_push( (Tree*)sptr );
treeDownref( prg, sp, input );
break;
}
case IN_INPUT_APPEND_WV: {
debug( prg, REALM_BYTECODE, "IN_INPUT_APPEND_WV \n" );
- Stream *accumStream = (Stream*)vm_pop();
+ Pointer *sptr = (Pointer*) vm_pop();
Tree *input = vm_pop();
- Word len = streamAppend( prg, sp, input, accumStream->in );
- treeUpref( (Tree*)accumStream );
- vm_push( (Tree*)accumStream );
+ StreamImpl *si = streamToImpl( (Stream*)sptr );
+ Word len = streamAppend( prg, sp, input, si );
+
+ treeUpref( (Tree*)sptr );
+ vm_push( (Tree*)sptr );
rcodeUnitStart( exec );
rcodeCode( exec, IN_INPUT_APPEND_BKT );
- rcodeWord( exec, (Word) accumStream );
+ rcodeWord( exec, (Word) sptr );
rcodeWord( exec, (Word) input );
rcodeWord( exec, (Word) len );
rcodeUnitTerm( exec );
@@ -2153,17 +2180,19 @@ again:
}
case IN_INPUT_APPEND_BKT: {
- Tree *accumStream;
+ Tree *sptr;
Tree *input;
Word len;
- read_tree( accumStream );
+ read_tree( sptr );
read_tree( input );
read_word( len );
debug( prg, REALM_BYTECODE, "IN_INPUT_APPEND_BKT\n" );
- undoStreamAppend( prg, sp, ((Stream*)accumStream)->in, input, len );
- treeDownref( prg, sp, accumStream );
+ StreamImpl *si = streamToImpl( (Stream*)sptr );
+ undoStreamAppend( prg, sp, si, input, len );
+
+ treeDownref( prg, sp, sptr );
treeDownref( prg, sp, input );
break;
}
@@ -2474,7 +2503,8 @@ again:
exec->pcr = (long)vm_pop();
exec->parser = (Parser*)vm_pop();
- parser->input->in->funcs->unsetEof( parser->input->in );
+ StreamImpl *si = streamToImpl( parser->input );
+ si->funcs->unsetEof( si );
treeDownref( prg, sp, (Tree*)parser );
break;
}
@@ -2612,7 +2642,9 @@ again:
Tree *input = constructStream( prg );
treeUpref( input );
- vm_push( input );
+ Tree *ptr = constructPointer( prg, input );
+ treeUpref( ptr );
+ vm_push( ptr );
break;
}
case IN_GET_INPUT: {
@@ -2628,11 +2660,11 @@ again:
debug( prg, REALM_BYTECODE, "IN_SET_INPUT\n" );
Parser *parser = (Parser*)vm_pop();
- Stream *accumStream = (Stream*)vm_pop();
- parser->input = accumStream;
- treeUpref( (Tree*)accumStream );
+ Stream *stream = (Stream*)vm_pop();
+ parser->input = stream;
+ treeUpref( (Tree*)stream );
treeDownref( prg, sp, (Tree*)parser );
- treeDownref( prg, sp, (Tree*)accumStream );
+ treeDownref( prg, sp, (Tree*)stream );
break;
}
case IN_CONSTRUCT_TERM: {
@@ -3682,7 +3714,9 @@ again:
Tree *obj = vm_pop();
treeDownref( prg, sp, obj );
if ( prg->stdinVal == 0 ) {
- prg->stdinVal = openStreamFd( prg, "<stdin>", 0 );
+ Tree *val = (Tree*)openStreamFd( prg, "<stdin>", 0 );
+ treeUpref( val );
+ prg->stdinVal = (Stream*)constructPointer( prg, val );
treeUpref( (Tree*)prg->stdinVal );
}
@@ -3697,7 +3731,9 @@ again:
Tree *obj = vm_pop();
treeDownref( prg, sp, obj );
if ( prg->stdoutVal == 0 ) {
- prg->stdoutVal = openStreamFd( prg, "<stdout>", 1 );
+ Tree *val = (Tree*)openStreamFd( prg, "<stdout>", 1 );
+ treeUpref( val );
+ prg->stdoutVal = (Stream*)constructPointer( prg, val );
treeUpref( (Tree*)prg->stdoutVal );
}
@@ -3712,7 +3748,9 @@ again:
Tree *obj = vm_pop();
treeDownref( prg, sp, obj );
if ( prg->stderrVal == 0 ) {
- prg->stderrVal = openStreamFd( prg, "<stderr>", 2 );
+ Tree *val = (Tree*)openStreamFd( prg, "<stderr>", 2 );
+ treeUpref( val );
+ prg->stderrVal = (Stream*)constructPointer( prg, val );
treeUpref( (Tree*)prg->stderrVal );
}
diff --git a/src/codegen.cc b/src/codegen.cc
index e3d5b3bf..a61a5c0e 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -19,7 +19,8 @@ void FsmCodeGen::writeMain( long activeRealm )
" struct colm_program *prg;\n"
" int exitStatus;\n"
" prg = colm_new_program( &colm_object );\n"
- " colm_set_debug( prg, " << activeRealm << " );\n"
+// " colm_set_debug( prg, " << activeRealm << " );\n"
+ " colm_set_debug( prg, 0x3 );\n"
" colm_run_program( prg, argc, argv );\n"
" exitStatus = colm_delete_program( prg );\n"
" return exitStatus;\n"
diff --git a/src/compiler.cc b/src/compiler.cc
index 45c39172..ae175492 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -964,7 +964,10 @@ PdaRun *Compiler::parsePattern( Program *prg, Tree **sp, const InputLoc &loc,
Stream *res = streamAllocate( prg );
res->id = LEL_ID_STREAM;
res->in = sourceStream;
- in->funcs->appendStream( in, (Tree*)res );
+
+ Tree *ptr = constructPointer( prg, (Tree*)res );
+
+ in->funcs->appendStream( in, ptr );
in->funcs->setEof( in );
long pcr = parseLoop( prg, sp, pdaRun, in, PcrStart );
@@ -992,6 +995,7 @@ PdaRun *Compiler::parsePattern( Program *prg, Tree **sp, const InputLoc &loc,
void Compiler::parsePatterns()
{
Program *prg = colm_new_program( runtimeData );
+ colm_set_debug( prg, 0x03 );
/* Turn off context-dependent parsing. */
prg->ctxDepParsing = 0;
diff --git a/src/declare.cc b/src/declare.cc
index 57b179c4..ee703e40 100644
--- a/src/declare.cc
+++ b/src/declare.cc
@@ -753,6 +753,7 @@ void Compiler::addInput( ObjectDef *frame )
{
/* Make the type ref. */
TypeRef *typeRef = TypeRef::cons( internal, uniqueTypeStream );
+ typeRef = TypeRef::cons( internal, TypeRef::Ptr, typeRef );
/* Create the field and insert it into the map. */
ObjectField *el = ObjectField::cons( internal, typeRef, "input" );
@@ -942,7 +943,9 @@ void Compiler::initGlobalFunctions()
{
ObjMethod *method;
- method = initFunction( uniqueTypeStream, globalObjectDef, "open",
+ UniqueType *streamPtrUt = findUniqueType( TYPE_PTR, streamLangEl );
+
+ method = initFunction( streamPtrUt, globalObjectDef, "open",
IN_OPEN_FILE, IN_OPEN_FILE, uniqueTypeStr, uniqueTypeStr, true );
method->useCallObj = false;
@@ -971,6 +974,7 @@ void Compiler::addStdin()
{
/* Make the type ref. */
TypeRef *typeRef = TypeRef::cons( internal, uniqueTypeStream );
+ typeRef = TypeRef::cons( internal, TypeRef::Ptr, typeRef );
/* Create the field and insert it into the map. */
ObjectField *el = ObjectField::cons( internal, typeRef, "stdin" );
@@ -988,6 +992,7 @@ void Compiler::addStdout()
{
/* Make the type ref. */
TypeRef *typeRef = TypeRef::cons( internal, uniqueTypeStream );
+ typeRef = TypeRef::cons( internal, TypeRef::Ptr, typeRef );
/* Create the field and insert it into the map. */
ObjectField *el = ObjectField::cons( internal, typeRef, "stdout" );
@@ -1005,6 +1010,7 @@ void Compiler::addStderr()
{
/* Make the type ref. */
TypeRef *typeRef = TypeRef::cons( internal, uniqueTypeStream );
+ typeRef = TypeRef::cons( internal, TypeRef::Ptr, typeRef );
/* Create the field and insert it into the map. */
ObjectField *el = ObjectField::cons( internal, typeRef, "stderr" );
diff --git a/src/input.c b/src/input.c
index 69210361..9c56b5e9 100644
--- a/src/input.c
+++ b/src/input.c
@@ -424,8 +424,8 @@ static void _setEof( StreamImpl *is )
static void _unsetEof( StreamImpl *is )
{
if ( isSourceStream( is ) ) {
- Stream *stream = (Stream*)is->queue->tree;
- stream->in->eof = false;
+ StreamImpl *si = streamToImpl( (Stream*)is->queue->tree );
+ si->eof = false;
}
else {
is->eof = false;
@@ -447,11 +447,11 @@ static int _getParseBlock( StreamImpl *is, int skip, char **pdp, int *copied )
}
if ( buf->type == RunBufSourceType ) {
- Stream *stream = (Stream*)buf->tree;
- int type = stream->in->funcs->getParseBlock( stream->in, skip, pdp, copied );
+ StreamImpl *si = streamToImpl( (Stream*)buf->tree );
+ int type = si->funcs->getParseBlock( si, skip, pdp, copied );
-// if ( type == INPUT_EOD && !stream->in->eosSent ) {
-// stream->in->eosSent = 1;
+// if ( type == INPUT_EOD && !si->eosSent ) {
+// si->eosSent = 1;
// ret = INPUT_EOS;
// continue;
// }
@@ -544,8 +544,8 @@ static int _getData( StreamImpl *is, char *dest, int length )
}
if ( buf->type == RunBufSourceType ) {
- Stream *stream = (Stream*)buf->tree;
- int glen = stream->in->funcs->getData( stream->in, dest+copied, length );
+ StreamImpl *si = streamToImpl( (Stream*)buf->tree );
+ int glen = si->funcs->getData( si, dest+copied, length );
if ( glen == 0 ) {
//debug( REALM_INPUT, "skipping over input\n" );
@@ -601,8 +601,8 @@ static int _consumeData( Program *prg, Tree **sp, StreamImpl *is, int length, Lo
break;
if ( buf->type == RunBufSourceType ) {
- Stream *stream = (Stream*)buf->tree;
- int slen = stream->in->funcs->consumeData( prg, sp, stream->in, length, loc );
+ StreamImpl *si = streamToImpl( (Stream*)buf->tree );
+ int slen = si->funcs->consumeData( prg, sp, si, length, loc );
//debug( REALM_INPUT, " got %d bytes from source\n", slen );
consumed += slen;
@@ -646,8 +646,8 @@ static int _undoConsumeData( StreamImpl *is, const char *data, int length )
//debug( REALM_INPUT, "undoing consume of %ld bytes\n", length );
if ( is->consumed == 0 && isSourceStream( is ) ) {
- Stream *stream = (Stream*)is->queue->tree;
- int len = stream->in->funcs->undoConsumeData( stream->in, data, length );
+ StreamImpl *si = streamToImpl( (Stream*)is->queue->tree );
+ int len = si->funcs->undoConsumeData( si, data, length );
return len;
}
else {
@@ -694,8 +694,8 @@ static void _undoConsumeTree( StreamImpl *is, Tree *tree, int ignore )
static struct LangEl *_consumeLangEl( StreamImpl *is, long *bindId, char **data, long *length )
{
if ( isSourceStream( is ) ) {
- Stream *stream = (Stream*)is->queue->tree;
- return stream->in->funcs->consumeLangEl( stream->in, bindId, data, length );
+ StreamImpl *si = streamToImpl( (Stream*)is->queue->tree );
+ return si->funcs->consumeLangEl( si, bindId, data, length );
}
else {
assert( false );
@@ -705,8 +705,8 @@ static struct LangEl *_consumeLangEl( StreamImpl *is, long *bindId, char **data,
static void _undoConsumeLangEl( StreamImpl *is )
{
if ( isSourceStream( is ) ) {
- Stream *stream = (Stream*)is->queue->tree;
- return stream->in->funcs->undoConsumeLangEl( stream->in );
+ StreamImpl *si = streamToImpl( (Stream*)is->queue->tree );
+ return si->funcs->undoConsumeLangEl( si );
}
else {
assert( false );
@@ -715,10 +715,8 @@ static void _undoConsumeLangEl( StreamImpl *is )
static void _prependData( StreamImpl *is, const char *data, long length )
{
- if ( isSourceStream( is ) && ((Stream*)is->queue->tree)->in->funcs == &streamFuncs ) {
- Stream *stream = (Stream*)is->queue->tree;
-
- _prependData( stream->in, data, length );
+ if ( isSourceStream( is ) && streamToImpl( (Stream*)is->queue->tree)->funcs == &streamFuncs ) {
+ _prependData( streamToImpl( (Stream*)is->queue->tree ), data, length );
}
else {
/* Create a new buffer for the data. This is the easy implementation.
@@ -770,8 +768,8 @@ static int _undoPrependData( StreamImpl *is, int length )
break;
if ( buf->type == RunBufSourceType ) {
- Stream *stream = (Stream*)buf->tree;
- int slen = stream->in->funcs->undoPrependData( stream->in, length );
+ StreamImpl *si = streamToImpl( (Stream*)buf->tree );
+ int slen = si->funcs->undoPrependData( si, length );
consumed += slen;
length -= slen;
diff --git a/src/input.h b/src/input.h
index 7fefe36a..ea2d42e1 100644
--- a/src/input.h
+++ b/src/input.h
@@ -47,6 +47,7 @@ struct Constructor;
struct ConsItem;
struct _FsmRun;
struct colm_tree;
+struct colm_stream;
struct colm_location;
struct colm_program;
diff --git a/src/loadcolm.cc b/src/loadcolm.cc
index 85da59b0..495bd445 100644
--- a/src/loadcolm.cc
+++ b/src/loadcolm.cc
@@ -744,6 +744,7 @@ struct LoadColm
argv[2] = 0;
colm_program *program = colm_new_program( &colm_object );
+ colm_set_debug( program, 0x3 );
colm_run_program( program, 2, argv );
/* Extract the parse tree. */
@@ -2408,7 +2409,8 @@ void LoadColm::go( long activeRealm )
argv[2] = 0;
colm_program *program = colm_new_program( &colm_object );
- colm_set_debug( program, activeRealm );
+// colm_set_debug( program, activeRealm );
+ colm_set_debug( program, 0x3 );
colm_run_program( program, 2, argv );
/* Extract the parse tree. */
diff --git a/src/loadinit.cc b/src/loadinit.cc
index 054e48cf..370f7f5f 100644
--- a/src/loadinit.cc
+++ b/src/loadinit.cc
@@ -338,6 +338,7 @@ void LoadInit::go( long activeRealm )
argv[2] = 0;
colm_program *program = colm_new_program( &colm_object );
+ colm_set_debug( program, 0x3 );
colm_run_program( program, 2, argv );
/* Extract the parse tree. */
diff --git a/src/pdarun.c b/src/pdarun.c
index 96170026..16036050 100644
--- a/src/pdarun.c
+++ b/src/pdarun.c
@@ -149,18 +149,6 @@ void undoStreamPush( Program *prg, Tree **sp, StreamImpl *is, long length )
}
}
-void undoStreamAppend( Program *prg, Tree **sp, StreamImpl *is, Tree *input, long length )
-{
- if ( input->id == LEL_ID_STR )
- is->funcs->undoAppendData( is, length );
- else if ( input->id == LEL_ID_STREAM )
- is->funcs->undoAppendStream( is );
- else {
- Tree *tree = is->funcs->undoAppendTree( is );
- treeDownref( prg, sp, tree );
- }
-}
-
/* Should only be sending back whole tokens/ignores, therefore the send back
* should never cross a buffer boundary. Either we slide back data, or we move to
* a previous buffer and slide back data. */
diff --git a/src/resolve.cc b/src/resolve.cc
index a753a305..96923c64 100644
--- a/src/resolve.cc
+++ b/src/resolve.cc
@@ -59,7 +59,13 @@ UniqueType *TypeRef::resolveTypeName( Compiler *pd )
}
case TypeMapEl::LangElType: {
- return pd->findUniqueType( TYPE_TREE, inDict->value );
+ UniqueType *ut = pd->findUniqueType( TYPE_TREE, inDict->value );
+ if ( ut == pd->uniqueTypeStream ) {
+ std::cerr << "resolving langEl as ptr to tree because"
+ " it is a stream" << std::endl;
+ return pd->findUniqueType( TYPE_PTR, ut->langEl );
+ }
+ return ut;
}
}
}
diff --git a/src/synthesis.cc b/src/synthesis.cc
index c993a2ba..79e04cee 100644
--- a/src/synthesis.cc
+++ b/src/synthesis.cc
@@ -528,6 +528,11 @@ bool castAssignment( Compiler *pd, CodeVect &code, UniqueType *destUT,
if ( destUT->typeId == TYPE_TREE && destUT->langEl == pd->anyLangEl &&
srcUT->typeId == TYPE_TREE )
return true;
+
+ /* Casting pointers to any. */
+ if ( destUT->typeId == TYPE_TREE && destUT->langEl == pd->anyLangEl &&
+ srcUT->typeId == TYPE_PTR )
+ return true;
/* Setting a reference from a tree. */
if ( destUT->typeId == TYPE_REF && srcUT->typeId == TYPE_TREE &&
@@ -1254,8 +1259,9 @@ UniqueType *LangTerm::evaluateParse( Compiler *pd, CodeVect &code, bool tree, bo
continue;
}
+ UniqueType *streamPtrUt = pd->findUniqueType( TYPE_PTR, pd->streamLangEl );
if ( !tree && ut->typeId == TYPE_TREE &&
- ut->langEl != pd->strLangEl && ut->langEl != pd->streamLangEl )
+ ut->langEl != pd->strLangEl && ut != streamPtrUt )
{
/* Convert it to a string. */
code.append( IN_TREE_TO_STR_TRIM );
@@ -1440,8 +1446,9 @@ void LangTerm::evaluateSendParser( Compiler *pd, CodeVect &code, bool strings )
continue;
}
+ UniqueType *streamPtrUt = pd->findUniqueType( TYPE_PTR, pd->streamLangEl );
if ( strings && ut->typeId == TYPE_TREE &&
- ut->langEl != pd->strLangEl && ut->langEl != pd->streamLangEl )
+ ut->langEl != pd->strLangEl && ut != streamPtrUt )
{
/* Convert it to a string. */
code.append( IN_TREE_TO_STR_TRIM );
@@ -1486,7 +1493,9 @@ UniqueType *LangTerm::evaluateSend( Compiler *pd, CodeVect &code ) const
UniqueType *varUt = varRef->lookup( pd );
GenericType *generic = varUt->langEl->generic;
- if ( varUt == pd->uniqueTypeStream )
+ UniqueType *streamPtrUt = pd->findUniqueType( TYPE_PTR, pd->streamLangEl );
+
+ if ( varUt == streamPtrUt )
evaluateSendStream( pd, code );
else if ( generic != 0 && generic->typeId == GEN_PARSER )
evaluateSendParser( pd, code, true );
@@ -1541,17 +1550,18 @@ UniqueType *LangTerm::evaluateEmbedString( Compiler *pd, CodeVect &code ) const
code.appendWord( mapEl->value );
break;
}
- case ConsItem::ExprType:
+ case ConsItem::ExprType: {
UniqueType *ut = item->expr->evaluate( pd, code );
+ UniqueType *streamPtrUt = pd->findUniqueType( TYPE_PTR, pd->streamLangEl );
if ( ut->typeId == TYPE_TREE &&
- ut->langEl != pd->strLangEl && ut->langEl != pd->streamLangEl )
+ ut->langEl != pd->strLangEl && ut != streamPtrUt )
{
/* Convert it to a string. */
code.append( IN_TREE_TO_STR_TRIM );
}
break;
- }
+ }}
}
/* If there was nothing loaded, load the empty string. We must produce
diff --git a/src/tree.c b/src/tree.c
index 4fab2bd1..f8c60070 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -212,8 +212,11 @@ Stream *openFile( Program *prg, Tree *name, Tree *mode )
memcpy( fileName, stringData(headName), stringLength(headName) );
fileName[stringLength(headName)] = 0;
FILE *file = fopen( fileName, fopenMode );
- if ( file != 0 )
+ if ( file != 0 ) {
stream = openStreamFile( prg, fileName, file );
+ treeUpref( (Tree*)stream );
+ stream = (Stream*)constructPointer( prg, (Tree*)stream );
+ }
return stream;
}
diff --git a/src/tree.h b/src/tree.h
index 311c227a..5f8cb568 100644
--- a/src/tree.h
+++ b/src/tree.h
@@ -349,6 +349,7 @@ void userIterDestroy( struct colm_program *prg, Tree ***psp, UserIter *uiter );
void userIterDestroy2( struct colm_program *prg, Tree ***psp, UserIter *uiter );
Tree *castTree( struct colm_program *prg, int langElId, Tree *tree );
+StreamImpl *streamToImpl( Stream *ptr );
#if defined(__cplusplus)
}