diff --git a/Week 4-workshop/README.md b/Week 4-workshop/README.md new file mode 100644 index 0000000..40cdc4f --- /dev/null +++ b/Week 4-workshop/README.md @@ -0,0 +1,5 @@ +## Workshop 3 content + +Workshop content: http://web.archive.org/web/20210817060220/https://teaching.csse.uwa.edu.au/units/CITS2002/workshops/workshop4.php \ +`stackmachine.c` template: http://web.archive.org/web/20210817060343/https://teaching.csse.uwa.edu.au/units/CITS2002/workshops/stackmachine.c \ +`stackinstructions`: http://web.archive.org/web/20210817060255/https://teaching.csse.uwa.edu.au/units/CITS2002/workshops/stackinstructions \ No newline at end of file diff --git a/Week 4-workshop/stackinstructions.txt b/Week 4-workshop/stackinstructions.txt new file mode 100644 index 0000000..2d2c835 --- /dev/null +++ b/Week 4-workshop/stackinstructions.txt @@ -0,0 +1,9 @@ +push 7 +push 3 +push 2 +subtract +multiply +push 5 +push 1 +add +add diff --git a/Week 4-workshop/stackmachine.c b/Week 4-workshop/stackmachine.c new file mode 100644 index 0000000..ea80ca2 --- /dev/null +++ b/Week 4-workshop/stackmachine.c @@ -0,0 +1,96 @@ +#include +#include +#include +#include + +// written by Chris.McDonald@uwa.edu.au +// +// compile: cc -std=c11 -Wall -Werror -o stackmachine stackmachine.c + +#define STACK_SIZE 1000 + +int stackmachine(FILE *input) +{ + int stack[STACK_SIZE]; // a large stack + int SP = -1; // stack is initially empty + + char line[100]; + +// READ FROM input UNTIL WE REACH THE END-OF-FILE + while(fgets(line, sizeof line, input) != NULL) { + char word1[50], word2[50]; + +// SPLIT THE LINE INTO UP TO TWO WORDS + int wcount = sscanf(line, "%s %s", word1, word2); + + if(wcount == 2) { + if(strcmp(word1, "push") == 0) { +// perform actions for the "push" instruction +// using word2 (an integer value) + stack[++SP] = atoi(word2); + } else if(strcmp(word1, "pop") == 0) { + SP--; + } + +// add other instructions here.... + } else if(wcount == 1 && SP > 0) { + if(strcmp(word1, "add") == 0) { +// perform actions for the "add" instruction + stack[--SP] = stack[SP] + stack[SP-1]; + } else if(strcmp(word1, "subtract") == 0) { + stack[--SP] = stack[SP-1] - stack[SP]; + } else if(strcmp(word1, "multiply") == 0) { + stack[--SP] = stack[SP] * stack[SP-1]; + } +// add other instructions here.... + } else if (SP < 2) { + fprintf(stderr, "HALT: Pointer out of range\n"); + exit(EXIT_FAILURE); + } + if (SP < 0 || SP >= STACK_SIZE) { + fprintf(stderr, "HALT: Pointer out of range\n"); + exit(EXIT_FAILURE); + } + + printf("%d\n",stack[SP]); + + if(wcount == 0) { + fprintf(stderr, "HALT: unrecognised line: %s\n", line); + exit(EXIT_FAILURE); + } + } + +// RETURN THE FINAL RESULT (FROM THE TOP-OF-STACK) + return stack[SP--]; +} + +int main(int argc, char *argv[]) +{ + int result; + argv[1] = "./stackinstructions.txt"; +// CHECK THE NUMBER OF ARGUMENTS + if(argc > 1) { + FILE *fp = fopen(argv[1], "r"); + +// ATTEMPT TO OPEN AND EVALUATE THE INSTRUCTIONS FROM A FILE + if(fp == NULL) { + fprintf(stderr, "HALT: cannot open '%s'\n", argv[1]); + exit(EXIT_FAILURE); + } + result = stackmachine(fp); + fclose(fp); // we opened it, so we close it + } + +// OTHERWISE, EVALUATE THE INSTRUCTIONS FROM stdin (THE KEYBOARD) + else { + result = stackmachine(stdin); + } + +// PRINT THE FINAL RESULT (FROM THE TOP-OF-STACK) + printf("result = %i\n", result); + +// YOU CAN PROVIDE ANY (OR ALL!) OF THE FOLLOWING LINES (DOESN'T MATTER) + exit(EXIT_SUCCESS); + return EXIT_SUCCESS; + return 0; +}