ooj
ooj copied to clipboard
I enjoyed reading your code
I made some minor modifications, would you consider taking a look at them and providing feedback?
#include<stdlib.h> //malloc
#include<stdio.h> //fgets printf
#include<string.h> //strlen
//typedef void _;
typedef char C,*S;
typedef struct a {
long long t, r;
long long d[3];
long long p[2];
}* Array;
static Array st[26];
#define globalArrayStack st
Array reduce(Array x, Array y);
Array scanArray(Array x, Array y);
Array ex(Array * e);
long long WS = 0;
long long * allocMem(long long size) {
size *= 8; // Assuming 8 bytes per long long
WS += size; // Update Workspace Size
return (long long *)malloc(size);
}
void copyMem(long long *dest, long long *src, long long count) {
for (long long i = 0; i < count; i++) {
dest[i] = src[i];
}
}
long long calcSize(long long rank, long long *dimensions) {
long long totalSize = 1;
for (long long i = 0; i < rank; i++) {
totalSize *= dimensions[i];
}
return totalSize;
}
Array indexOfChar(char targetChar, char* str) {
for (long long i = 0; str[i] != '\0'; i++) {
if (str[i] == targetChar) {
return (Array)(i + 1); // +1 because index is 1-based in this context
}
}
return 0;
}
Array createArray(long long type, long long rank, long long *dimensions) {
Array newArray = (Array)allocMem(5 + calcSize(rank, dimensions));
newArray->t = type;
newArray->r = rank;
copyMem(newArray->d, dimensions, rank);
return newArray;
}
Array id(Array x) {
return x;
}
Array sequence(Array x) {
long long length = *x->p;
Array newArray = createArray(0, 1, &length);
for (long long i = 0; i < length; i++) {
newArray->p[i] = i;
}
return newArray;
}
Array plus(Array x, Array y) {
long long rank = y->r;
long long *dimensions = y->d;
long long totalCount = calcSize(rank, dimensions);
Array resultArray = createArray(0, rank, dimensions);
for (long long i = 0; i < totalCount; i++) {
resultArray->p[i] = ((!x->r) ? *x->p : x->p[i]) + ((!y->r) ? *y->p : y->p[i]);
}
return resultArray;
}
Array mul(Array x, Array y) {
long long rank = y->r;
long long *dimensions = y->d;
long long totalCount = calcSize(rank, dimensions);
Array resultArray = createArray(0, rank, dimensions);
for (long long i = 0; i < totalCount; i++) {
resultArray->p[i] = ((!x->r) ? *x->p : x->p[i]) * ((!y->r) ? *y->p : y->p[i]);
}
return resultArray;
}
Array extractFromArray(Array indexArray, Array sourceArray) {
long long reducedRank = sourceArray->r - 1;
long long *reducedDimensions = sourceArray->d + 1;
long long totalElements = calcSize(reducedRank, reducedDimensions);
Array resultArray = createArray(sourceArray->t, reducedRank, reducedDimensions);
copyMem(resultArray->p, sourceArray->p + (totalElements * *indexArray->p), totalElements);
return resultArray;
}
Array boxArray(Array inputArray) {
Array boxedArray = createArray(1, 0, 0);
*boxedArray->p = (long long) inputArray;
return boxedArray;
}
Array concatenateArrays(Array firstArray, Array secondArray) {
long long firstArraySize = calcSize(firstArray->r, firstArray->d);
long long secondArraySize = calcSize(secondArray->r, secondArray->d);
long long totalSize = firstArraySize + secondArraySize;
Array concatenatedArray = createArray(secondArray->t, 1, &totalSize);
copyMem(concatenatedArray->p, firstArray->p, firstArraySize);
copyMem(concatenatedArray->p + firstArraySize, secondArray->p, secondArraySize);
return concatenatedArray;
}
Array findElement(Array x, Array y) {
printf("nyi\n");
return (Array) 0;
}
Array reshapeArray(Array shapeArray, Array inputArray) {
// Determine the rank and total size for the new shape
long long newRank = shapeArray->r ? *shapeArray->d : 1;
long long newSize = calcSize(newRank, shapeArray->p);
// Calculate the total number of elements in the input array
long long inputSize = calcSize(inputArray->r, inputArray->d);
// Create a new array with the desired shape and type
Array reshapedArray = createArray(inputArray->t, newRank, shapeArray->p);
// Determine the number of elements to copy (the smaller of newSize or inputSize)
long long elementsToCopy = newSize > inputSize ? inputSize : newSize;
// Copy elements from the input array to the reshaped array
copyMem(reshapedArray->p, inputArray->p, elementsToCopy);
// If the new size is larger, repeat the input array elements to fill the reshaped array
if (newSize > inputSize) {
copyMem(reshapedArray->p + inputSize, reshapedArray->p, newSize - inputSize);
}
return reshapedArray;
}
Array sha(Array x) {
Array z = createArray(0, 1, & x -> r);
copyMem(z -> p, x -> d, x -> r);
return z;
}
Array size(Array x) {
// Create an array to store the size result
Array resultArray = createArray(0, 0, 0);
// If the array x has a rank (r) greater than 0, use the size of the first dimension.
// Otherwise, the size is considered as 1 (for rank 0 arrays).
long long sizeValue = (x->r > 0) ? x->d[0] : 1;
// Store the calculated size in the result array
*resultArray->p = sizeValue;
return resultArray;
}
Array firstElement(Array x) {
Array z = createArray(0, 0, 0);
*z -> p = * x -> p;
return z;
}
Array reverseArray(Array inputArray) {
long long rank = inputArray->r;
long long *dimensions = inputArray->d;
long long totalElements = calcSize(rank, dimensions);
Array reversedArray = createArray(0, rank, dimensions);
for (long long index = 0; index < totalElements; index++) {
reversedArray->p[index] = inputArray->p[totalElements - index - 1];
}
return reversedArray;
}
char verbTable[] = "+{!<#,*|", at[] = "\\/";
Array( * verbDispatcher[])(Array, Array) = {
0,
plus,
extractFromArray,
findElement,
0,
reshapeArray,
concatenateArrays,
mul,
0
},
( * vm[])(Array) = {
0,
id,
size,
sequence,
boxArray,
sha,
0,
firstElement,
reverseArray
},
( * va[])(Array, Array) = {
0,
scanArray,
reduce
};
Array reduce(Array functionArray, Array inputArray) {
// Check if the input array is empty or has rank 0; return it directly if so
if (!inputArray->r) {
return inputArray;
}
// Create arrays for the reduction process
Array resultArray = createArray(0, 0, 0);
Array tempArray = createArray(0, 0, 0);
// Initialize the first element of resultArray with the first element of inputArray
*resultArray->p = *inputArray->p;
// If inputArray has more than one element, initialize tempArray with the second element
*tempArray->p = inputArray->r > 1 ? inputArray->p[1] : 0;
// Perform the reduction
long long totalIterations = (inputArray->r ? *inputArray->d : 1) - 1;
for (long long i = 0; i < totalIterations; ++i) {
*tempArray->p = inputArray->p[i + 1];
*resultArray->p = *((*verbDispatcher[(long long)functionArray])(resultArray, tempArray))->p;
}
return resultArray;
}
Array scanArray(Array functionArray, Array inputArray) {
// Check if inputArray is empty or has rank 0, in which case return inputArray itself
if (!inputArray->r) {
return inputArray;
}
// Create an array 'result' with the same shape as inputArray
Array result = createArray(0, inputArray->r, inputArray->d);
// Initialize temporary arrays for the scan operation
Array temp1 = createArray(0, 0, 0);
Array temp2 = createArray(0, 0, 0);
// Initialize the first elements of temp1 and result with the first element of inputArray
*temp1->p = *result->p = *inputArray->p;
// If inputArray has more than one element, initialize temp2 with the second element
if (inputArray->r > 1) {
*temp2->p = inputArray->p[1];
}
// Iterate over the elements of the inputArray, applying the functionArray
long long totalIterations = (inputArray->r ? *inputArray->d : 1) - 1;
for (long long i = 0; i < totalIterations; ++i) {
*temp2->p = inputArray->p[i + 1];
result->p[i + 1] = *temp1->p = *((*verbDispatcher[(long long)functionArray])(temp1, temp2))->p;
}
// Return the final result of the scan operation
return result;
}
long long convertStringToLongLong(char* inputString, long long *numberLength) { // convertStringToLongLong
char currentChar;
long long index = 0, result = 0;
*numberLength = 0;
while ((currentChar = *inputString++) && (currentChar >= '0' && currentChar <= '9')) {
index++;
result = result * 10 + (currentChar - '0');
}
*numberLength = index;
return result;
}
void printInt(long long i) {
printf("%lld ", i);
}
void newline() {
printf("\n");
}
void printTab() {
printf(" ");
}
void printArray(Array arrayToPrint) {
long long rank = arrayToPrint->r;
long long *dimensions = arrayToPrint->d;
long long totalElements = calcSize(rank, dimensions);
if (arrayToPrint->t) {
// If the array type is non-zero, handle as a nested (boxed) array
for (long long i = 0; i < totalElements; i++) {
printf("< ");
printArray((Array)arrayToPrint->p[i]);
}
} else {
// Handle as a flat array
for (long long i = 0; i < totalElements; i++) {
printInt(arrayToPrint->p[i]);
}
}
}
char isLowercase(long long a) {
return a >= 'a' && a <= 'z';
}
char qv(long long a) {
return a < 'a';
}
char isUppercase(long long a) { // qv
return a < 'a';
}
Array getAdverb(char c) {
return indexOfChar(c, at);
}
Array verb(char c) {
return indexOfChar(c, verbTable);
}
Array noun(char** inputString) { // createNounFromString
char firstCharacter = **inputString;
long long stringLength;
// Check if the first character is not a digit; return NULL if so
if (firstCharacter < '0' || firstCharacter > '9') {
return NULL;
}
// Create an array to store the converted number
Array numberArray = createArray(0, 0, 0);
// Convert the string to a long long number and store in the array
*numberArray->p = convertStringToLongLong(*inputString, &stringLength);
// Move the input string pointer forward by the length of the numeric part
*inputString += stringLength - 1;
return numberArray;
}
Array executeExpression(Array *expressionElements) {
long long firstElement = (long long)*expressionElements;
long long secondElement = (long long)expressionElements[1];
if (isLowercase(firstElement)) {
if (secondElement == ':') {
return (st[firstElement - 'a'] = executeExpression(expressionElements + 2));
}
firstElement = (long long)st[firstElement - 'a'];
}
if (isUppercase(firstElement) && getAdverb(secondElement)) {
Array (*adverbFunction)(Array, Array) = va[(long long)getAdverb(secondElement)];
return adverbFunction((Array)firstElement, executeExpression(expressionElements + 2));
}
if (isUppercase(firstElement)) {
Array (*monadFunction)(Array) = vm[firstElement];
return monadFunction(executeExpression(expressionElements + 1));
}
if (secondElement) {
Array (*verbFunction)(Array, Array) = verbDispatcher[secondElement];
return verbFunction((Array)firstElement, executeExpression(expressionElements + 2));
}
return (Array)firstElement;
}
Array * parseInput(char* inputStr) {
Array parsedElement;
Array *parsedElements;
char currentChar;
long long strLength = strlen(inputStr);
if (strLength==1) {
printf("Error: Input string is empty\n");
exit(1);
}
if (!strLength) return (Array *)0;
inputStr[--strLength] = 0;
parsedElements = (Array *)allocMem(strLength + 1);
strLength = 0;
while ((currentChar = *inputStr)) {
parsedElement = noun(&inputStr);
if (!parsedElement) {
parsedElement = verb(currentChar);
}
if (!parsedElement) {
parsedElement = (Array)(long long)currentChar;
}
parsedElements[strLength++] = parsedElement;
inputStr++;
}
parsedElements[strLength] = 0;
return parsedElements;
}
int main() {
char inputString[99];
while (1) {
//printf("WS: %llu\n", WS); // Print workspace size
printTab(); // Print a tab or space
// Read input from stdin. If fgets returns NULL, break the loop
if (fgets(inputString, 99, stdin) == NULL) {
break;
}
// Process the input and print the result
printArray(executeExpression(parseInput(inputString)));
newline(); // Print a newline character
}
return 0;
}
// https://codebeautify.org/cpp-formatter-beautifier