tinyvm/libtvm/tvm_program.c
Payton Turnage e99a0428f3 Implement defines using the htab structure.
The htab_structure has been modified in two ways, which should not break
compatability with any of its uses.

It includes a void pointer, which is in this commit used to point to a
string for defines, and will in the future be used to point to the address
space for words, bytes, and double words.

It now includes a function htab_add_str specifically for storing strings.
It calls htab_add so as not to be redundant, but makes the node's value
their index for the lexer to fetch using htab_find, and assigns their
void pointer.

The lexer will now use htab_find on all tokens to see if they are a define
string, and if so, substitute them with the appropriate token.

The defines htab is destroyed after lexing, because that memory is done.
2014-01-13 10:20:21 -05:00

75 lines
1.6 KiB
C

#include <tvm/tvm_file.h>
#include <tvm/tvm_program.h>
#include <tvm/tvm_preprocessor.h>
#include <tvm/tvm_lexer.h>
#include <tvm/tvm_parser.h>
tvm_program_t *program_create()
{
tvm_program_t *p = (tvm_program_t *)calloc(1, sizeof(tvm_program_t));
p->label_htab = htab_create();
p->defines = htab_create();
return p;
}
void program_destroy(tvm_program_t *p)
{
htab_destroy(p->label_htab);
if(p->values)
{
for(int i = 0; i < p->num_values; i++) free(p->values[i]);
free(p->values);
}
if(p->args)
{
for(int i = 0; p->args[i]; i++) free(p->args[i]);
free(p->args);
}
if(p->instr) free(p->instr);
free(p);
}
int program_interpret(tvm_program_t *p, char *filename, tvm_memory_t *pMemory)
{
FILE *pFile = NULL;
int source_length = 0;
/* Attempt to open the file. If the file cannot be opened, try once more. */
if(filename)
for(int i = 0; i < 2; i++)
if(!pFile) pFile = tvm_fopen(filename, ".vm", "r");
if(pFile) goto pi_interpret;
printf("File was not found, or does not exist. Unable to interpret.\n");
return 1;
pi_interpret:
source_length = tvm_flength(pFile);
char *source = calloc(source_length, sizeof(char));
tvm_fcopy(source, source_length, pFile);
fclose(pFile);
int err = 0;
while((err = tvm_preprocess(source, &source_length, p->defines)) > 0);
/* The preprocessor encountered a problem. */
if (err < 0)
return 1;
tvm_lexer_t *lexer_ctx = lexer_create();
lex(lexer_ctx, source, p->defines);
free(source);
if(parse_labels(p, (const char ***)lexer_ctx->tokens) != 0) return 1;
if(parse_instructions(p, (const char ***)lexer_ctx->tokens, pMemory) != 0) return 1;
lexer_destroy(lexer_ctx);
return 0;
}