shithub: mc

Download patch

ref: 96aa84cdbe397910f532f8c802c8de9825e49c59
parent: d0ffb958c7247028223c7e53253249d52a47a324
author: andrewc <andrewchamberss@gmail.com>
date: Fri Oct 28 12:48:15 EDT 2016

merge consecutive string literals

--- a/doc/lang.txt
+++ b/doc/lang.txt
@@ -192,6 +192,13 @@
 
             eg: "foo\"bar"
 
+        Multiple consecutive string literals are implicitly merged to create
+        a single combined string literal. To allow a string literal to span
+        across multiple lines, the new line characters must be be escaped.
+        
+            eg: "foo" \
+                "bar"
+
         Character literals represent a single codepoint in the character
         set. A character starts with a single quote, contains a single
         codepoint worth of text, encoded either as an escape sequence
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -141,7 +141,7 @@
 %type <trait> traitdef
 
 %type <node> exprln retexpr goto continue break expr atomicexpr
-%type <node> littok literal asnexpr lorexpr landexpr borexpr
+%type <node> littok literal asnexpr lorexpr landexpr borexpr strlit
 %type <node> bandexpr cmpexpr unionexpr addexpr mulexpr shiftexpr prefixexpr postfixexpr
 %type <node> funclit seqlit tuplit name block stmt label use
 %type <node> fnparam declbody declcore typedeclcore structent arrayelt structelt tuphead
@@ -780,7 +780,7 @@
 tuplit  : Toparen tupbody Tcparen
 	{$$ = mkexprl($1->loc, Otup, $2.nl, $2.nn);}
 
-littok  : Tstrlit       {$$ = mkstr($1->loc, $1->strval);}
+littok  : strlit	{$$ = $1;}
 	| Tchrlit       {$$ = mkchar($1->loc, $1->chrval);}
 	| Tfloatlit     {$$ = mkfloat($1->loc, $1->fltval);}
 	| Tboollit      {$$ = mkbool($1->loc, !strcmp($1->id, "true"));}
@@ -789,6 +789,18 @@
 		$$ = mkint($1->loc, $1->intval);
 		if ($1->inttype)
 			$$->lit.type = mktype($1->loc, $1->inttype);
+	}
+	;
+
+strlit : Tstrlit { $$ = mkstr($1->loc, $1->strval); }
+	| strlit Tstrlit {
+		Str merged;
+		
+		merged.len = $1->lit.strval.len + $2->strval.len;
+		merged.buf = malloc(merged.len);
+		memcpy(merged.buf, $1->lit.strval.buf, $1->lit.strval.len);
+		memcpy(merged.buf + $1->lit.strval.len, $2->strval.buf, $2->strval.len);
+		$$ = mkstr($1->loc, merged);
 	}
 	;
 
--- /dev/null
+++ b/test/multistr.myr
@@ -1,0 +1,13 @@
+use std
+
+const main = {
+	var multi
+
+	multi = "abc" "def" \
+	"ghi"
+	
+	match multi
+	| "abcdefghi":
+	| fail: std.fatal("failed: {}\n", fail)
+	;;
+}
--- a/test/tests
+++ b/test/tests
@@ -81,6 +81,7 @@
 B log-and	E	0
 B log-or	E	1
 B str		E	102
+B multistr		E	0
 B generic	E	42
 B genericval	E	42
 B trait-builtin	E	42