bitwise: add progress on ion
This commit is contained in:
parent
d67ca84c45
commit
e779c77d32
|
@ -45,3 +45,4 @@ misc/kf/kf
|
||||||
*.bin
|
*.bin
|
||||||
blue-pill/*/*.d
|
blue-pill/*/*.d
|
||||||
core
|
core
|
||||||
|
bitwise/ion/ion
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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
|
Loading…
Reference in New Issue