labashki/src/stack.c
2024-06-17 05:48:07 +05:00

123 lines
2.8 KiB
C

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "stack.h"
Stack *program_init(uint16_t stacksize)
{
Stack *stack = calloc(1,sizeof(&stack) + sizeof(Instruction) * PROGRAM_MAXSIZE + sizeof(int16_t) * MAX_LABELS +
sizeof(uint16_t) * stacksize);
stack->stacksize = stacksize;
for (unsigned int i = 0; i < MAX_LABELS; i++)
stack->labels[i] = -1; // костыль ебанный
return stack;
}
void stack_push(Stack *stack, uint16_t data)
{
if (stack->pointer > STACK_SIZE)
kms(stack, "STACK OVERFLOW");
stack->memory[stack->pointer++] = data;
}
uint16_t stack_pop(Stack *stack)
{
if (stack->pointer <= 0)
kms(stack, "STACK UNDERFLOW");
return stack->memory[--stack->pointer];
}
uint16_t stack_peek(Stack *stack)
{
return stack->memory[stack->pointer - 1];
}
void kms(Stack *stack, const char *err)
{
if (DEBUG_MODE)
for (int i = 0; i < stack->pointer; i++)
printf("%d: %d\n", i, stack->memory[i]);
fprintf(stderr, "%s", err);
free(stack);
exit(1);
}
void parse_and_process(Stack *stack, FILE *file)
{
char *line = NULL;
size_t len = 0;
while (getline(&line, &len, file) != -1)
{
if (line[0] == ';')
continue;
line[strcspn(line, "\n")] = 0;
unsigned long com = strcspn(line, ";");
if (com)
line[com] = '\0'; // шоб пропустил комментарий
Instruction inst;
memset(&inst, 0, sizeof(inst)); // обнуляем структуру на всякий если
// вернутся старые значения
inst.name = strtok(line, " ");
if (!inst.name)
continue;
if (inst.name[0] == 9)
{
printf("Tabs are not allowed!\n");
exit(1);
}
char *data = strtok(NULL, "");
if (!data)
data = 0;
else if (inst.name[0] == '#' || inst.name[1] == '#')
inst.arg = strtok(data, " ");
else if (inst.name[0] == '$' || inst.name[1] == '$')
inst.arg = data;
else
inst.data = strtol(data, NULL, 10);
char *duppedname = strdup(inst.name);
if (!inst.arg)
inst.arg = "\n";
char *duppedarg = strdup(inst.arg);
stack->program[stack->program_size++] = (Instruction){duppedname, duppedarg, inst.data};
}
}
Stack *stack_callback_pointer;
void stack_init_callback(Stack *stack)
{
stack_callback_pointer = stack;
}
uint16_t stack_pop_callback(void)
{
return stack_pop(stack_callback_pointer);
}
void stack_push_callback(uint16_t number)
{
stack_push(stack_callback_pointer, number);
}
size_t stack_len_callback(void)
{
return stack_callback_pointer->pointer;
}