summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apl9.h1
-rw-r--r--array.c6
-rw-r--r--functions.c25
-rw-r--r--memory.c12
-rw-r--r--tests/queens.apl2
5 files changed, 34 insertions, 12 deletions
diff --git a/apl9.h b/apl9.h
index 1208cac..bbba10f 100644
--- a/apl9.h
+++ b/apl9.h
@@ -104,6 +104,7 @@ struct Array
Rune *runedata;
Mixed *mixeddata;
Array **arraydata;
+ Array *prototype; /* only in use when size == 0 and type == AtypeArray */
};
u64int info;
/* info is a bitmap of information, divided as follows:
diff --git a/array.c b/array.c
index f97ac5c..a46668b 100644
--- a/array.c
+++ b/array.c
@@ -191,7 +191,7 @@ arrayitem(Array *a, int index)
case AtypeFloat: res = mkscalarfloat(a->mixeddata[index].f); break;
case AtypeRune: res = mkscalarrune(a->mixeddata[index].r); break;
default:
- throwerror(L"Unhandled case in arrayitem", ENotImplemented);
+ throwerror(L"Unhandled case in arrayitem 1", ENotImplemented);
}
break;
case AtypeArray:
@@ -199,7 +199,7 @@ arrayitem(Array *a, int index)
incarrayref(res);
break;
default:
- throwerror(L"Unhandled case in arrayitem", ENotImplemented);
+ throwerror(L"Unhandled case in arrayitem 2", ENotImplemented);
}
return res;
}
@@ -351,6 +351,8 @@ fillelement(Array *a)
return fill;
}
case AtypeArray:{
+ if(GetSize(a) == 0)
+ return fnSame(a->prototype);
Array *b = duparrayshape(a, GetType(a));
for(int i = 0; i < GetSize(b); i++){
Array *fill = fillelement(a->arraydata[i]);
diff --git a/functions.c b/functions.c
index 9eb444e..b2e4d9f 100644
--- a/functions.c
+++ b/functions.c
@@ -577,8 +577,11 @@ fnMix(Array *right)
Array *
fnSplit(Array *right)
{
- Rune *code = L"0≡≢⍴⍵: ⍵ ⋄ 1≡≢⍴⍵: ⊂⍵ ⋄ (⊂⍵)⌷⍨¨⍳≢⍵";
- return rundfn(code, nil, nil, nil, right);
+ Rune *code = L"0≡≢⍴⍵: ⍵ ⋄ 1≡≢⍴⍵: ⊂⍵ ⋄ (⊂⍵)⌷⍨¨⍳¯1↓⍴⍵";
+ Array *result = rundfn(code, nil, nil, nil, right);
+ if(GetSize(result) == 0)
+ result->prototype = rundfn(L"⊂(⊃⌽⍴⍵)↑⎕proto ⍵", nil, nil, nil, right);
+ return result;
}
Array *
@@ -597,9 +600,12 @@ fnEnclose(Array *right)
Array *
fnDisclose(Array *right)
{
- if(GetSize(right) == 0)
- return fillelement(right);
- else
+ if(GetSize(right) == 0){
+ Array *fill = fillelement(right);
+ Array *res = fnDisclose(fill);
+ freearray(fill);
+ return res;
+ }else
return arrayitem(right, 0);
}
@@ -1321,6 +1327,9 @@ fnTake(Array *left, Array *right)
for(i = 0; i < GetRank(right); i++)
result->shape[i] = shape[i];
+ if(size == 0)
+ result->prototype = fnSame(fill);
+
int *index = emallocz(sizeof(int) * GetSize(left), 1);
int fromindex;
for(i = 0; i < size; i++){
@@ -1778,6 +1787,9 @@ fnCatenateFirst(Array *left, Array *right)
freearray(leftarr);
freearray(rightarr);
+
+ if(GetSize(result) == 0)
+ result->prototype = fillelement(left);
return result;
}
@@ -1793,6 +1805,9 @@ fnReshape(Array *left, Array *right)
return arrayitem(right, 0);
Array *res = allocarray(GetType(right), GetSize(left), size);
+ if(size == 0)
+ res->prototype = fillelement(right);
+
for(i = 0; i < GetSize(left); i++)
res->shape[i] = left->intdata[i];
for(i = 0, p = res->rawdata; i < size; i++, p += datasizes[GetType(res)])
diff --git a/memory.c b/memory.c
index f1ff3a3..c94993c 100644
--- a/memory.c
+++ b/memory.c
@@ -64,11 +64,15 @@ freearray(Array *a)
SetRefs(a, GetRefs(a)-1);
if(GetRefs(a) == 0){
- if(GetType(a) == AtypeArray)
- for(int i = 0; i < GetSize(a); i++)
- freearray(a->arraydata[i]);
+ if(GetType(a) == AtypeArray){
+ if(GetSize(a) > 0){
+ for(int i = 0; i < GetSize(a); i++)
+ freearray(a->arraydata[i]);
+ free(a->rawdata);
+ }else
+ freearray(a->prototype);
+ }
free(a->shape);
- free(a->rawdata);
free(a);
arrayalloccounts--;
}
diff --git a/tests/queens.apl b/tests/queens.apl
index d372186..5ea1de4 100644
--- a/tests/queens.apl
+++ b/tests/queens.apl
@@ -3,7 +3,7 @@ atk←{∪∊(⊂⍵)+¯1 0 1×⊂⌽⍳⍴⍵}
subs←{(⊂⍵)⍪¨(⍳⍴⊃⍺)~atk ⍵}
accm←{⍺⍪((⍴⍵)=⍴⊃⍺)↑⊂⍵}
fmt←{(⊂⎕io+⍵=⌾⍳⍴⍵)⌷'∘⎕'}
-queens←{fmt¨ 1↓(↓1 ⍵⍴0)accm dfs subs ⍬}
+queens←{fmt¨ (↓0 ⍵⍴0)accm dfs subs ⍬}
eightqueens←queens 8
⎕←'Number of solutions to 8 queens: ',⍕≢eightqueens
⎕←'First five:'