Something went wrong. Try again.
the hito embeddable programming language
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102#include "source.h"#include "util.h"#include <stdlib.h>#include <string.h>#include <stdio.h>
struct source { char* contents; const char* file_name; size_t size;};
static source_t *_source_alloc(struct source data) { source_t *source = malloc(sizeof (struct source)); if (source == NULL) { die("Out of memory: cannot allocate source struct"); } *source = data; return source;}
static struct source _read_file(const char *file_name) { FILE *f = fopen(file_name, "r"); if (!f) { die("Cannot read file %s", file_name); } size_t capacity = 1024; // initial buffer size size_t length = 0; char *buffer = malloc(capacity); if (buffer == NULL) { die("Out of memory: cannot allocate buffer for %s", file_name); } int ch; while ((ch = fgetc(f)) != EOF) { if (length + 1 >= capacity) { capacity *= 2; char *tmp = realloc(buffer, capacity); if (tmp == NULL) { fclose(f); die("Out of memory: cannot enlarge buffer for %s", file_name); } buffer = tmp; } buffer[length++] = (char)ch; }
buffer[length] = '\0'; // null-terminate fclose(f); struct source it; it.contents = buffer; it.size = length; it.file_name = file_name; return it;}
source_t *source_alloc_from_file(char* file_name) { return _source_alloc(_read_file(file_name));}
source_t *source_alloc(const char* file_name, char* contents) { struct source it = { .file_name = file_name, .contents = contents, .size = strlen(contents)}; return _source_alloc(it); }
pos_t source_next_pos(source_t *source, pos_t pos) { if (source->contents[pos.idx] == '\n') { pos.idx++; pos.col = 0; pos.line++; } else { pos.idx++; pos.col++; } return pos;}
void source_print_pos(source_t *source, pos_t pos) { fprintf(stderr,"%s:%d:%d", source->file_name,pos.line + 1,pos.col + 1);}
void source_print_line(source_t *source, pos_t pos, int highlight_len) { fprintf(stderr,"%5d | ",pos.line+1); for (size_t i = pos.idx - pos.col; i < source->size && source->contents[i] != '\n' && source->contents[i] != '\0'; i++) fputc(source->contents[i],stderr); if (highlight_len <= 0) return; fprintf(stderr,"\n | "); for (int i = 0; i < pos.col; i++) fputc(' ',stderr); for (int i = 0; i < highlight_len; i++) fputc('^',stderr);}
const char* source_contents_from(source_t* source, pos_t pos) { if (pos.idx >= source->size) { return source->contents + source->size; } else { return source->contents + pos.idx; }}
void source_dealloc(source_t* source) { free(source->contents);}