ooj icon indicating copy to clipboard operation
ooj copied to clipboard

I enjoyed reading your code

Open dataf3l opened this issue 1 year ago • 12 comments

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

dataf3l avatar Jan 05 '24 07:01 dataf3l