summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@colm.net>2019-12-28 15:32:53 +0200
committerAdrian Thurston <thurston@colm.net>2019-12-28 15:32:53 +0200
commita1028d7f79c71a1e52ae11071b69adaec593cbdb (patch)
tree684fd7114a7bd67df1140c15a0accbfbe66bc624
parentf2bbad18a77fc52ba64d6bf4a14338fec8061d1f (diff)
downloadcolm-literal-concatenation.tar.gz
colm: testing a new grammar where string concatenations are allowedliteral-concatenation
This commit brings back string concatenations in match/cons/string literals at the top level. It does not bring back concatenation of [] lists. For example, you can write: match Foo "hi "there BUT NOT: match Foo [Hi] [There] The concatenation (of both forms) was removed when bare sends were added, due to the ambiguity created. However, removing these concatenations has proven quite annoying. This change re-introduces the ambiguity, which maybe we should do something about by detecting when it is likely via mis-alignments of the strings, or making some other change to sends. refs #95
-rw-r--r--colm/colm.lm21
-rw-r--r--colm/loadfinal.cc64
2 files changed, 51 insertions, 34 deletions
diff --git a/colm/colm.lm b/colm/colm.lm
index 9052f325..c95d0c41 100644
--- a/colm/colm.lm
+++ b/colm/colm.lm
@@ -736,13 +736,14 @@ def pattern_top_el
[DQ LitpatElList: litpat_el<* dq_lit_term] :Dq
| [SQ SqConsDataList: sq_cons_data<* sq_lit_term] :Sq
| [TILDE opt_tilde_data TILDE_NL] :Tilde
-| [SQOPEN PatternElList: pattern_el<* SQCLOSE] :SubList
def pattern_list
- [pattern_top_el] :Base
+ [pattern_top_el pattern_list] :List
+| [pattern_top_el] :Base
def pattern
- [pattern_list]
+ [pattern_list] :TopList
+| [SQOPEN PatternElList: pattern_el<* SQCLOSE] :SubList
#
# Constructor List
@@ -768,13 +769,14 @@ def cons_top_el
[DQ LitConsElList: lit_cons_el<* dq_lit_term] :Dq
| [SQ SqConsDataList: sq_cons_data<* sq_lit_term] :Sq
| [TILDE opt_tilde_data TILDE_NL] :Tilde
-| [SQOPEN ConsElList: cons_el<* SQCLOSE] :SubList
def cons_list
- [cons_top_el] :Base
+ [cons_top_el cons_list] :List
+| [cons_top_el] :Base
def constructor
- [cons_list]
+ [cons_list] :TopList
+| [SQOPEN ConsElList: cons_el<* SQCLOSE] :SubList
#
# Accumulate
@@ -821,13 +823,14 @@ def string_top_el
[DQ LitStringElList: lit_string_el<* dq_lit_term] :Dq
| [SQ SqConsDataList: sq_cons_data<* sq_lit_term] :Sq
| [TILDE opt_tilde_data TILDE_NL] :Tilde
-| [SQOPEN StringElList: string_el<* SQCLOSE] :SubList
def string_list
- [string_top_el] :Base
+ [string_top_el string_list] :List
+| [string_top_el] :Base
def string
- [string_list]
+ [string_list] :TopList
+| [SQOPEN StringElList: string_el<* SQCLOSE] :SubList
#
# Variable References
diff --git a/colm/loadfinal.cc b/colm/loadfinal.cc
index 4162140d..29f5205b 100644
--- a/colm/loadfinal.cc
+++ b/colm/loadfinal.cc
@@ -645,28 +645,29 @@ struct LoadColm
patternTopEl.opt_tilde_data().loc(), patternData );
list = PatternItemList::cons( patternItem );
break;
- }
- case pattern_top_el::SubList: {
- list = walkPatternElList( patternTopEl.PatternElList(), patternVarRef );
- break;
}}
return list;
}
PatternItemList *walkPatternList( pattern_list patternList, LangVarRef *patternVarRef )
{
- PatternItemList *list = 0;
- switch ( patternList.prodName() ) {
- case pattern_list::Base: {
- list = walkPattternTopEl( patternList.pattern_top_el(), patternVarRef );
- break;
- }}
- return list;
+ PatternItemList *ret = new PatternItemList;
+ RepeatIter<pattern_top_el> patternTopElIter ( patternList );
+ while ( !patternTopElIter.end() ) {
+ PatternItemList *list = walkPattternTopEl( patternTopElIter.value(), patternVarRef );
+ ret->append( *list );
+ delete list;
+ patternTopElIter.next();
+ }
+ return ret;
}
PatternItemList *walkPattern( pattern Pattern, LangVarRef *patternVarRef )
{
- return walkPatternList( Pattern.pattern_list(), patternVarRef );
+ if ( Pattern.prodName() == pattern::TopList )
+ return walkPatternList( Pattern.pattern_list(), patternVarRef );
+ else
+ return walkPatternElList( Pattern.PatternElList(), patternVarRef );
}
LangExpr *walkOptDefInit( opt_def_init optDefInit )
@@ -1560,22 +1561,29 @@ struct LoadColm
ConsItem::InputText, consData );
list = ConsItemList::cons( consItem );
break;
- }
- case cons_top_el::SubList: {
- list = walkConsElList( consTopEl.ConsElList(), consTypeRef );
- break;
}}
return list;
}
ConsItemList *walkConsList( cons_list consList, TypeRef *consTypeRef )
{
- return walkConsTopEl( consList.cons_top_el(), consTypeRef );
+ ConsItemList *ret = new ConsItemList;
+ RepeatIter<cons_top_el> consTopElIter ( consList );
+ while ( !consTopElIter.end() ) {
+ ConsItemList *list = walkConsTopEl( consTopElIter.value(), consTypeRef );
+ ret->append( *list );
+ delete list;
+ consTopElIter.next();
+ }
+ return ret;
}
ConsItemList *walkConstructor( constructor Constructor, TypeRef *consTypeRef )
{
- return walkConsList( Constructor.cons_list(), consTypeRef );
+ if ( Constructor.prodName() == constructor::TopList )
+ return walkConsList( Constructor.cons_list(), consTypeRef );
+ else
+ return walkConsElList( Constructor.ConsElList(), consTypeRef );
}
/*
@@ -1691,23 +1699,29 @@ struct LoadColm
ConsItem::InputText, consData );
list = ConsItemList::cons( consItem );
break;
- }
- case string_top_el::SubList: {
- list = walkStringElList( stringTopEl.StringElList() );
- break;
}}
return list;
}
ConsItemList *walkStringList( string_list stringList )
{
- return walkStringTopEl( stringList.string_top_el() );
+ ConsItemList *ret = new ConsItemList;
+ RepeatIter<string_top_el> stringTopElIter( stringList );
+ while ( !stringTopElIter.end() ) {
+ ConsItemList *list = walkStringTopEl( stringTopElIter.value() );
+ ret->append( *list );
+ delete list;
+ stringTopElIter.next();
+ }
+ return ret;
}
ConsItemList *walkString( string String )
{
- ConsItemList *list = walkStringList( String.string_list() );
- return list;
+ if ( String.prodName() == string::TopList )
+ return walkStringList( String.string_list() );
+ else
+ return walkStringElList( String.StringElList() );
}
/*