shithub: lpa

Download patch

ref: 6bc6badcb6768cd559431f139d13c7b9e5ef16ed
parent: 5af5764e62f81ec4057e99a3bd03902b723cd7b8
author: Peter Mikkelsen <peter@pmikkelsen.com>
date: Sat Jul 27 07:38:28 EDT 2024

Character arrays

--- a/array.c
+++ b/array.c
@@ -62,6 +62,12 @@
 }
 
 void
+setchar(Array *a, usize offset, Rune v)
+{
+	a->chardata[offset] = v;
+}
+
+void
 setarray(Array *a, usize offset, Array *v)
 {
 	a->arraydata[offset] = v;
@@ -103,10 +109,7 @@
 {
 	char *p = buf;
 
-	if(a->rank == 0){
-		p += printitem(p, a, 0, depth);
-		goto end;
-	}else if(a->rank == 1 && a->type == TypeNumber){
+	if(a->rank <= 1 && a->type == TypeNumber){
 		if(a->size == 0)
 			p += sprint(p, "⍬");
 		for(uvlong i = 0; i < a->size; i++){
@@ -115,7 +118,7 @@
 			p += printitem(p, a, i, depth);
 		}
 		goto end;
-	}else if(a->rank == 1 && a->type == TypeChar){
+	}else if(a->rank <= 1 && a->type == TypeChar){
 		p += sprint(p, "'");
 		for(uvlong i = 0; i < a->size; i++)
 			p += printitem(p, a, i, depth); /* TODO: quoting */
--- a/dat.h
+++ b/dat.h
@@ -119,6 +119,7 @@
 	TokDel,
 	TokLarrow,
 	TokSemi,
+	TokString,
 
 	TokEnd,
 };
@@ -131,6 +132,7 @@
 	union {
 		vlong num; /* TokNumber */
 		char *name; /* TokName: UTF-8 encoded name */
+		Rune *string; /* TokString: string contents */
 		int prim; /* TokPrimitive */
 	};
 };
--- a/fns.h
+++ b/fns.h
@@ -2,6 +2,7 @@
 void initarrays(void);
 Array *allocarray(int, int, usize);
 void setint(Array *, usize, vlong);
+void setchar(Array *, usize, Rune);
 void setarray(Array *, usize, Array *);
 void setshape(Array *, int, usize);
 Array *simplifyarray(Array *);
--- a/parse.c
+++ b/parse.c
@@ -414,11 +414,25 @@
 {
 	Ast *val = alloc(DataAst);
 	val->tag = AstConst;
+	vlong num, len;
+	Rune *str;
 
-	vlong num = t->tokens[t->offset].num;
-	match(t, TokNumber);
-	val->val = allocarray(TypeNumber, 0, 1);
-	setint(val->val, 0, num);
-
+	switch(peek(t)){
+	case TokNumber:
+		num = t->tokens[t->offset].num;
+		val->val = allocarray(TypeNumber, 0, 1);
+		setint(val->val, 0, num);
+		break;
+	case TokString:
+		str = t->tokens[t->offset].string;
+		len = runestrlen(str);
+		val->val = allocarray(TypeChar, len != 1, len);
+		for(uvlong i = 0; i < len; i++)
+			setchar(val->val, i, str[i]);
+		break;
+	default:
+		match(t, TokNumber); /* TODO: syntax error could be better here */
+	}
+	match(t, peek(t));
 	return val;
 }
--- a/scan.c
+++ b/scan.c
@@ -77,6 +77,24 @@
 			tok->name[size] = 0;
 			continue;
 		}
+		if(r == '\''){
+			cp += n;
+			n = chartorune(&r, cp);
+
+			char *start = cp;
+			while(!(r == '\'' || r == 0)){
+				cp += n;
+				n = chartorune(&r, cp);
+			}
+			if(r == 0)
+				error(ESyntax, "unmatched '");
+
+			tok = newtok(tokens, TokString);
+			usize size = utfnlen(start, cp - start) + 1;
+			tok->string = malloc(sizeof(Rune) * size);
+			runesnprint(tok->string, size, "%s", start);
+			goto next;
+		}
 		error(ESyntax, "unexpected: '%C'", r);
 next:
 		cp += n;