bitwise: add progress on ion

This commit is contained in:
Kyle Isom 2018-03-23 15:25:46 -07:00
parent d67ca84c45
commit e779c77d32
4 changed files with 80 additions and 32 deletions

1
.gitignore vendored
View File

@ -45,3 +45,4 @@ misc/kf/kf
*.bin *.bin
blue-pill/*/*.d blue-pill/*/*.d
core core
bitwise/ion/ion

View File

@ -1,6 +1,6 @@
TARGET := ion TARGET := ion
OBJS := $(TARGET).o OBJS := $(TARGET).o
CFLAGS := -g -std=c99 CFLAGS := -g -std=c99 -Wall -Werror
all: $(TARGET) all: $(TARGET)

View File

@ -1,10 +1,11 @@
#include <assert.h> #include <assert.h>
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#define MAX(a, b) a < b ? b : a #define MAX(a, b) ((a) < (b) ? (b) : (a))
// stretchy buffers // stretchy buffers
typedef struct _BufHeader { typedef struct _BufHeader {
@ -13,54 +14,91 @@ typedef struct _BufHeader {
char buf[0]; // C99 char buf[0]; // C99
} BufHeader; } BufHeader;
#define buf__hdr(b) (BufHeader *)((char *)buf - offsetof(BufHeader, buf)) void *buf__grow(const void *, size_t, size_t);
#define buf_fits(b, n) ((buf_len(b) + n) <= buf_cap(b)) #define buf__hdr(b) ((BufHeader *)((char *)(b) - offsetof(BufHeader, buf)))
#define buf__fit(b, n) (buf__fits(b, n) ? 0 : (b) = (buf_grow(b, 2*buf_cap(b), sizeof(*b)))) #define buf__fits(b, n) ((buf_len(b) + n) <= buf_cap(b))
#define buf__fit(b, n) (buf__fits(b, n) ? 0 : ((b) = (buf__grow((b), buf_len(b) + (n), sizeof(*(b))))))
#define buf_len(b) ((b) ? buf__hdr(b)->len : 0) #define buf_len(b) ((b) ? buf__hdr(b)->len : 0)
#define buf_cap(b) ((b) ? buf__hdr(b)->cap : 0) #define buf_cap(b) ((b) ? buf__hdr(b)->cap : 0)
#define buf_push(b, x) (buf__fit((b), 1), (b)[buf_len(b)++] = (x)) #define buf_push(b, x) (buf__fit((b), 1), (b)[buf_len((b))] = (x), buf__hdr((b))->len++)
#define buf_free(b) ((b) ? free(buf__hdr((b))) : 0)
#define prlu(m, v) (printf("%s: %lu\n", m, (unsigned long)(v)))
void * void *
buf__grow(const void *buf, size_t nlen, size_t esize) buf__grow(const void *buf, size_t nlen, size_t esize)
{ {
size_t ncap = MAX(1 + 2*buf_cap(buf), new_len); size_t ncap = MAX(1 + 2*buf_cap(buf), nlen);
assert(nlen <= ncap); assert(nlen <= ncap);
size_t nsize = ncap * esize; size_t nsize = offsetof(BufHeader, buf) + ncap * esize;
BufHdr *nhdr; BufHeader *nhdr;
if (buf) { if (buf) {
nhdr = realloc(buf__hdr(buf), nsize) nhdr = realloc(buf__hdr(buf), nsize);
} }
else { else {
nhdr = malloc(new_size) nhdr = malloc(nsize);
nhdr->len = 0; nhdr->len = 0;
} }
nhdr.cap = ncap; nhdr->cap = ncap;
return nhdr; return nhdr->buf;
}
static void
buf_test(void)
{
int *stretchy = NULL;
for (int i = 0; i < 1024; i++) {
buf_push(stretchy, i);
}
for (int i = 0; i < buf_len(stretchy); i++) {
assert(stretchy[i] == i);
}
buf_free(stretchy);
printf("OK\n");
}
typedef enum TokenKind {
TOKEN_INT,
TOKEN_NAME,
// ...
} TokenKind;
typedef struct Token {
TokenKind kind;
// ...
} Token;
Token token;
void next_token(void) {
switch (*stream) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
while (isdigit(*stream)) {
stream++;
}
token.kind = TOKEN_INT;
break;
default:
token.kind = *stream;
break;
}
} }
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
int *buf = NULL; buf_test();
buf_push(buf, 47); // std::vector::push_back
// now buf actually points to a buffer
buf_push(buf, 1234);
printf("buf length: %lu / cap: %lu\n",
(unsigned long)buf_len(buf),
(unsigned long)buf_cap(buf));
for (int i = 0; i < buf_len(buf); i++) {
printf("%d\n", buf[i]);
}
for (int i = 0; i < 1024; i++) {
buf_push(buf, i+1);
}
printf("buf length: %lu / cap: %lu\n", buf_len(buf), buf_cap(buf));
buf_free(buf);
return 0; return 0;
} }

View File

@ -8,4 +8,13 @@ NOTES
stretch buffers: stretch buffers:
+ dynamically growable arrays such that with a few pitfalls but is easy to generate + dynamically growable arrays such that with a few pitfalls but is easy to generate
+ invented by stb? + invented by stb?
2018-03-22 (day 2)
------------------
+ lexing: char stream to token stream
+ ex. '1234 (x+y)' translates to '1234' '(' 'x' '+' 'y' ')'
+ no semantics yet
+ simple hand-written approach
+ mark: 1:06:11