libpulsar
A modular compiler for the pulsar programming language
Loading...
Searching...
No Matches
tstream.c
Go to the documentation of this file.
1// Copyright (C) 2023 Ethan Uppal. All rights reserved.
2
3#include "tstream_short.h"
4#include "error/error.h" // ps_error et al.
5#include "util/arena.h" // ast_sprintf
6#include "util/io.h" // ps_file_ctx
7
8inline void ps_tstream_init(struct ps_tstream* ts,
9 const struct ps_token_arr* tokens, const struct ps_file_ctx* file_ctx) {
10 ts->index = 0;
11 ts->tokens = tokens;
12 ts->file_ctx = file_ctx;
13}
14
15inline bool ps_tstream_is_eof(struct ps_tstream* ts) {
16 return ts->index >= ts->tokens->length;
17}
18
19inline struct ps_token* ps_tstream_current(struct ps_tstream* ts) {
20 return eof() ? NULL : (struct ps_token*)&ts->tokens->contents[ts->index];
21}
22
23inline void ps_tstream_advance_n(struct ps_tstream* ts, isize n) {
24 ts->index += n;
25}
26
28 enum ps_token_type type) {
29 if (ts->index + n < ts->tokens->length) {
30 const struct ps_token* token = &ts->tokens->contents[ts->index + n];
31 return token->type == type ? (struct ps_token*)token : NULL;
32 }
33 return NULL;
34}
35
37 enum ps_token_type type, STR ctx) {
38 struct ps_token* current = tcur();
39
40 // handle end of file
41 if (!current) {
42 ps_tstream_eof_error(ts, -1, ctx,
43 ast_sprintf("Expected '%s' here", ps_token_type_to_string(type)));
44 return NULL;
45 }
46
47 // consume the token
49
50 // handle mismatch
51 if (current->type != type) {
52 ps_error(PS_SCOPE_ERROR, PS_ECODE_UNEXPECTED_TKN, ts->file_ctx->buffer,
53 current->loc, current->length,
54 ast_sprintf("Unexpected token %s", ctx),
55 ast_sprintf("Expected '%s' here, received '%s' instead",
58 NULL);
59 return NULL;
60 }
61
62 return current;
63}
64
65#define _PS_MATCH_N_ERROR_FIX_MSG \
66 ast_sprintf("Expected one of %zu options here, received '%s' instead", \
67 count, ps_token_type_to_string(current->type))
68
70 enum ps_token_type types[], usize count, STR ctx) {
71 struct ps_token* current = tcur();
72
73 // handle end of file
74 if (!current) {
75 ps_tstream_eof_error(ts, -1, ctx,
76 ast_sprintf("Expected one of %zu options here", count));
77 return NULL;
78 }
79
80 // consume the token
82
83 // check for match
84 for (usize i = 0; i < count; i++) {
85 if (current->type == types[i]) {
86 return current;
87 }
88 }
89
90 // handle mismatch
91 ps_error(PS_SCOPE_ERROR, PS_ECODE_UNEXPECTED_TKN, ts->file_ctx->buffer,
92 current->loc, current->length, ast_sprintf("Unexpected token %s", ctx),
94 return NULL;
95}
96
97#undef _PS_MATCH_N_ERROR_FIX_MSG
98
99void ps_tstream_eof_error(struct ps_tstream* ts, int code, STR ctx, STR fix) {
100 ps_assert(ts->tokens->length > 0, "precondition");
101
102 // use last token
103 const struct ps_token* token =
104 &ts->tokens->contents[ts->tokens->length - 1];
105
106 ps_error(PS_SCOPE_ERROR, code == -1 ? PS_ECODE_UNEXPECTED_TKN : code,
107 ts->file_ctx->buffer, token->loc, token->length,
108 ast_sprintf("Unexpected end of file %s", ctx), fix, NULL);
109}
#define ps_assert(cond, msg)
Asserts the given condition cond, aborting via ps_abort with the given msg otherwise.
Definition abort.h:53
Defines an arena allocator for the compiler.
#define ast_sprintf(fmt,...)
Definition arena.h:77
#define STR
Definition def.h:40
#define isize
Definition def.h:49
#define usize
Definition def.h:50
Error reporting and displaying utilities.
Defines safe file I/O functions.
Represents an error or source-referencing display message.
Definition error.h:43
Information captured in a file necessary for effective info/error reporting.
Definition io.h:15
char * buffer
Definition io.h:17
Represents a token.
Definition token.h:34
usize length
Definition token.h:38
enum ps_token_type type
Definition token.h:36
struct ps_loc loc
Definition token.h:35
Processes tokens in a stream.
Definition tstream.h:16
usize index
inv: 0 < index <= tokens->length.
Definition tstream.h:18
const struct ps_token_arr * tokens
The tokens in the stream.
Definition tstream.h:21
const struct ps_file_ctx * file_ctx
The file context for the stream.
Definition tstream.h:24
STR ps_token_type_to_string(enum ps_token_type type)
Returns: the string representation of the given token type type.
Definition token.c:13
ps_token_type
The type of a token.
Definition token.h:18
void ps_tstream_eof_error(struct ps_tstream *ts, int code, STR ctx, STR fix)
Reports an end-of-file error with the given context ctx, using the last token in ts for location.
Definition tstream.c:99
struct ps_token * ps_tstream_match(struct ps_tstream *ts, enum ps_token_type type, STR ctx)
Attempts to match the next token with the given token type.
Definition tstream.c:36
#define _PS_MATCH_N_ERROR_FIX_MSG
Definition tstream.c:65
void ps_tstream_init(struct ps_tstream *ts, const struct ps_token_arr *tokens, const struct ps_file_ctx *file_ctx)
Points tstream to the first token in tokens and reads from it there on.
Definition tstream.c:8
bool ps_tstream_is_eof(struct ps_tstream *ts)
Whether tstream has no more tokens.
Definition tstream.c:15
struct ps_token * ps_tstream_current(struct ps_tstream *ts)
The current token in tstream.
Definition tstream.c:19
struct ps_token * ps_tstream_peek(struct ps_tstream *ts, usize n, enum ps_token_type type)
If the nth next token in ts is of the given type, returns it.
Definition tstream.c:27
struct ps_token * ps_tstream_match_any(struct ps_tstream *ts, enum ps_token_type types[], usize count, STR ctx)
Attempts to match the next token with one of the given token types.
Definition tstream.c:69
void ps_tstream_advance_n(struct ps_tstream *ts, isize n)
Advances tstream to its nth next token.
Definition tstream.c:23
#define ps_tstream_advance(tstream)
Advances tstream the next token.
Definition tstream.h:51
#define tcur()
#define eof()