Rename sss_* to just *
This commit is contained in:
parent
0567fcc8ac
commit
79795096e7
6
ast.h
6
ast.h
@ -64,7 +64,7 @@ typedef struct tag_ast_s {
|
|||||||
|
|
||||||
struct type_ast_s {
|
struct type_ast_s {
|
||||||
type_ast_e tag;
|
type_ast_e tag;
|
||||||
sss_file_t *file;
|
file_t *file;
|
||||||
const char *start, *end;
|
const char *start, *end;
|
||||||
union {
|
union {
|
||||||
struct {} UnknownTypeAST;
|
struct {} UnknownTypeAST;
|
||||||
@ -115,7 +115,7 @@ typedef enum {
|
|||||||
|
|
||||||
struct ast_s {
|
struct ast_s {
|
||||||
ast_e tag;
|
ast_e tag;
|
||||||
sss_file_t *file;
|
file_t *file;
|
||||||
const char *start, *end;
|
const char *start, *end;
|
||||||
union {
|
union {
|
||||||
struct {} Unknown;
|
struct {} Unknown;
|
||||||
@ -249,7 +249,7 @@ struct ast_s {
|
|||||||
} DocTest;
|
} DocTest;
|
||||||
struct {
|
struct {
|
||||||
const char *path;
|
const char *path;
|
||||||
sss_file_t *file;
|
file_t *file;
|
||||||
bool main_program;
|
bool main_program;
|
||||||
} Use;
|
} Use;
|
||||||
struct {
|
struct {
|
||||||
|
54
files.c
54
files.c
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
static const int tabstop = 4;
|
static const int tabstop = 4;
|
||||||
|
|
||||||
public char *resolve_path(const char *path, const char *relative_to)
|
public char *resolve_path(const char *path, const char *relative_to, const char *system_path)
|
||||||
{
|
{
|
||||||
if (!relative_to || streq(relative_to, "/dev/stdin")) relative_to = ".";
|
if (!relative_to || streq(relative_to, "/dev/stdin")) relative_to = ".";
|
||||||
if (!path || strlen(path) == 0) return NULL;
|
if (!path || strlen(path) == 0) return NULL;
|
||||||
@ -38,9 +38,10 @@ public char *resolve_path(const char *path, const char *relative_to)
|
|||||||
if (resolved) return heap_str(resolved);
|
if (resolved) return heap_str(resolved);
|
||||||
} else {
|
} else {
|
||||||
// Relative path:
|
// Relative path:
|
||||||
char *blpath = heap_str(getenv("SSSPATH"));
|
|
||||||
char *relative_dir = dirname(heap_str(relative_to));
|
char *relative_dir = dirname(heap_str(relative_to));
|
||||||
for (char *dir; (dir = strsep(&blpath, ":")); ) {
|
if (!system_path) system_path = ".";
|
||||||
|
char *copy = strdup(system_path);
|
||||||
|
for (char *dir, *pos = copy; (dir = strsep(&pos, ":")); ) {
|
||||||
if (dir[0] == '/') {
|
if (dir[0] == '/') {
|
||||||
char *resolved = realpath(heap_strf("%s/%s", dir, path), buf);
|
char *resolved = realpath(heap_strf("%s/%s", dir, path), buf);
|
||||||
if (resolved) return heap_str(resolved);
|
if (resolved) return heap_str(resolved);
|
||||||
@ -58,28 +59,29 @@ public char *resolve_path(const char *path, const char *relative_to)
|
|||||||
if (resolved) return heap_str(resolved);
|
if (resolved) return heap_str(resolved);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(copy);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sss_file_t *_load_file(const char* filename, FILE *file)
|
static file_t *_load_file(const char* filename, FILE *file)
|
||||||
{
|
{
|
||||||
if (!file) return NULL;
|
if (!file) return NULL;
|
||||||
|
|
||||||
sss_file_t *ret = new(sss_file_t, .filename=filename);
|
file_t *ret = new(file_t, .filename=filename);
|
||||||
|
|
||||||
size_t file_size = 0, line_cap = 0;
|
size_t file_size = 0, line_cap = 0;
|
||||||
char *file_buf = NULL, *line_buf = NULL;
|
char *file_buf = NULL, *line_buf = NULL;
|
||||||
FILE *mem = open_memstream(&file_buf, &file_size);
|
FILE *mem = open_memstream(&file_buf, &file_size);
|
||||||
int64_t line_len = 0;
|
int64_t line_len = 0;
|
||||||
while ((line_len = getline(&line_buf, &line_cap, file)) >= 0) {
|
while ((line_len = getline(&line_buf, &line_cap, file)) >= 0) {
|
||||||
sss_line_t line_info = {.offset=file_size, .indent=0, .is_empty=false};
|
file_line_t line_info = {.offset=file_size, .indent=0, .is_empty=false};
|
||||||
char *p;
|
char *p;
|
||||||
for (p = line_buf; *p == ' ' || *p == '\t'; ++p)
|
for (p = line_buf; *p == ' ' || *p == '\t'; ++p)
|
||||||
line_info.indent += *p == ' ' ? 1 : 4;
|
line_info.indent += *p == ' ' ? 1 : 4;
|
||||||
line_info.is_empty = *p != '\r' && *p != '\n';
|
line_info.is_empty = *p != '\r' && *p != '\n';
|
||||||
if (ret->line_capacity <= ret->num_lines) {
|
if (ret->line_capacity <= ret->num_lines) {
|
||||||
ret->lines = GC_REALLOC(ret->lines, sizeof(sss_line_t)*(ret->line_capacity += 32));
|
ret->lines = GC_REALLOC(ret->lines, sizeof(file_line_t)*(ret->line_capacity += 32));
|
||||||
}
|
}
|
||||||
ret->lines[ret->num_lines++] = line_info;
|
ret->lines[ret->num_lines++] = line_info;
|
||||||
fwrite(line_buf, sizeof(char), line_len, mem);
|
fwrite(line_buf, sizeof(char), line_len, mem);
|
||||||
@ -97,7 +99,7 @@ static sss_file_t *_load_file(const char* filename, FILE *file)
|
|||||||
free(file_buf);
|
free(file_buf);
|
||||||
ret->relative_filename = filename;
|
ret->relative_filename = filename;
|
||||||
if (filename && filename[0] != '<' && !streq(filename, "/dev/stdin")) {
|
if (filename && filename[0] != '<' && !streq(filename, "/dev/stdin")) {
|
||||||
filename = resolve_path(filename, ".");
|
filename = resolve_path(filename, ".", ".");
|
||||||
// Convert to relative path (if applicable)
|
// Convert to relative path (if applicable)
|
||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
char *cwd = getcwd(buf, sizeof(buf));
|
char *cwd = getcwd(buf, sizeof(buf));
|
||||||
@ -111,7 +113,7 @@ static sss_file_t *_load_file(const char* filename, FILE *file)
|
|||||||
//
|
//
|
||||||
// Read an entire file into memory.
|
// Read an entire file into memory.
|
||||||
//
|
//
|
||||||
public sss_file_t *sss_load_file(const char* filename)
|
public file_t *load_file(const char* filename)
|
||||||
{
|
{
|
||||||
FILE *file = filename[0] ? fopen(filename, "r") : stdin;
|
FILE *file = filename[0] ? fopen(filename, "r") : stdin;
|
||||||
return _load_file(filename, file);
|
return _load_file(filename, file);
|
||||||
@ -120,7 +122,7 @@ public sss_file_t *sss_load_file(const char* filename)
|
|||||||
//
|
//
|
||||||
// Create a virtual file from a string.
|
// Create a virtual file from a string.
|
||||||
//
|
//
|
||||||
public sss_file_t *sss_spoof_file(const char* filename, const char *text)
|
public file_t *spoof_file(const char* filename, const char *text)
|
||||||
{
|
{
|
||||||
FILE *file = fmemopen((char*)text, strlen(text)+1, "r");
|
FILE *file = fmemopen((char*)text, strlen(text)+1, "r");
|
||||||
return _load_file(filename, file);
|
return _load_file(filename, file);
|
||||||
@ -129,7 +131,7 @@ public sss_file_t *sss_spoof_file(const char* filename, const char *text)
|
|||||||
//
|
//
|
||||||
// Given a pointer, determine which line number it points to (1-indexed)
|
// Given a pointer, determine which line number it points to (1-indexed)
|
||||||
//
|
//
|
||||||
public int64_t sss_get_line_number(sss_file_t *f, const char *p)
|
public int64_t get_line_number(file_t *f, const char *p)
|
||||||
{
|
{
|
||||||
// Binary search:
|
// Binary search:
|
||||||
int64_t lo = 0, hi = (int64_t)f->num_lines-1;
|
int64_t lo = 0, hi = (int64_t)f->num_lines-1;
|
||||||
@ -137,7 +139,7 @@ public int64_t sss_get_line_number(sss_file_t *f, const char *p)
|
|||||||
int64_t offset = (int64_t)(p - f->text);
|
int64_t offset = (int64_t)(p - f->text);
|
||||||
while (lo <= hi) {
|
while (lo <= hi) {
|
||||||
int64_t mid = (lo + hi) / 2;
|
int64_t mid = (lo + hi) / 2;
|
||||||
sss_line_t *line = &f->lines[mid];
|
file_line_t *line = &f->lines[mid];
|
||||||
if (line->offset == offset)
|
if (line->offset == offset)
|
||||||
return mid + 1;
|
return mid + 1;
|
||||||
else if (line->offset < offset)
|
else if (line->offset < offset)
|
||||||
@ -151,39 +153,39 @@ public int64_t sss_get_line_number(sss_file_t *f, const char *p)
|
|||||||
//
|
//
|
||||||
// Given a pointer, determine which line column it points to.
|
// Given a pointer, determine which line column it points to.
|
||||||
//
|
//
|
||||||
public int64_t sss_get_line_column(sss_file_t *f, const char *p)
|
public int64_t get_line_column(file_t *f, const char *p)
|
||||||
{
|
{
|
||||||
int64_t line_no = sss_get_line_number(f, p);
|
int64_t line_no = get_line_number(f, p);
|
||||||
sss_line_t *line = &f->lines[line_no-1];
|
file_line_t *line = &f->lines[line_no-1];
|
||||||
return 1 + (int64_t)(p - (f->text + line->offset));
|
return 1 + (int64_t)(p - (f->text + line->offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Given a pointer, get the indentation of the line it's on.
|
// Given a pointer, get the indentation of the line it's on.
|
||||||
//
|
//
|
||||||
public int64_t sss_get_indent(sss_file_t *f, const char *p)
|
public int64_t get_indent(file_t *f, const char *p)
|
||||||
{
|
{
|
||||||
int64_t line_no = sss_get_line_number(f, p);
|
int64_t line_no = get_line_number(f, p);
|
||||||
sss_line_t *line = &f->lines[line_no-1];
|
file_line_t *line = &f->lines[line_no-1];
|
||||||
return line->indent;
|
return line->indent;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Return a pointer to the line with the specified line number (1-indexed)
|
// Return a pointer to the line with the specified line number (1-indexed)
|
||||||
//
|
//
|
||||||
public const char *sss_get_line(sss_file_t *f, int64_t line_number)
|
public const char *get_line(file_t *f, int64_t line_number)
|
||||||
{
|
{
|
||||||
if (line_number == 0 || line_number > (int64_t)f->num_lines) return NULL;
|
if (line_number == 0 || line_number > (int64_t)f->num_lines) return NULL;
|
||||||
sss_line_t *line = &f->lines[line_number-1];
|
file_line_t *line = &f->lines[line_number-1];
|
||||||
return f->text + line->offset;
|
return f->text + line->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Return a value like /foo:line:col
|
// Return a value like /foo:line:col
|
||||||
//
|
//
|
||||||
public const char *sss_get_file_pos(sss_file_t *f, const char *p)
|
public const char *get_file_pos(file_t *f, const char *p)
|
||||||
{
|
{
|
||||||
return heap_strf("%s:%ld:%ld", f->filename, sss_get_line_number(f, p), sss_get_line_column(f, p));
|
return heap_strf("%s:%ld:%ld", f->filename, get_line_number(f, p), get_line_column(f, p));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fputc_column(FILE *out, char c, char print_char, int *column)
|
static int fputc_column(FILE *out, char c, char print_char, int *column)
|
||||||
@ -205,7 +207,7 @@ static int fputc_column(FILE *out, char c, char print_char, int *column)
|
|||||||
//
|
//
|
||||||
// Print a span from a file
|
// Print a span from a file
|
||||||
//
|
//
|
||||||
public int fprint_span(FILE *out, sss_file_t *file, const char *start, const char *end, const char *hl_color, int64_t context_lines, bool use_color)
|
public int fprint_span(FILE *out, file_t *file, const char *start, const char *end, const char *hl_color, int64_t context_lines, bool use_color)
|
||||||
{
|
{
|
||||||
if (!file) return 0;
|
if (!file) return 0;
|
||||||
|
|
||||||
@ -238,8 +240,8 @@ public int fprint_span(FILE *out, sss_file_t *file, const char *start, const cha
|
|||||||
if (context_lines == 0)
|
if (context_lines == 0)
|
||||||
return fprintf(out, "%s%.*s%s", hl_color, (int)(end - start), start, normal_color);
|
return fprintf(out, "%s%.*s%s", hl_color, (int)(end - start), start, normal_color);
|
||||||
|
|
||||||
int64_t start_line = sss_get_line_number(file, start),
|
int64_t start_line = get_line_number(file, start),
|
||||||
end_line = sss_get_line_number(file, end);
|
end_line = get_line_number(file, end);
|
||||||
|
|
||||||
int64_t first_line = start_line - (context_lines - 1),
|
int64_t first_line = start_line - (context_lines - 1),
|
||||||
last_line = end_line + (context_lines - 1);
|
last_line = end_line + (context_lines - 1);
|
||||||
@ -261,7 +263,7 @@ public int fprint_span(FILE *out, sss_file_t *file, const char *start, const cha
|
|||||||
}
|
}
|
||||||
|
|
||||||
printed += fprintf(out, lineno_fmt, digits, line_no);
|
printed += fprintf(out, lineno_fmt, digits, line_no);
|
||||||
const char *line = sss_get_line(file, line_no);
|
const char *line = get_line(file, line_no);
|
||||||
if (!line) break;
|
if (!line) break;
|
||||||
|
|
||||||
int column = 0;
|
int column = 0;
|
||||||
|
24
files.h
24
files.h
@ -13,31 +13,31 @@ typedef struct {
|
|||||||
int64_t offset;
|
int64_t offset;
|
||||||
int64_t indent:63;
|
int64_t indent:63;
|
||||||
bool is_empty:1;
|
bool is_empty:1;
|
||||||
} sss_line_t;
|
} file_line_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *filename, *relative_filename;
|
const char *filename, *relative_filename;
|
||||||
const char *text;
|
const char *text;
|
||||||
int64_t len;
|
int64_t len;
|
||||||
int64_t num_lines, line_capacity;
|
int64_t num_lines, line_capacity;
|
||||||
sss_line_t *lines;
|
file_line_t *lines;
|
||||||
} sss_file_t;
|
} file_t;
|
||||||
|
|
||||||
char *resolve_path(const char *path, const char *relative_to);
|
char *resolve_path(const char *path, const char *relative_to, const char *system_path);
|
||||||
__attribute__((nonnull))
|
__attribute__((nonnull))
|
||||||
sss_file_t *sss_load_file(const char *filename);
|
file_t *load_file(const char *filename);
|
||||||
__attribute__((nonnull, returns_nonnull))
|
__attribute__((nonnull, returns_nonnull))
|
||||||
sss_file_t *sss_spoof_file(const char *filename, const char *text);
|
file_t *spoof_file(const char *filename, const char *text);
|
||||||
__attribute__((pure, nonnull))
|
__attribute__((pure, nonnull))
|
||||||
int64_t sss_get_line_number(sss_file_t *f, const char *p);
|
int64_t get_line_number(file_t *f, const char *p);
|
||||||
__attribute__((pure, nonnull))
|
__attribute__((pure, nonnull))
|
||||||
int64_t sss_get_line_column(sss_file_t *f, const char *p);
|
int64_t get_line_column(file_t *f, const char *p);
|
||||||
__attribute__((pure, nonnull))
|
__attribute__((pure, nonnull))
|
||||||
int64_t sss_get_indent(sss_file_t *f, const char *p);
|
int64_t get_indent(file_t *f, const char *p);
|
||||||
__attribute__((pure, nonnull))
|
__attribute__((pure, nonnull))
|
||||||
const char *sss_get_line(sss_file_t *f, int64_t line_number);
|
const char *get_line(file_t *f, int64_t line_number);
|
||||||
__attribute__((pure, nonnull))
|
__attribute__((pure, nonnull))
|
||||||
const char *sss_get_file_pos(sss_file_t *f, const char *p);
|
const char *get_file_pos(file_t *f, const char *p);
|
||||||
int fprint_span(FILE *out, sss_file_t *file, const char *start, const char *end, const char *hl_color, int64_t context_lines, bool use_color);
|
int fprint_span(FILE *out, file_t *file, const char *start, const char *end, const char *hl_color, int64_t context_lines, bool use_color);
|
||||||
|
|
||||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||||
|
@ -22,9 +22,7 @@ int main(int argc, char *argv[])
|
|||||||
const char *autofmt = getenv("AUTOFMT");
|
const char *autofmt = getenv("AUTOFMT");
|
||||||
if (!autofmt) autofmt = "indent -kr -nut";
|
if (!autofmt) autofmt = "indent -kr -nut";
|
||||||
|
|
||||||
setenv("SSSPATH", ".", 0);
|
file_t *f = load_file(argv[1]);
|
||||||
|
|
||||||
sss_file_t *f = sss_load_file(argv[1]);
|
|
||||||
|
|
||||||
ast_t *ast = parse_file(f, NULL);
|
ast_t *ast = parse_file(f, NULL);
|
||||||
|
|
||||||
|
56
parse.c
56
parse.c
@ -1,4 +1,4 @@
|
|||||||
// Parse SSS code using recursive descent
|
// Parse code using recursive descent
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <gc.h>
|
#include <gc.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
@ -17,7 +17,7 @@
|
|||||||
static const char closing[128] = {['(']=')', ['[']=']', ['<']='>', ['{']='}'};
|
static const char closing[128] = {['(']=')', ['[']=']', ['<']='>', ['{']='}'};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
sss_file_t *file;
|
file_t *file;
|
||||||
jmp_buf *on_err;
|
jmp_buf *on_err;
|
||||||
} parse_ctx_t;
|
} parse_ctx_t;
|
||||||
|
|
||||||
@ -99,8 +99,8 @@ __attribute__((noreturn))
|
|||||||
static void vparser_err(parse_ctx_t *ctx, const char *start, const char *end, const char *fmt, va_list args) {
|
static void vparser_err(parse_ctx_t *ctx, const char *start, const char *end, const char *fmt, va_list args) {
|
||||||
if (isatty(STDERR_FILENO) && !getenv("NO_COLOR"))
|
if (isatty(STDERR_FILENO) && !getenv("NO_COLOR"))
|
||||||
fputs("\x1b[31;1;7m", stderr);
|
fputs("\x1b[31;1;7m", stderr);
|
||||||
fprintf(stderr, "%s:%ld.%ld: ", ctx->file->relative_filename, sss_get_line_number(ctx->file, start),
|
fprintf(stderr, "%s:%ld.%ld: ", ctx->file->relative_filename, get_line_number(ctx->file, start),
|
||||||
sss_get_line_column(ctx->file, start));
|
get_line_column(ctx->file, start));
|
||||||
vfprintf(stderr, fmt, args);
|
vfprintf(stderr, fmt, args);
|
||||||
if (isatty(STDERR_FILENO) && !getenv("NO_COLOR"))
|
if (isatty(STDERR_FILENO) && !getenv("NO_COLOR"))
|
||||||
fputs(" \x1b[m", stderr);
|
fputs(" \x1b[m", stderr);
|
||||||
@ -320,12 +320,12 @@ bool comment(const char **pos) {
|
|||||||
|
|
||||||
bool indent(parse_ctx_t *ctx, const char **out) {
|
bool indent(parse_ctx_t *ctx, const char **out) {
|
||||||
const char *pos = *out;
|
const char *pos = *out;
|
||||||
int64_t starting_indent = sss_get_indent(ctx->file, pos);
|
int64_t starting_indent = get_indent(ctx->file, pos);
|
||||||
whitespace(&pos);
|
whitespace(&pos);
|
||||||
if (sss_get_line_number(ctx->file, pos) == sss_get_line_number(ctx->file, *out))
|
if (get_line_number(ctx->file, pos) == get_line_number(ctx->file, *out))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (sss_get_indent(ctx->file, pos) > starting_indent) {
|
if (get_indent(ctx->file, pos) > starting_indent) {
|
||||||
*out = pos;
|
*out = pos;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -764,7 +764,7 @@ ast_t *parse_index_suffix(parse_ctx_t *ctx, ast_t *lhs) {
|
|||||||
PARSER(parse_if) {
|
PARSER(parse_if) {
|
||||||
// if <condition> [then] <body> [else <body>]
|
// if <condition> [then] <body> [else <body>]
|
||||||
const char *start = pos;
|
const char *start = pos;
|
||||||
int64_t starting_indent = sss_get_indent(ctx->file, pos);
|
int64_t starting_indent = get_indent(ctx->file, pos);
|
||||||
|
|
||||||
if (!match_word(&pos, "if"))
|
if (!match_word(&pos, "if"))
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -780,7 +780,7 @@ PARSER(parse_if) {
|
|||||||
const char *tmp = pos;
|
const char *tmp = pos;
|
||||||
whitespace(&tmp);
|
whitespace(&tmp);
|
||||||
ast_t *else_body = NULL;
|
ast_t *else_body = NULL;
|
||||||
if (sss_get_indent(ctx->file, tmp) == starting_indent && match_word(&tmp, "else")) {
|
if (get_indent(ctx->file, tmp) == starting_indent && match_word(&tmp, "else")) {
|
||||||
pos = tmp;
|
pos = tmp;
|
||||||
else_body = expect(ctx, start, &pos, parse_opt_indented_block, "I expected a body for this 'else'");
|
else_body = expect(ctx, start, &pos, parse_opt_indented_block, "I expected a body for this 'else'");
|
||||||
}
|
}
|
||||||
@ -898,12 +898,12 @@ PARSER(parse_string) {
|
|||||||
|
|
||||||
// printf("Parsing string: '%c' .. '%c' interp: '%c%c'\n", *start, close_quote, open_interp, close_interp);
|
// printf("Parsing string: '%c' .. '%c' interp: '%c%c'\n", *start, close_quote, open_interp, close_interp);
|
||||||
|
|
||||||
int64_t starting_indent = sss_get_indent(ctx->file, pos);
|
int64_t starting_indent = get_indent(ctx->file, pos);
|
||||||
int64_t string_indent;
|
int64_t string_indent;
|
||||||
if (*pos == '\r' || *pos == '\n') {
|
if (*pos == '\r' || *pos == '\n') {
|
||||||
const char *first_line = pos;
|
const char *first_line = pos;
|
||||||
whitespace(&first_line);
|
whitespace(&first_line);
|
||||||
string_indent = sss_get_indent(ctx->file, first_line);
|
string_indent = get_indent(ctx->file, first_line);
|
||||||
if (string_indent <= starting_indent)
|
if (string_indent <= starting_indent)
|
||||||
parser_err(ctx, start, first_line, "Multi-line strings must be indented on their first line");
|
parser_err(ctx, start, first_line, "Multi-line strings must be indented on their first line");
|
||||||
} else {
|
} else {
|
||||||
@ -935,12 +935,12 @@ PARSER(parse_string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (*pos == open_quote && closing[(int)open_quote]) {
|
} else if (*pos == open_quote && closing[(int)open_quote]) {
|
||||||
if (sss_get_indent(ctx->file, pos) == starting_indent) {
|
if (get_indent(ctx->file, pos) == starting_indent) {
|
||||||
++depth;
|
++depth;
|
||||||
}
|
}
|
||||||
chunk = CORD_cat_char(chunk, *pos);
|
chunk = CORD_cat_char(chunk, *pos);
|
||||||
} else if (*pos == close_quote) {
|
} else if (*pos == close_quote) {
|
||||||
if (sss_get_indent(ctx->file, pos) == starting_indent) {
|
if (get_indent(ctx->file, pos) == starting_indent) {
|
||||||
--depth;
|
--depth;
|
||||||
if (depth == 0)
|
if (depth == 0)
|
||||||
break;
|
break;
|
||||||
@ -956,7 +956,7 @@ PARSER(parse_string) {
|
|||||||
--pos;
|
--pos;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (sss_get_indent(ctx->file, pos) == starting_indent) {
|
if (get_indent(ctx->file, pos) == starting_indent) {
|
||||||
if (*pos == close_quote) {
|
if (*pos == close_quote) {
|
||||||
break;
|
break;
|
||||||
} else if (some_of(&pos, ".") >= 2) {
|
} else if (some_of(&pos, ".") >= 2) {
|
||||||
@ -1330,7 +1330,7 @@ PARSER(parse_extended_expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PARSER(parse_block) {
|
PARSER(parse_block) {
|
||||||
int64_t block_indent = sss_get_indent(ctx->file, pos);
|
int64_t block_indent = get_indent(ctx->file, pos);
|
||||||
const char *start = pos;
|
const char *start = pos;
|
||||||
whitespace(&pos);
|
whitespace(&pos);
|
||||||
ast_list_t *statements = NULL;
|
ast_list_t *statements = NULL;
|
||||||
@ -1344,7 +1344,7 @@ PARSER(parse_block) {
|
|||||||
}
|
}
|
||||||
statements = new(ast_list_t, .ast=stmt, .next=statements);
|
statements = new(ast_list_t, .ast=stmt, .next=statements);
|
||||||
whitespace(&pos);
|
whitespace(&pos);
|
||||||
if (sss_get_indent(ctx->file, pos) != block_indent) {
|
if (get_indent(ctx->file, pos) != block_indent) {
|
||||||
pos = stmt->end; // backtrack
|
pos = stmt->end; // backtrack
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1360,12 +1360,12 @@ PARSER(parse_opt_indented_block) {
|
|||||||
PARSER(parse_namespace) {
|
PARSER(parse_namespace) {
|
||||||
const char *start = pos;
|
const char *start = pos;
|
||||||
whitespace(&pos);
|
whitespace(&pos);
|
||||||
int64_t indent = sss_get_indent(ctx->file, pos);
|
int64_t indent = get_indent(ctx->file, pos);
|
||||||
ast_list_t *statements = NULL;
|
ast_list_t *statements = NULL;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
const char *next = pos;
|
const char *next = pos;
|
||||||
whitespace(&next);
|
whitespace(&next);
|
||||||
if (sss_get_indent(ctx->file, next) != indent) break;
|
if (get_indent(ctx->file, next) != indent) break;
|
||||||
ast_t *stmt;
|
ast_t *stmt;
|
||||||
if ((stmt=optional(ctx, &pos, parse_struct_def))
|
if ((stmt=optional(ctx, &pos, parse_struct_def))
|
||||||
||(stmt=optional(ctx, &pos, parse_enum_def))
|
||(stmt=optional(ctx, &pos, parse_enum_def))
|
||||||
@ -1376,7 +1376,7 @@ PARSER(parse_namespace) {
|
|||||||
pos = stmt->end;
|
pos = stmt->end;
|
||||||
whitespace(&pos);
|
whitespace(&pos);
|
||||||
} else {
|
} else {
|
||||||
if (sss_get_indent(ctx->file, next) > indent && next < strchrnul(next, '\n'))
|
if (get_indent(ctx->file, next) > indent && next < strchrnul(next, '\n'))
|
||||||
parser_err(ctx, next, strchrnul(next, '\n'), "I couldn't parse this namespace statement");
|
parser_err(ctx, next, strchrnul(next, '\n'), "I couldn't parse this namespace statement");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1390,7 +1390,7 @@ PARSER(parse_struct_def) {
|
|||||||
const char *start = pos;
|
const char *start = pos;
|
||||||
if (!match_word(&pos, "struct")) return NULL;
|
if (!match_word(&pos, "struct")) return NULL;
|
||||||
|
|
||||||
int64_t starting_indent = sss_get_indent(ctx->file, pos);
|
int64_t starting_indent = get_indent(ctx->file, pos);
|
||||||
|
|
||||||
spaces(&pos);
|
spaces(&pos);
|
||||||
const char *name = get_id(&pos);
|
const char *name = get_id(&pos);
|
||||||
@ -1406,7 +1406,7 @@ PARSER(parse_struct_def) {
|
|||||||
|
|
||||||
const char *ns_pos = pos;
|
const char *ns_pos = pos;
|
||||||
whitespace(&ns_pos);
|
whitespace(&ns_pos);
|
||||||
int64_t ns_indent = sss_get_indent(ctx->file, ns_pos);
|
int64_t ns_indent = get_indent(ctx->file, ns_pos);
|
||||||
ast_t *namespace = NULL;
|
ast_t *namespace = NULL;
|
||||||
if (ns_indent > starting_indent) {
|
if (ns_indent > starting_indent) {
|
||||||
pos = ns_pos;
|
pos = ns_pos;
|
||||||
@ -1421,7 +1421,7 @@ ast_t *parse_enum_def(parse_ctx_t *ctx, const char *pos) {
|
|||||||
// tagged union: enum Foo(a|b(x:Int,y:Int)=5|...) \n namespace
|
// tagged union: enum Foo(a|b(x:Int,y:Int)=5|...) \n namespace
|
||||||
const char *start = pos;
|
const char *start = pos;
|
||||||
if (!match_word(&pos, "enum")) return NULL;
|
if (!match_word(&pos, "enum")) return NULL;
|
||||||
int64_t starting_indent = sss_get_indent(ctx->file, pos);
|
int64_t starting_indent = get_indent(ctx->file, pos);
|
||||||
spaces(&pos);
|
spaces(&pos);
|
||||||
const char *name = get_id(&pos);
|
const char *name = get_id(&pos);
|
||||||
if (!name)
|
if (!name)
|
||||||
@ -1481,7 +1481,7 @@ ast_t *parse_enum_def(parse_ctx_t *ctx, const char *pos) {
|
|||||||
|
|
||||||
const char *ns_pos = pos;
|
const char *ns_pos = pos;
|
||||||
whitespace(&ns_pos);
|
whitespace(&ns_pos);
|
||||||
int64_t ns_indent = sss_get_indent(ctx->file, ns_pos);
|
int64_t ns_indent = get_indent(ctx->file, ns_pos);
|
||||||
ast_t *namespace = NULL;
|
ast_t *namespace = NULL;
|
||||||
if (ns_indent > starting_indent) {
|
if (ns_indent > starting_indent) {
|
||||||
pos = ns_pos;
|
pos = ns_pos;
|
||||||
@ -1636,9 +1636,9 @@ PARSER(parse_use) {
|
|||||||
size_t path_len = strcspn(pos, " \t\r\n;");
|
size_t path_len = strcspn(pos, " \t\r\n;");
|
||||||
if (path_len < 1)
|
if (path_len < 1)
|
||||||
parser_err(ctx, start, pos, "There is no filename here to use");
|
parser_err(ctx, start, pos, "There is no filename here to use");
|
||||||
char *path = heap_strf("%.*s.sss", (int)path_len, pos);
|
char *path = heap_strf("%.*s.nl", (int)path_len, pos);
|
||||||
pos += path_len;
|
pos += path_len;
|
||||||
char *resolved_path = resolve_path(path, ctx->file->filename);
|
char *resolved_path = resolve_path(path, ctx->file->filename, getenv("USE_PATH"));
|
||||||
if (!resolved_path)
|
if (!resolved_path)
|
||||||
parser_err(ctx, start, pos, "No such file exists: \"%s\"", path);
|
parser_err(ctx, start, pos, "No such file exists: \"%s\"", path);
|
||||||
while (match(&pos, ";")) continue;
|
while (match(&pos, ";")) continue;
|
||||||
@ -1670,7 +1670,7 @@ PARSER(parse_inline_block) {
|
|||||||
return NewAST(ctx->file, start, pos, Block, .statements=statements);
|
return NewAST(ctx->file, start, pos, Block, .statements=statements);
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_t *parse_file(sss_file_t *file, jmp_buf *on_err) {
|
ast_t *parse_file(file_t *file, jmp_buf *on_err) {
|
||||||
parse_ctx_t ctx = {
|
parse_ctx_t ctx = {
|
||||||
.file=file,
|
.file=file,
|
||||||
.on_err=on_err,
|
.on_err=on_err,
|
||||||
@ -1691,7 +1691,7 @@ ast_t *parse_file(sss_file_t *file, jmp_buf *on_err) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type_ast_t *parse_type_str(const char *str) {
|
type_ast_t *parse_type_str(const char *str) {
|
||||||
sss_file_t *file = sss_spoof_file("<type>", str);
|
file_t *file = spoof_file("<type>", str);
|
||||||
parse_ctx_t ctx = {
|
parse_ctx_t ctx = {
|
||||||
.file=file,
|
.file=file,
|
||||||
.on_err=NULL,
|
.on_err=NULL,
|
||||||
@ -1710,7 +1710,7 @@ type_ast_t *parse_type_str(const char *str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ast_t *parse_expression_str(const char *str) {
|
ast_t *parse_expression_str(const char *str) {
|
||||||
sss_file_t *file = sss_spoof_file("<expression>", str);
|
file_t *file = spoof_file("<expression>", str);
|
||||||
parse_ctx_t ctx = {
|
parse_ctx_t ctx = {
|
||||||
.file=file,
|
.file=file,
|
||||||
.on_err=NULL,
|
.on_err=NULL,
|
||||||
|
2
parse.h
2
parse.h
@ -6,4 +6,4 @@
|
|||||||
|
|
||||||
type_ast_t *parse_type_str(const char *str);
|
type_ast_t *parse_type_str(const char *str);
|
||||||
ast_t *parse_expression_str(const char *str);
|
ast_t *parse_expression_str(const char *str);
|
||||||
ast_t *parse_file(sss_file_t *file, jmp_buf *on_err);
|
ast_t *parse_file(file_t *file, jmp_buf *on_err);
|
||||||
|
Loading…
Reference in New Issue
Block a user