123 lines
2.8 KiB
C
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;
|
|
}
|