M array.c => array.c +8 -5
@@ 62,6 62,12 @@ setint(Array *a, usize offset, vlong v)
}
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 @@ printarraysub(char *buf, Array *a, int depth)
{
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 @@ printarraysub(char *buf, Array *a, int depth)
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 */
M dat.h => dat.h +2 -0
@@ 119,6 119,7 @@ enum TokenTag
TokDel,
TokLarrow,
TokSemi,
+ TokString,
TokEnd,
};
@@ 131,6 132,7 @@ struct Token
union {
vlong num; /* TokNumber */
char *name; /* TokName: UTF-8 encoded name */
+ Rune *string; /* TokString: string contents */
int prim; /* TokPrimitive */
};
};
M fns.h => fns.h +1 -0
@@ 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 *);
M parse.c => parse.c +19 -5
@@ 414,11 414,25 @@ parseconst(TokenList *t)
{
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;
}
M scan.c => scan.c +18 -0
@@ 77,6 77,24 @@ scan(char *buf)
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;