summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/colm.lm2
-rw-r--r--src/compiler.h17
-rw-r--r--src/consinit.cc15
-rw-r--r--src/declare.cc126
-rw-r--r--src/loadcolm.cc15
-rw-r--r--src/loadinit.cc23
-rw-r--r--src/lookup.cc65
-rw-r--r--src/parser.cc55
-rw-r--r--src/parser.h10
-rw-r--r--src/parsetree.h134
-rw-r--r--src/resolve.cc2
-rw-r--r--src/synthesis.cc6
-rw-r--r--test/binary1.lm2
-rw-r--r--test/exit6.lm7
-rw-r--r--test/generate2.lm2
-rw-r--r--test/inpush1.lm2
-rw-r--r--test/lookup1.lm4
-rw-r--r--test/tags3.lm4
18 files changed, 310 insertions, 181 deletions
diff --git a/src/colm.lm b/src/colm.lm
index 30a50c31..29c70a8c 100644
--- a/src/colm.lm
+++ b/src/colm.lm
@@ -745,7 +745,7 @@ def string
#
def var_ref
- [qual id]
+ [region_qual qual id]
def qual
[qual id DOT] :Dot
diff --git a/src/compiler.h b/src/compiler.h
index e7cd3fc8..e953c473 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -1045,13 +1045,30 @@ LangEl *findType( Compiler *pd, Namespace *nspace, const String &data );
ObjectMethod *initFunction( UniqueType *retType, ObjectDef *obj,
const String &name, int methIdWV, int methIdWC,
bool isConst, bool useFnInstr = false, GenericType *useGeneric = 0 );
+
ObjectMethod *initFunction( UniqueType *retType, ObjectDef *obj,
const String &name, int methIdWV, int methIdWC,
UniqueType *arg1, bool isConst, bool useFnInstr = false,
GenericType *useGeneric = 0 );
+
ObjectMethod *initFunction( UniqueType *retType, ObjectDef *obj,
const String &name, int methIdWV, int methIdWC,
UniqueType *arg1, UniqueType *arg2, bool isConst,
bool useFnInstr = false, GenericType *useGeneric = 0 );
+ObjectMethod *initFunction( UniqueType *retType, Namespace *nspace, ObjectDef *obj,
+ const String &name, int methIdWV, int methIdWC,
+ bool isConst, bool useFnInstr = false, GenericType *useGeneric = 0 );
+
+ObjectMethod *initFunction( UniqueType *retType, Namespace *nspace, ObjectDef *obj,
+ const String &name, int methIdWV, int methIdWC,
+ UniqueType *arg1, bool isConst, bool useFnInstr = false,
+ GenericType *useGeneric = 0 );
+
+ObjectMethod *initFunction( UniqueType *retType, Namespace *nspace, ObjectDef *obj,
+ const String &name, int methIdWV, int methIdWC,
+ UniqueType *arg1, UniqueType *arg2, bool isConst,
+ bool useFnInstr = false, GenericType *useGeneric = 0 );
+
+
#endif /* _PARSEDATA_H */
diff --git a/src/consinit.cc b/src/consinit.cc
index 0653dce2..794c07ae 100644
--- a/src/consinit.cc
+++ b/src/consinit.cc
@@ -755,7 +755,8 @@ void ConsInit::parseInput( StmtList *stmtList )
popQual->append( QualItem( QualItem::Arrow, internal, String( "argv" ) ) );
LangVarRef *popRef = LangVarRef::cons( internal,
- 0, curLocalFrame->rootScope, popQual, String("pop") );
+ curNspace(), 0, curLocalFrame()->rootScope,
+ NamespaceQual::cons( curNspace() ), popQual, String("pop") );
LangExpr *pop = LangExpr::cons( LangTerm::cons( InputLoc(), popRef, popArgs ) );
TypeRef *typeRef = TypeRef::cons( internal, pd->uniqueTypeStr );
@@ -774,15 +775,17 @@ void ConsInit::parseInput( StmtList *stmtList )
/* Reference A->value */
QualItemVect *qual = new QualItemVect;
- LangVarRef *varRef = LangVarRef::cons( internal, 0,
- curLocalFrame->rootScope, qual, String("A") );
+ LangVarRef *varRef = LangVarRef::cons( internal, curNspace(), 0,
+ curLocalFrame()->rootScope, NamespaceQual::cons( curNspace() ),
+ qual, String("A") );
LangExpr *Avalue = LangExpr::cons( LangTerm::cons( internal,
LangTerm::VarRefType, varRef ) );
/* Call open. */
QualItemVect *openQual = new QualItemVect;
LangVarRef *openRef = LangVarRef::cons( internal,
- 0, curLocalFrame->rootScope, openQual, String("open") );
+ 0, 0, curLocalFrame()->rootScope,
+ NamespaceQual::cons( curNspace() ), openQual, String("open") );
CallArgVect *openArgs = new CallArgVect;
openArgs->append( new CallArg(Avalue) );
openArgs->append( new CallArg(modeExpr) );
@@ -811,8 +814,8 @@ void ConsInit::exportTree( StmtList *stmtList )
{
/* reference P */
QualItemVect *qual = new QualItemVect;
- LangVarRef *varRef = LangVarRef::cons( internal, 0,
- curLocalFrame->rootScope, qual, String("P") );
+ LangVarRef *varRef = LangVarRef::cons( internal, curNspace(), 0,
+ curLocalFrame()->rootScope, NamespaceQual::cons( curNspace() ), qual, String("P") );
LangExpr *expr = LangExpr::cons( LangTerm::cons( internal,
LangTerm::VarRefType, varRef ) );
diff --git a/src/declare.cc b/src/declare.cc
index 69c33a91..9116331e 100644
--- a/src/declare.cc
+++ b/src/declare.cc
@@ -49,38 +49,43 @@ void Compiler::initUniqueTypes( )
uniqeTypeMap.insert( uniqueTypeStream );
}
-ObjectMethod *initFunction( UniqueType *retType, ObjectDef *obj,
- const String &name, int methIdWV, int methIdWC, bool isConst,
- bool useFnInstr, GenericType *useGeneric )
+ObjectMethod *initFunction( UniqueType *retType, Namespace *nspace, ObjectDef *obj,
+ const String &name, int methIdWV, int methIdWC,
+ int nargs, UniqueType **args, bool isConst, bool useFnInstr,
+ GenericType *useGeneric )
{
ObjectMethod *objMethod = new ObjectMethod( retType, name,
- methIdWV, methIdWC, 0, 0, 0, isConst );
+ methIdWV, methIdWC, nargs, args, 0, isConst );
objMethod->useFnInstr = useFnInstr;
- obj->rootScope->methodMap.insert( name, objMethod );
-
+
+ if ( nspace != 0 )
+ nspace->rootScope->methodMap.insert( name, objMethod );
+ else
+ obj->rootScope->methodMap.insert( name, objMethod );
+
if ( useGeneric ) {
objMethod->useGenericId = true;
objMethod->generic = useGeneric;
}
+
return objMethod;
}
ObjectMethod *initFunction( UniqueType *retType, ObjectDef *obj,
+ const String &name, int methIdWV, int methIdWC, bool isConst,
+ bool useFnInstr, GenericType *useGeneric )
+{
+ return initFunction( retType, 0, obj, name, methIdWV, methIdWC,
+ 0, 0, isConst, useFnInstr, useGeneric );
+}
+
+ObjectMethod *initFunction( UniqueType *retType, ObjectDef *obj,
const String &name, int methIdWV, int methIdWC, UniqueType *arg1,
bool isConst, bool useFnInstr, GenericType *useGeneric )
{
UniqueType *args[] = { arg1 };
- ObjectMethod *objMethod = new ObjectMethod( retType, name,
- methIdWV, methIdWC, 1, args, 0, isConst );
- objMethod->useFnInstr = useFnInstr;
- obj->rootScope->methodMap.insert( name, objMethod );
-
- if ( useGeneric ) {
- objMethod->useGenericId = true;
- objMethod->generic = useGeneric;
- }
-
- return objMethod;
+ return initFunction( retType, 0, obj, name, methIdWV, methIdWC,
+ 1, args, isConst, useFnInstr, useGeneric );
}
ObjectMethod *initFunction( UniqueType *retType, ObjectDef *obj,
@@ -89,19 +94,40 @@ ObjectMethod *initFunction( UniqueType *retType, ObjectDef *obj,
bool isConst, bool useFnInstr, GenericType *useGeneric )
{
UniqueType *args[] = { arg1, arg2 };
- ObjectMethod *objMethod = new ObjectMethod( retType, name,
- methIdWV, methIdWC, 2, args, 0, isConst );
- objMethod->useFnInstr = useFnInstr;
- obj->rootScope->methodMap.insert( name, objMethod );
+ return initFunction( retType, 0, obj, name, methIdWV, methIdWC,
+ 2, args, isConst, useFnInstr, useGeneric );
+}
- if ( useGeneric ) {
- objMethod->useGenericId = true;
- objMethod->generic = useGeneric;
- }
+/*
+ * With namespace supplied. Global functions.
+ */
- return objMethod;
+ObjectMethod *initFunction( UniqueType *retType, Namespace *nspace, ObjectDef *obj,
+ const String &name, int methIdWV, int methIdWC, bool isConst,
+ bool useFnInstr, GenericType *useGeneric )
+{
+ return initFunction( retType, nspace, obj, name, methIdWV, methIdWC,
+ 0, 0, isConst, useFnInstr, useGeneric );
}
+ObjectMethod *initFunction( UniqueType *retType, Namespace *nspace, ObjectDef *obj,
+ const String &name, int methIdWV, int methIdWC, UniqueType *arg1,
+ bool isConst, bool useFnInstr, GenericType *useGeneric )
+{
+ UniqueType *args[] = { arg1 };
+ return initFunction( retType, nspace, obj, name, methIdWV, methIdWC,
+ 1, args, isConst, useFnInstr, useGeneric );
+}
+
+ObjectMethod *initFunction( UniqueType *retType, Namespace *nspace, ObjectDef *obj,
+ const String &name, int methIdWV, int methIdWC,
+ UniqueType *arg1, UniqueType *arg2,
+ bool isConst, bool useFnInstr, GenericType *useGeneric )
+{
+ UniqueType *args[] = { arg1, arg2 };
+ return initFunction( retType, nspace, obj, name, methIdWV, methIdWC,
+ 2, args, isConst, useFnInstr, useGeneric );
+}
ObjectField *NameScope::checkRedecl( const String &name )
{
@@ -489,7 +515,7 @@ void LangStmt::chooseDefaultIter( Compiler *pd, IterCall *iterCall ) const
/* This is two-part, It gets rewritten before evaluation in synthesis. */
/* The iterator name. */
- LangVarRef *callVarRef = LangVarRef::cons( loc, context, scope, "triter" );
+ LangVarRef *callVarRef = LangVarRef::cons( loc, 0, context, scope, "triter" );
/* The parameters. */
CallArgVect *callExprVect = new CallArgVect;
@@ -812,7 +838,7 @@ void Compiler::declareStrFields( )
initFunction( uniqueTypeStr, strObj, "suffix",
IN_STR_SUFFIX, IN_STR_SUFFIX, uniqueTypeInt, true, true );
- initFunction( uniqueTypeStr, globalObjectDef, "sprintf",
+ initFunction( uniqueTypeStr, rootNamespace, globalObjectDef, "sprintf",
IN_SPRINTF, IN_SPRINTF, uniqueTypeStr, uniqueTypeInt, true );
addLengthField( strObj, IN_STR_LENGTH );
@@ -918,66 +944,66 @@ void Compiler::declareGlobalFields()
{
ObjectMethod *method;
- method = initFunction( uniqueTypeStream, globalObjectDef, "open",
+ method = initFunction( uniqueTypeStream, rootNamespace, globalObjectDef, "open",
IN_OPEN_FILE, IN_OPEN_FILE, uniqueTypeStr, uniqueTypeStr, true );
method->useCallObj = false;
- method = initFunction( uniqueTypeStr, globalObjectDef, "tolower",
+ method = initFunction( uniqueTypeStr, rootNamespace, globalObjectDef, "tolower",
IN_TO_LOWER, IN_TO_LOWER, uniqueTypeStr, true );
method->useCallObj = false;
- method = initFunction( uniqueTypeStr, globalObjectDef, "toupper",
+ method = initFunction( uniqueTypeStr, rootNamespace, globalObjectDef, "toupper",
IN_TO_UPPER, IN_TO_UPPER, uniqueTypeStr, true );
method->useCallObj = false;
- method = initFunction( uniqueTypeInt, globalObjectDef, "atoi",
+ method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "atoi",
IN_STR_ATOI, IN_STR_ATOI, uniqueTypeStr, true, true );
method->useCallObj = false;
- method = initFunction( uniqueTypeInt, globalObjectDef, "atoo",
+ method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "atoo",
IN_STR_ATOO, IN_STR_ATOO, uniqueTypeStr, true, true );
method->useCallObj = false;
- method = initFunction( uniqueTypeStr, globalObjectDef, "prefix",
+ method = initFunction( uniqueTypeStr, rootNamespace, globalObjectDef, "prefix",
IN_PREFIX, IN_PREFIX, uniqueTypeStr, uniqueTypeInt, true, true );
method->useCallObj = false;
- method = initFunction( uniqueTypeStr, globalObjectDef, "suffix",
+ method = initFunction( uniqueTypeStr, rootNamespace, globalObjectDef, "suffix",
IN_SUFFIX, IN_SUFFIX, uniqueTypeStr, uniqueTypeInt, true, true );
method->useCallObj = false;
- method = initFunction( uniqueTypeInt, globalObjectDef, "uord8",
+ method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "uord8",
IN_STR_UORD8, IN_STR_UORD8, uniqueTypeStr, true, true );
method->useCallObj = false;
- method = initFunction( uniqueTypeInt, globalObjectDef, "sord8",
+ method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "sord8",
IN_STR_SORD8, IN_STR_SORD8, uniqueTypeStr, true, true );
method->useCallObj = false;
- method = initFunction( uniqueTypeInt, globalObjectDef, "uord16",
+ method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "uord16",
IN_STR_UORD16, IN_STR_UORD16, uniqueTypeStr, true, true );
method->useCallObj = false;
- method = initFunction( uniqueTypeInt, globalObjectDef, "sord16",
+ method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "sord16",
IN_STR_SORD16, IN_STR_SORD16, uniqueTypeStr, true, true );
method->useCallObj = false;
- method = initFunction( uniqueTypeInt, globalObjectDef, "uord32",
+ method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "uord32",
IN_STR_UORD32, IN_STR_UORD32, uniqueTypeStr, true, true );
method->useCallObj = false;
- method = initFunction( uniqueTypeInt, globalObjectDef, "sord32",
+ method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "sord32",
IN_STR_SORD32, IN_STR_SORD32, uniqueTypeStr, true, true );
method->useCallObj = false;
- method = initFunction( uniqueTypeInt, globalObjectDef, "exit",
+ method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "exit",
IN_EXIT, IN_EXIT, uniqueTypeInt, true, true );
- method = initFunction( uniqueTypeInt, globalObjectDef, "exit_hard",
+ method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "exit_hard",
IN_EXIT_HARD, IN_EXIT_HARD, uniqueTypeInt, true, true );
- method = initFunction( uniqueTypeInt, globalObjectDef, "system",
+ method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "system",
IN_SYSTEM, IN_SYSTEM, uniqueTypeStr, true );
addStdin();
@@ -1371,7 +1397,10 @@ void Compiler::makeFuncVisible( Function *func, bool isUserIter )
objMethod->iterDef = uiter;
}
- globalObjectDef->rootScope->methodMap.insert( func->name, objMethod );
+ NameScope *scope = !isUserIter ? func->nspace->rootScope : globalObjectDef->rootScope;
+
+ if ( !scope->methodMap.insert( func->name, objMethod ) )
+ error(func->typeRef->loc) << "function " << func->name << " redeclared" << endp;
func->objMethod = objMethod;
}
@@ -1395,7 +1424,12 @@ void Compiler::makeInHostVisible( Function *func )
objMethod->useCallObj = false;
objMethod->func = func;
- globalObjectDef->rootScope->methodMap.insert( func->name, objMethod );
+ NameScope *scope = func->nspace->rootScope;
+
+ if ( !scope->methodMap.insert( func->name, objMethod ) ) {
+ error(func->typeRef->loc) << "in-host function " << func->name <<
+ " redeclared" << endp;
+ }
func->objMethod = objMethod;
}
diff --git a/src/loadcolm.cc b/src/loadcolm.cc
index 4bb773d3..9af89016 100644
--- a/src/loadcolm.cc
+++ b/src/loadcolm.cc
@@ -228,7 +228,7 @@ struct LoadColm
IterCall *iterCall = walkIterCall( Statement.iter_call() );
stmt = forScope( Statement.id().loc(), forDecl,
- curScope, typeRef, iterCall, stmtList );
+ curScope(), typeRef, iterCall, stmtList );
popScope();
break;
@@ -448,7 +448,7 @@ struct LoadColm
if ( optLabel.prodName() == opt_label::Id ) {
String id = optLabel.id().data();
varRef = LangVarRef::cons( optLabel.id().loc(),
- curStruct(), curScope, id );
+ curNspace(), curStruct(), curScope(), id );
}
return varRef;
}
@@ -1298,11 +1298,12 @@ struct LoadColm
LangVarRef *walkVarRef( var_ref varRef )
{
+ NamespaceQual *nspaceQual = walkRegionQual( varRef.region_qual() );
qual Qual = varRef.qual();
QualItemVect *qualItemVect = walkQual( Qual );
String id = varRef.id().data();
LangVarRef *langVarRef = LangVarRef::cons( varRef.id().loc(),
- curStruct(), curScope, qualItemVect, id );
+ curNspace(), curStruct(), curScope(), nspaceQual, qualItemVect, id );
return langVarRef;
}
@@ -1891,7 +1892,7 @@ struct LoadColm
LangVarRef *captureVarRef = 0;
if ( captureField != 0 ) {
captureVarRef = LangVarRef::cons( captureField->loc,
- curStruct(), curScope, captureField->name );
+ curNspace(), curStruct(), curScope(), captureField->name );
}
expr = LangExpr::cons( LangTerm::consNew(
@@ -1899,14 +1900,14 @@ struct LoadColm
/* Check for redeclaration. */
if ( captureField != 0 ) {
- if ( curScope->checkRedecl( captureField->name ) != 0 ) {
+ if ( curScope()->checkRedecl( captureField->name ) != 0 ) {
error( captureField->loc ) << "variable " <<
captureField->name << " redeclared" << endp;
}
/* Insert it into the field map. */
captureField->typeRef = typeRef;
- curScope->insertField( captureField->name, captureField );
+ curScope()->insertField( captureField->name, captureField );
}
break;
}
@@ -2040,7 +2041,7 @@ struct LoadColm
case iter_call::Id: {
String tree = Tree.id().data();
LangVarRef *varRef = LangVarRef::cons( Tree.id().loc(),
- curStruct(), curScope, tree );
+ curNspace(), curStruct(), curScope(), tree );
LangTerm *langTerm = LangTerm::cons( Tree.id().loc(),
LangTerm::VarRefType, varRef );
LangExpr *langExpr = LangExpr::cons( langTerm );
diff --git a/src/loadinit.cc b/src/loadinit.cc
index f8454e3a..f14ea174 100644
--- a/src/loadinit.cc
+++ b/src/loadinit.cc
@@ -284,8 +284,9 @@ void LoadInit::consParseStmt( StmtList *stmtList )
QualItemVect *popQual = new QualItemVect;
popQual->append( QualItem( QualItem::Arrow, internal, String( "argv" ) ) );
- LangVarRef *popRef = LangVarRef::cons( internal, 0,
- curLocalFrame->rootScope, popQual, String("pop") );
+ LangVarRef *popRef = LangVarRef::cons( internal, curNspace(), 0,
+ curLocalFrame()->rootScope, NamespaceQual::cons( curNspace() ),
+ popQual, String("pop") );
LangExpr *pop = LangExpr::cons( LangTerm::cons( InputLoc(), popRef, popArgs ) );
TypeRef *typeRef = TypeRef::cons( internal, pd->uniqueTypeStr );
@@ -303,16 +304,14 @@ void LoadInit::consParseStmt( StmtList *stmtList )
LangExpr *modeExpr = LangExpr::cons( LangTerm::cons( internal, modeCons ) );
/* Reference A->value */
- QualItemVect *qual = new QualItemVect;
- LangVarRef *varRef = LangVarRef::cons( internal, 0,
- curLocalFrame->rootScope, qual, String("A") );
+ LangVarRef *varRef = LangVarRef::cons( internal, curNspace(), 0,
+ curLocalFrame()->rootScope, String("A") );
LangExpr *Avalue = LangExpr::cons( LangTerm::cons( internal,
LangTerm::VarRefType, varRef ) );
/* Call open. */
- QualItemVect *openQual = new QualItemVect;
LangVarRef *openRef = LangVarRef::cons( internal,
- 0, curLocalFrame->rootScope, openQual, String("open") );
+ curNspace(), 0, curLocalFrame()->rootScope, String("open") );
CallArgVect *openArgs = new CallArgVect;
openArgs->append( new CallArg(Avalue) );
openArgs->append( new CallArg(modeExpr) );
@@ -339,9 +338,8 @@ void LoadInit::consParseStmt( StmtList *stmtList )
void LoadInit::consExportTree( StmtList *stmtList )
{
- QualItemVect *qual = new QualItemVect;
- LangVarRef *varRef = LangVarRef::cons( internal, 0,
- curLocalFrame->rootScope, qual, String("P") );
+ LangVarRef *varRef = LangVarRef::cons( internal, curNspace(), 0,
+ curLocalFrame()->rootScope, String("P") );
LangExpr *expr = LangExpr::cons( LangTerm::cons( internal,
LangTerm::VarRefType, varRef ) );
@@ -355,9 +353,8 @@ void LoadInit::consExportTree( StmtList *stmtList )
void LoadInit::consExportError( StmtList *stmtList )
{
- QualItemVect *qual = new QualItemVect;
- LangVarRef *varRef = LangVarRef::cons( internal, 0,
- curLocalFrame->rootScope, qual, String("error") );
+ LangVarRef *varRef = LangVarRef::cons( internal, curNspace(), 0,
+ curLocalFrame()->rootScope, String("error") );
LangExpr *expr = LangExpr::cons( LangTerm::cons( internal,
LangTerm::VarRefType, varRef ) );
diff --git a/src/lookup.cc b/src/lookup.cc
index ea4885d2..5a57b66f 100644
--- a/src/lookup.cc
+++ b/src/lookup.cc
@@ -67,6 +67,8 @@ ObjectMethod *NameScope::findMethod( const String &name ) const
MethodMapEl *methodMapEl = methodMap.find( name );
if ( methodMapEl != 0 )
return methodMapEl->value;
+ if ( parentScope != 0 )
+ return parentScope->findMethod( name );
return 0;
}
@@ -131,16 +133,16 @@ bool LangVarRef::isLocalRef() const
return false;
}
-bool LangVarRef::isContextRef() const
+bool LangVarRef::isStructRef() const
{
- if ( context != 0 ) {
+ if ( structDef != 0 ) {
if ( qual->length() > 0 ) {
- if ( context->objectDef->rootScope->findField( qual->data[0].data ) != 0 )
+ if ( structDef->objectDef->rootScope->findField( qual->data[0].data ) != 0 )
return true;
}
- else if ( context->objectDef->rootScope->findField( name ) != 0 )
+ else if ( structDef->objectDef->rootScope->findField( name ) != 0 )
return true;
- else if ( context->objectDef->rootScope->findMethod( name ) != 0 )
+ else if ( structDef->objectDef->rootScope->findMethod( name ) != 0 )
return true;
}
@@ -169,14 +171,36 @@ VarRefLookup LangVarRef::lookupObj( Compiler *pd ) const
NameScope *rootScope;
if ( isLocalRef() )
rootScope = scope;
- else if ( isContextRef() )
- rootScope = context->objectDef->rootScope;
+ else if ( isStructRef() )
+ rootScope = structDef->objectDef->rootScope;
else
rootScope = pd->globalObjectDef->rootScope;
return lookupQualification( pd, rootScope );
}
+VarRefLookup LangVarRef::lookupMethodObj( Compiler *pd ) const
+{
+ NameScope *rootScope;
+
+ if ( qual->length() == 0 && nspaceQual != 0 && nspaceQual->qualNames.length() > 0 ) {
+ Namespace *nspace = pd->rootNamespace->findNamespace( nspaceQual->qualNames[0] );
+ rootScope = nspace->rootScope;
+ }
+ else if ( isLocalRef() )
+ rootScope = scope;
+ else if ( isStructRef() )
+ rootScope = structDef->objectDef->rootScope;
+ else if ( qual->length() == 0 ) {
+ rootScope = nspace != 0 ? nspace->rootScope : pd->rootNamespace->rootScope;
+ }
+ else
+ rootScope = pd->globalObjectDef->rootScope;
+
+ return lookupQualification( pd, rootScope );
+}
+
+
VarRefLookup LangVarRef::lookupField( Compiler *pd ) const
{
/* Lookup the object that the field is in. */
@@ -215,6 +239,33 @@ UniqueType *LangVarRef::lookup( Compiler *pd ) const
VarRefLookup LangVarRef::lookupMethod( Compiler *pd ) const
{
/* Lookup the object that the field is in. */
+ VarRefLookup lookup = lookupMethodObj( pd );
+
+ /* Find the method. */
+ ObjectMethod *method = lookup.inScope->findMethod( name );
+ if ( method == 0 ) {
+ /* Not found as a method, try it as an object on which we will call a
+ * default function. */
+ qual->append( QualItem( QualItem::Dot, loc, name ) );
+
+ /* Lookup the object that the field is in. */
+ VarRefLookup lookup = lookupObj( pd );
+
+ /* Find the method. */
+ method = lookup.inScope->findMethod( "finish" );
+ if ( method == 0 )
+ error(loc) << "cannot find " << name << "(...) in object" << endp;
+ }
+
+ lookup.objMethod = method;
+ lookup.uniqueType = method->returnUT;
+
+ return lookup;
+}
+
+VarRefLookup LangVarRef::lookupIterCall( Compiler *pd ) const
+{
+ /* Lookup the object that the field is in. */
VarRefLookup lookup = lookupObj( pd );
/* Find the method. */
diff --git a/src/parser.cc b/src/parser.cc
index 37ba9893..af00a4a5 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -150,8 +150,8 @@ void BaseParser::init()
pd->rootLocalFrame = ObjectDef::cons( ObjectDef::FrameType,
"local", pd->nextObjectId++ );
- curLocalFrame = pd->rootLocalFrame;
- curScope = pd->rootLocalFrame->rootScope;
+ localFrameTop = pd->rootLocalFrame;
+ scopeTop = pd->rootLocalFrame->rootScope;
/* Declarations of internal types. They must be declared now because we use
@@ -244,6 +244,9 @@ Namespace *BaseParser::createNamespace( const InputLoc &loc, const String &name
nspace = new Namespace( loc, name,
pd->namespaceList.length(), parent );
+ /* Link the new namespace's scope to the parent namespace's scope. */
+ nspace->rootScope->parentScope = parent->rootScope;
+
parent->childNamespaces.append( nspace );
pd->namespaceList.append( nspace );
}
@@ -433,22 +436,22 @@ ObjectDef *BaseParser::blockOpen()
ObjectDef *frame = ObjectDef::cons( ObjectDef::FrameType,
"local", pd->nextObjectId++ );
- curLocalFrame = frame;
- curScope = frame->rootScope;
+ localFrameTop = frame;
+ scopeTop = frame->rootScope;
return frame;
}
void BaseParser::blockClose()
{
- curLocalFrame = pd->rootLocalFrame;
- curScope = pd->rootLocalFrame->rootScope;
+ localFrameTop = pd->rootLocalFrame;
+ scopeTop = pd->rootLocalFrame->rootScope;
}
void BaseParser::functionDef( StmtList *stmtList, ObjectDef *localFrame,
ParameterList *paramList, TypeRef *typeRef, const String &name, bool exprt )
{
CodeBlock *codeBlock = CodeBlock::cons( stmtList, localFrame );
- Function *newFunction = Function::cons( typeRef, name,
+ Function *newFunction = Function::cons( curNspace(), typeRef, name,
paramList, codeBlock, pd->nextFuncId++, false, exprt );
pd->functionList.append( newFunction );
newFunction->inContext = curStruct();
@@ -457,7 +460,7 @@ void BaseParser::functionDef( StmtList *stmtList, ObjectDef *localFrame,
void BaseParser::inHostDef( const String &hostCall, ObjectDef *localFrame,
ParameterList *paramList, TypeRef *typeRef, const String &name, bool exprt )
{
- Function *newFunction = Function::cons( typeRef, name,
+ Function *newFunction = Function::cons( curNspace(), typeRef, name,
paramList, 0, pd->nextHostId++, false, exprt );
newFunction->hostCall = hostCall;
newFunction->localFrame = localFrame;
@@ -470,7 +473,7 @@ void BaseParser::iterDef( StmtList *stmtList, ObjectDef *localFrame,
ParameterList *paramList, const String &name )
{
CodeBlock *codeBlock = CodeBlock::cons( stmtList, localFrame );
- Function *newFunction = Function::cons( 0, name,
+ Function *newFunction = Function::cons( 0, 0, name,
paramList, codeBlock, pd->nextFuncId++, true, false );
pd->functionList.append( newFunction );
}
@@ -496,7 +499,7 @@ LangStmt *BaseParser::globalDef( ObjectField *objField, LangExpr *expr,
if ( expr != 0 ) {
LangVarRef *varRef = LangVarRef::cons( objField->loc,
- structDef, curScope, objField->name );
+ curNspace(), structDef, curScope(), objField->name );
stmt = LangStmt::cons( objField->loc,
assignType, varRef, expr );
@@ -679,7 +682,7 @@ LangExpr *BaseParser::parseCmd( const InputLoc &loc, bool tree, bool stop,
LangVarRef *varRef = 0;
if ( objField != 0 ) {
varRef = LangVarRef::cons( objField->loc,
- curStruct(), curScope, objField->name );
+ curNspace(), curStruct(), curScope(), objField->name );
}
/* The typeref for the parser. */
@@ -698,14 +701,14 @@ LangExpr *BaseParser::parseCmd( const InputLoc &loc, bool tree, bool stop,
/* Check for redeclaration. */
if ( objField != 0 ) {
- if ( curScope->checkRedecl( objField->name ) != 0 ) {
+ if ( curScope()->checkRedecl( objField->name ) != 0 ) {
error( objField->loc ) << "variable " << objField->name <<
" redeclared" << endp;
}
/* Insert it into the field map. */
objField->typeRef = typeRef;
- curScope->insertField( objField->name, objField );
+ curScope()->insertField( objField->name, objField );
}
return expr;
@@ -717,7 +720,7 @@ PatternItemList *BaseParser::consPatternEl( LangVarRef *varRef, PatternItemList
list->head->varRef = varRef;
if ( varRef != 0 ) {
- if ( curScope->checkRedecl( varRef->name ) != 0 ) {
+ if ( curScope()->checkRedecl( varRef->name ) != 0 ) {
error( varRef->loc ) << "variable " << varRef->name <<
" redeclared" << endp;
}
@@ -727,7 +730,7 @@ PatternItemList *BaseParser::consPatternEl( LangVarRef *varRef, PatternItemList
ObjectField::UserLocalType, typeRef, varRef->name );
/* Insert it into the field map. */
- curScope->insertField( varRef->name, objField );
+ curScope()->insertField( varRef->name, objField );
}
return list;
@@ -782,7 +785,7 @@ LangStmt *BaseParser::forScope( const InputLoc &loc, const String &data,
NameScope *scope, TypeRef *typeRef, IterCall *iterCall, StmtList *stmtList )
{
/* Check for redeclaration. */
- if ( curScope->checkRedecl( data ) != 0 )
+ if ( curScope()->checkRedecl( data ) != 0 )
error( loc ) << "variable " << data << " redeclared" << endp;
/* Note that we pass in a null type reference. This type is dependent on
@@ -790,7 +793,7 @@ LangStmt *BaseParser::forScope( const InputLoc &loc, const String &data,
* the iterator that is called. This lookup is done at compile time. */
ObjectField *iterField = ObjectField::cons( loc,
ObjectField::UserLocalType, (TypeRef*)0, data );
- curScope->insertField( data, iterField );
+ curScope()->insertField( data, iterField );
LangStmt *stmt = LangStmt::cons( loc, LangStmt::ForIterType,
iterField, typeRef, iterCall, stmtList, curStruct(), scope );
@@ -882,7 +885,7 @@ LangExpr *BaseParser::construct( const InputLoc &loc, ObjectField *objField,
LangVarRef *varRef = 0;
if ( objField != 0 ) {
varRef = LangVarRef::cons( objField->loc,
- curStruct(), curScope, objField->name );
+ curNspace(), curStruct(), curScope(), objField->name );
}
LangExpr *expr = LangExpr::cons( LangTerm::cons( loc, LangTerm::ConstructType,
@@ -890,14 +893,14 @@ LangExpr *BaseParser::construct( const InputLoc &loc, ObjectField *objField,
/* Check for redeclaration. */
if ( objField != 0 ) {
- if ( curScope->checkRedecl( objField->name ) != 0 ) {
+ if ( curScope()->checkRedecl( objField->name ) != 0 ) {
error( objField->loc ) << "variable " << objField->name <<
" redeclared" << endp;
}
/* Insert it into the field map. */
objField->typeRef = typeRef;
- curScope->insertField( objField->name, objField );
+ curScope()->insertField( objField->name, objField );
}
return expr;
@@ -922,19 +925,19 @@ LangStmt *BaseParser::varDef( ObjectField *objField,
LangStmt *stmt = 0;
/* Check for redeclaration. */
- if ( curScope->checkRedecl( objField->name ) != 0 ) {
+ if ( curScope()->checkRedecl( objField->name ) != 0 ) {
error( objField->loc ) << "variable " << objField->name <<
" redeclared" << endp;
}
/* Insert it into the field map. */
- curScope->insertField( objField->name, objField );
+ curScope()->insertField( objField->name, objField );
//cout << "var def " << $1->objField->name << endl;
if ( expr != 0 ) {
LangVarRef *varRef = LangVarRef::cons( objField->loc,
- curStruct(), curScope, objField->name );
+ curNspace(), curStruct(), curScope(), objField->name );
stmt = LangStmt::cons( objField->loc, assignType, varRef, expr );
}
@@ -960,7 +963,7 @@ LangStmt *BaseParser::exportStmt( ObjectField *objField,
if ( expr != 0 ) {
LangVarRef *varRef = LangVarRef::cons( objField->loc,
- 0, curScope, objField->name );
+ curNspace(), 0, curScope(), objField->name );
stmt = LangStmt::cons( objField->loc, assignType, varRef, expr );
}
@@ -1066,10 +1069,10 @@ void BaseParser::precedenceStmt( PredType predType, PredDeclList *predDeclList )
void BaseParser::pushScope()
{
- curScope = curLocalFrame->pushScope( curScope );
+ scopeTop = curLocalFrame()->pushScope( curScope() );
}
void BaseParser::popScope()
{
- curScope = curScope->parentScope;
+ scopeTop = curScope()->parentScope;
}
diff --git a/src/parser.h b/src/parser.h
index 8843aad6..baa08f61 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -42,8 +42,8 @@ struct BaseParser
RegionSetVect regionStack;
NamespaceVect namespaceStack;
StructStack structStack;
- ObjectDef *curLocalFrame;
- NameScope *curScope;
+ ObjectDef *localFrameTop;
+ NameScope *scopeTop;
bool enterRl;
@@ -55,6 +55,12 @@ struct BaseParser
Namespace *curNspace()
{ return namespaceStack.top(); }
+
+ NameScope *curScope()
+ { return scopeTop; }
+
+ ObjectDef *curLocalFrame()
+ { return localFrameTop; }
/* Lexical feedback. */
diff --git a/src/parsetree.h b/src/parsetree.h
index d028b3f7..d6cc246f 100644
--- a/src/parsetree.h
+++ b/src/parsetree.h
@@ -811,13 +811,64 @@ struct TypeAlias
typedef DList<TypeAlias> TypeAliasList;
+typedef AvlMap<String, ObjectField*, CmpStr> FieldMap;
+typedef AvlMapEl<String, ObjectField*> FieldMapEl;
+
+typedef AvlMap<String, ObjectMethod*, CmpStr> MethodMap;
+typedef AvlMapEl<String, ObjectMethod*> MethodMapEl;
+
+/* tree_t of name scopes for an object def. All of the object fields inside this
+ * tree live in one object def. This is used for scoping names in functions. */
+struct NameScope
+{
+ NameScope()
+ :
+ owner(0),
+ parentScope(0),
+ childIter(0)
+ {}
+
+ ObjectDef *owner;
+ FieldMap fieldMap;
+ MethodMap methodMap;
+
+ NameScope *parentScope;
+ DList<NameScope> children;
+
+ /* For iteration after declaration. */
+ NameScope *childIter;
+
+ NameScope *prev, *next;
+
+ int depth()
+ {
+ int depth = 0;
+ NameScope *scope = this;
+ while ( scope != 0 ) {
+ depth += 1;
+ scope = scope->parentScope;
+ }
+ return depth;
+ }
+
+ ObjectField *findField( const String &name ) const;
+ ObjectMethod *findMethod( const String &name ) const;
+
+ ObjectField *checkRedecl( const String &name );
+ void insertField( const String &name, ObjectField *value );
+};
+
+
struct Namespace
{
/* Construct with a list of joins */
Namespace( const InputLoc &loc, const String &name, int id,
Namespace *parentNamespace ) :
loc(loc), name(name), id(id),
- parentNamespace(parentNamespace) { }
+ parentNamespace(parentNamespace)
+ {
+ rootScope = new NameScope;
+ }
/* tree_t traversal. */
Namespace *findNamespace( const String &name );
@@ -850,6 +901,8 @@ struct Namespace
Namespace *parentNamespace;
NamespaceVect childNamespaces;
+ NameScope *rootScope;
+
Namespace *next, *prev;
void declare( Compiler *pd );
@@ -2462,59 +2515,11 @@ struct ObjectField
ObjectField *prev, *next;
};
-typedef AvlMap<String, ObjectField*, CmpStr> FieldMap;
-typedef AvlMapEl<String, ObjectField*> FieldMapEl;
-
typedef DListVal<ObjectField*> FieldList;
typedef DList<ObjectField> ParameterList;
-typedef AvlMap<String, ObjectMethod*, CmpStr> MethodMap;
-typedef AvlMapEl<String, ObjectMethod*> MethodMapEl;
-
-
-/* tree_t of name scopes for an object def. All of the object fields inside this
- * tree live in one object def. This is used for scoping names in functions. */
-struct NameScope
-{
- NameScope()
- :
- owner(0),
- parentScope(0),
- childIter(0)
- {}
-
- ObjectDef *owner;
- FieldMap fieldMap;
- MethodMap methodMap;
-
- NameScope *parentScope;
- DList<NameScope> children;
-
- /* For iteration after declaration. */
- NameScope *childIter;
-
- NameScope *prev, *next;
-
- int depth()
- {
- int depth = 0;
- NameScope *scope = this;
- while ( scope != 0 ) {
- depth += 1;
- scope = scope->parentScope;
- }
- return depth;
- }
-
- ObjectField *findField( const String &name ) const;
- ObjectMethod *findMethod( const String &name ) const;
-
- ObjectField *checkRedecl( const String &name );
- void insertField( const String &name, ObjectField *value );
-};
-
struct ObjectDef
{
enum Type {
@@ -2647,22 +2652,27 @@ typedef Vector<QualItem> QualItemVect;
struct LangVarRef
{
- static LangVarRef *cons( const InputLoc &loc, StructDef *context,
- NameScope *scope, QualItemVect *qual, const String &name )
+ static LangVarRef *cons( const InputLoc &loc, Namespace *nspace,
+ StructDef *structDef, NameScope *scope,
+ NamespaceQual *nspaceQual, QualItemVect *qual,
+ const String &name )
{
LangVarRef *l = new LangVarRef;
l->loc = loc;
- l->context = context;
+ l->nspace = nspace;
+ l->structDef = structDef;
l->scope = scope;
+ l->nspaceQual = nspaceQual;
l->qual = qual;
l->name = name;
return l;
}
- static LangVarRef *cons( const InputLoc &loc, StructDef *context,
- NameScope *scope, const String &name )
+ static LangVarRef *cons( const InputLoc &loc, Namespace *nspace,
+ StructDef *structDef, NameScope *scope, const String &name )
{
- return cons( loc, context, scope, new QualItemVect, name );
+ return cons( loc, nspace, structDef, scope,
+ NamespaceQual::cons( nspace ), new QualItemVect, name );
}
void resolve( Compiler *pd ) const;
@@ -2671,15 +2681,17 @@ struct LangVarRef
UniqueType *loadField( Compiler *pd, CodeVect &code, ObjectDef *inObject,
ObjectField *el, bool forWriting, bool revert ) const;
+ VarRefLookup lookupIterCall( Compiler *pd ) const;
VarRefLookup lookupMethod( Compiler *pd ) const;
VarRefLookup lookupField( Compiler *pd ) const;
VarRefLookup lookupQualification( Compiler *pd, NameScope *rootScope ) const;
VarRefLookup lookupObj( Compiler *pd ) const;
+ VarRefLookup lookupMethodObj( Compiler *pd ) const;
bool isInbuiltObject() const;
bool isLocalRef() const;
- bool isContextRef() const;
+ bool isStructRef() const;
void loadQualification( Compiler *pd, CodeVect &code, NameScope *rootScope,
int lastPtrInQual, bool forWriting, bool revert ) const;
void loadInbuiltObject( Compiler *pd, CodeVect &code,
@@ -2721,9 +2733,12 @@ struct LangVarRef
void popRefQuals( Compiler *pd, CodeVect &code,
VarRefLookup &lookup, CallArgVect *args, bool temps ) const;
+
InputLoc loc;
- StructDef *context;
+ Namespace *nspace;
+ StructDef *structDef;
NameScope *scope;
+ NamespaceQual *nspaceQual;
QualItemVect *qual;
String name;
long argSize;
@@ -3350,6 +3365,7 @@ struct Function
{
Function()
:
+ nspace(0),
paramListSize(0),
paramUTs(0),
inContext(0),
@@ -3357,12 +3373,13 @@ struct Function
inHost(false)
{}
- static Function *cons( TypeRef *typeRef, const String &name,
+ static Function *cons( Namespace *nspace, TypeRef *typeRef, const String &name,
ParameterList *paramList, CodeBlock *codeBlock,
int funcId, bool isUserIter, bool exprt )
{
Function *f = new Function;
+ f->nspace = nspace;
f->typeRef = typeRef;
f->name = name;
f->paramList = paramList;
@@ -3374,6 +3391,7 @@ struct Function
return f;
}
+ Namespace *nspace;
TransBlock *transBlock;
TypeRef *typeRef;
String name;
diff --git a/src/resolve.cc b/src/resolve.cc
index 96742435..95221bcb 100644
--- a/src/resolve.cc
+++ b/src/resolve.cc
@@ -377,7 +377,7 @@ UniqueType *TypeRef::resolveIterator( Compiler *pd )
UniqueType *searchUT = searchTypeRef->resolveType( pd );
/* Lookup the iterator call. Make sure it is an iterator. */
- VarRefLookup lookup = iterCall->langTerm->varRef->lookupMethod( pd );
+ VarRefLookup lookup = iterCall->langTerm->varRef->lookupIterCall( pd );
if ( lookup.objMethod->iterDef == 0 ) {
error(loc) << "attempt to iterate using something "
"that is not an iterator" << endp;
diff --git a/src/synthesis.cc b/src/synthesis.cc
index 151c941c..35877de5 100644
--- a/src/synthesis.cc
+++ b/src/synthesis.cc
@@ -564,7 +564,7 @@ void LangVarRef::loadContextObj( Compiler *pd, CodeVect &code,
int lastPtrInQual, bool forWriting ) const
{
/* Start the search in the global object. */
- ObjectDef *rootObj = context->objectDef;
+ ObjectDef *rootObj = structDef->objectDef;
if ( forWriting && lastPtrInQual < 0 ) {
/* If we are writing an no reference was found in the qualification
@@ -627,7 +627,7 @@ void LangVarRef::loadObj( Compiler *pd, CodeVect &code,
loadInbuiltObject( pd, code, lastPtrInQual, forWriting );
else if ( isLocalRef() )
loadLocalObj( pd, code, lastPtrInQual, forWriting );
- else if ( isContextRef() )
+ else if ( isStructRef() )
loadContextObj( pd, code, lastPtrInQual, forWriting );
else
loadGlobalObj( pd, code, lastPtrInQual, forWriting );
@@ -2278,7 +2278,7 @@ void LangStmt::compileForIter( Compiler *pd, CodeVect &code ) const
UniqueType *searchUT = typeRef->uniqueType;
/* Lookup the iterator call. Make sure it is an iterator. */
- VarRefLookup lookup = iterCall->langTerm->varRef->lookupMethod( pd );
+ VarRefLookup lookup = iterCall->langTerm->varRef->lookupIterCall( pd );
if ( lookup.objMethod->iterDef == 0 ) {
error(loc) << "attempt to iterate using something "
"that is not an iterator" << endp;
diff --git a/test/binary1.lm b/test/binary1.lm
index e2cb4a09..93392d00 100644
--- a/test/binary1.lm
+++ b/test/binary1.lm
@@ -508,7 +508,7 @@ int push( L: list<int>, Int: int )
}
parse S: binary::start(Binary) [ stdin ]
-print_all_names( S )
+binary::print_all_names( S )
print( '*** SUCCESS ***\n' )
##### EXP #####
www.google.ca.
diff --git a/test/exit6.lm b/test/exit6.lm
index 5e20118a..3595d93e 100644
--- a/test/exit6.lm
+++ b/test/exit6.lm
@@ -830,10 +830,9 @@ for OutputLine: output_line in RagelTree {
}
send Output "*/
-iter i()
-{
-
-}
+# iter i()
+#{
+#}
for I: any in i() {
Int: int = 1
diff --git a/test/generate2.lm b/test/generate2.lm
index 7a2e0f71..06dfa2af 100644
--- a/test/generate2.lm
+++ b/test/generate2.lm
@@ -201,7 +201,7 @@ end # generate
Generate: generate = new generate()
Generate->OpenStack = new list<generate::open_item>()
-Sentinal: generate::open_item = new_open_item( '** SENTINAL **', 1 )
+Sentinal: generate::open_item = generate::new_open_item( '** SENTINAL **', 1 )
Generate->OpenStack->push( Sentinal )
parse S: generate::start(Generate)[stdin]
diff --git a/test/inpush1.lm b/test/inpush1.lm
index 07d89f51..2fcf6e38 100644
--- a/test/inpush1.lm
+++ b/test/inpush1.lm
@@ -55,7 +55,7 @@ namespace lang
parse_stop H: hash::hash[ input ]
if ( H ) {
if ( H.Inc ) {
- FN: str = unquote( H.Inc )
+ FN: str = string::unquote( H.Inc )
print[ 'opening ' FN '\n' ]
IS: stream = open( FN, 'r' )
if ( ! IS ) {
diff --git a/test/lookup1.lm b/test/lookup1.lm
index 069ea894..0c4cbbcf 100644
--- a/test/lookup1.lm
+++ b/test/lookup1.lm
@@ -2212,7 +2212,7 @@ Lookup->declaratorData = new lookup::list_declarator_data()
Lookup->templDecl = new lookup::list_int()
# Root namespace object
-Lookup->rootNamespace = createLangObject( Lookup->NamespaceType, '<root_namespace>', nil )
+Lookup->rootNamespace = lookup::createLangObject( Lookup->NamespaceType, '<root_namespace>', nil )
# Initialize the namespace and declaration stacks with the root namespace
Lookup->curNamespace->push_tail( Lookup->rootNamespace )
@@ -2237,7 +2237,7 @@ if ! S {
}
print( '***** NAMSPACES *****\n' )
-printObject( '', Lookup->rootNamespace )
+lookup::printObject( '', Lookup->rootNamespace )
print( '***** UNKNOWN DECLARATORS *****\n' )
for DI: lookup::declarator_id in S {
if match DI
diff --git a/test/tags3.lm b/test/tags3.lm
index de83ea58..70f44335 100644
--- a/test/tags3.lm
+++ b/test/tags3.lm
@@ -302,9 +302,9 @@ Tags->TagStack = construct tags::tag_stack []
parse HTML_P: tags::start(Tags)[ stdin ]
HTML: tags::start = HTML_P
-flatten( HTML )
+tags::flatten( HTML )
print_xml( HTML )
-printLinks( HTML )
+tags::printLinks( HTML )
##### IN #####
<t1>