1, fix: core dump when multi-include same file in '../examples/complex.c',
authoryu.dongliang <18588496441@163.com>
Mon, 27 Nov 2023 04:52:30 +0000 (12:52 +0800)
committeryu.dongliang <18588496441@163.com>
Mon, 27 Nov 2023 04:52:34 +0000 (12:52 +0800)
2, add some examples

examples/complex.c [new file with mode: 0644]
examples/list_test.c [new file with mode: 0644]
examples/scf_malloc.c [new file with mode: 0644]
examples/string.c [new file with mode: 0644]
lib/scf_complex.c [new file with mode: 0644]
parse/scf_dfa_include.c

diff --git a/examples/complex.c b/examples/complex.c
new file mode 100644 (file)
index 0000000..611e02b
--- /dev/null
@@ -0,0 +1,22 @@
+include "../lib/scf_capi.c";
+include "../lib/scf_complex.c";
+
+int main()
+{
+       complex* c1;
+       complex* c2;
+       complex* c3;
+
+       complex* c0 = create complex(1.0, 2.0);
+
+       c1 = create complex(3.0, 4.0);
+
+       c2 = c0 + c1;
+       c3 = c0 * c1;
+
+       printf("c2: %lf,%lf\n", c2->real, c2->imag);
+       printf("c3: %lf,%lf\n", c3->real, c3->imag);
+
+       return 0;
+}
+
diff --git a/examples/list_test.c b/examples/list_test.c
new file mode 100644 (file)
index 0000000..f5d179c
--- /dev/null
@@ -0,0 +1,39 @@
+include "../lib/scf_list.c";
+include "../lib/scf_capi.c";
+
+struct Data
+{
+       list list;
+       int  a;
+};
+
+int main()
+{
+       Data* d;
+       list  h;
+       int   i;
+
+       list_init(&h);
+
+       for (i = 0; i < 10; i++) {
+               d  = malloc(sizeof(Data));
+
+               d->a = i;
+               list_add_tail(&h, &d->list);
+       }
+
+       list* l;
+
+       for (l = list_head(&h); l != list_sentinel(&h); ) {
+
+               d  = container(l, Data, list);
+               l  = list_next(l);
+
+               printf("%d\n", d->a);
+
+               list_del(&d->list);
+               free(d);
+       }
+
+       return 0;
+}
diff --git a/examples/scf_malloc.c b/examples/scf_malloc.c
new file mode 100644 (file)
index 0000000..bf204b0
--- /dev/null
@@ -0,0 +1,364 @@
+
+int      brk (uint8_t* addr);
+uint8_t* sbrk(uintptr_t inc);
+
+int      printf(const char* fmt, ...);
+
+uint8_t* memset(uint8_t* dst, int c,        uintptr_t n);
+uint8_t* memcpy(uint8_t* dst, uint8_t* src, uintptr_t n);
+
+// min size of block is 64, so low 6 bits can be used for flags
+// flags in prev_size:
+//       Free Last First
+//       2    1    0
+struct scf_mblock_t
+{
+       uintptr_t     magic;
+       uintptr_t     prev_size;
+       uintptr_t     cur_size;
+       uintptr_t     free;
+};
+
+scf_mblock_t*  scf__mblocks[30];
+scf_mblock_t*  scf__free_blocks = NULL;
+uint8_t*       scf__last_brk    = NULL;
+
+uint8_t* scf__malloc(uintptr_t size)
+{
+       scf_mblock_t* b;
+       scf_mblock_t* b2;
+
+       uintptr_t bytes   = (sizeof(scf_mblock_t) + size + 63) >> 6 << 6;
+       intptr_t  nblocks = sizeof(scf__mblocks) / sizeof(scf__mblocks[0]);
+
+       uintptr_t rest;
+       uint8_t*  addr = NULL;
+       uint8_t*  p    = NULL;
+       intptr_t  i;
+
+       for (i = 0; i < nblocks; i++) {
+
+               if ((64 << i) < bytes)
+                       continue;
+
+               if (scf__mblocks[i])
+                       break;
+       }
+
+       if (i == nblocks) {
+
+               uintptr_t pages = (bytes + 4095) >> 12;
+
+               p = sbrk(pages << 12);
+               if (!p)
+                       return NULL;
+               scf__last_brk = p + (pages << 12);
+
+               rest = (pages << 12) - bytes;
+
+               b = (scf_mblock_t*)p;
+
+               b->prev_size = 0x3;
+               b->cur_size  = bytes;
+               b->magic     = 0x10f0;
+       } else {
+               b = scf__mblocks[i];
+               scf__mblocks[i] = (scf_mblock_t*)b->free;
+
+               p = (uint8_t*)b;
+
+               rest = b->cur_size - bytes;
+
+               b->prev_size &= ~0x4;
+               b->magic      = 0x10f0;
+       }
+
+       addr = p + sizeof(scf_mblock_t);
+
+       if (0 == rest) {
+               printf("%s(),%d, b: %p, scf__last_brk: %p\n", __func__, __LINE__, b, scf__last_brk);
+               return addr;
+       }
+
+       p  += bytes;
+       b2  = (scf_mblock_t*)p;
+
+       for (; i >= 0; i--) {
+
+               if (rest >= (64 << i)) {
+                       b2->free = (uintptr_t)scf__mblocks[i];
+                       scf__mblocks[i] = b2;
+                       break;
+               }
+       }
+
+       b ->cur_size  = bytes;
+       b2->cur_size  = rest;
+       b2->prev_size = bytes | 0x4;
+       b2->magic     = 0xf010;
+
+       if (b->prev_size & 0x2) {
+               b->prev_size &= ~0x2;
+               b2->prev_size |= 0x2;
+       }
+
+       printf("%s(),%d, b: %p, scf__last_brk: %p\n", __func__, __LINE__, b, scf__last_brk);
+       return addr;
+}
+
+int scf__free(uint8_t* p)
+{
+       p -= sizeof(scf_mblock_t);
+
+       scf_mblock_t*  b = (scf_mblock_t*)p;
+       scf_mblock_t*  b2;
+       scf_mblock_t*  b3;
+       scf_mblock_t** pb;
+
+       uintptr_t bytes   = b->cur_size;
+       intptr_t  nblocks = sizeof(scf__mblocks) / sizeof(scf__mblocks[0]);
+       intptr_t  i;
+
+       if (b->prev_size & 0x4) {
+               printf("%s(), %d, error: double free: %p\n", __func__, __LINE__, p);
+               return -1;
+       }
+
+       if (0x10f0 != b->magic) {
+               printf("%s(), %d, error: corruption free: %p\n", __func__, __LINE__, p);
+               return -1;
+       }
+
+       b->prev_size |= 0x4;
+       b->magic      = 0xf010;
+
+       while (!(b->prev_size & 0x2)) {
+
+               b2 = (scf_mblock_t*)((uintptr_t)b + bytes);
+
+               uintptr_t bytes2 = b2->cur_size;
+
+               for (i = nblocks - 1; i >= 0; i--) {
+
+                       if (bytes2 >= (64 << i))
+                               break;
+               }
+
+               for (pb = &scf__mblocks[i]; *pb; pb = (scf_mblock_t**)&(*pb)->free) {
+
+                       if (*pb == b2)
+                               break;
+               }
+               if (!*pb)
+                       break;
+
+               *pb = (scf_mblock_t*)b2->free;
+
+               bytes       += bytes2;
+               b->cur_size  = bytes;
+
+               if (b2->prev_size & 0x2)
+                       b->prev_size |= 0x2;
+               else {
+                       b3 = (scf_mblock_t*)((uintptr_t)b2 + bytes2);
+
+                       b3->prev_size = bytes | (b3->prev_size & 0x7);
+               }
+       }
+
+       while (!(b->prev_size & 0x1)) {
+
+               uintptr_t bytes2 = b->prev_size & ~0x7;
+
+               b2 = (scf_mblock_t*)((uintptr_t)b - bytes2);
+
+               bytes2 = b2->cur_size;
+
+               for (i = nblocks - 1; i >= 0; i--) {
+
+                       if (bytes2 >= (64 << i))
+                               break;
+               }
+
+               for (pb = &scf__mblocks[i]; *pb; pb = (scf_mblock_t**)&(*pb)->free) {
+                       if (*pb == b2)
+                               break;
+               }
+               if (!*pb)
+                       break;
+
+               *pb = (scf_mblock_t*)b2->free;
+
+               bytes        += bytes2;
+               b2->cur_size  = bytes;
+
+               if (b->prev_size  &  0x2)
+                       b2->prev_size |= 0x2;
+               else {
+                       b3 = (scf_mblock_t*)((uintptr_t)b2 + bytes);
+
+                       b3->prev_size = bytes | (b3->prev_size & 0x7);
+               }
+
+               b = b2;
+       }
+
+       bytes = b->cur_size;
+
+       if (0x7 == (b->prev_size) & 0x7) {
+
+               if (scf__last_brk == (uint8_t*)b + bytes) {
+
+                       printf("%s(), %d, b: %p, scf__last_brk: %p\n", __func__, __LINE__, b, scf__last_brk);
+                       scf__last_brk = (uint8_t*)b;
+                       brk((uint8_t*)b);
+
+                       int flag = 1;
+                       while (flag) {
+                               flag = 0;
+
+                               pb = &scf__free_blocks;
+                               while (*pb) {
+
+                                       b = *pb;
+                                       bytes = b->cur_size;
+
+                                       if (scf__last_brk != (uint8_t*)b + bytes) {
+
+                                               pb = (scf_mblock_t**)&b->free;
+                                               continue;
+                                       }
+                                       *pb = (scf_mblock_t*)b->free;
+
+                                       printf("%s(), %d, b: %p, scf__last_brk: %p\n", __func__, __LINE__, b, scf__last_brk);
+                                       scf__last_brk = (uint8_t*)b;
+                                       brk((uint8_t*)b);
+                                       flag = 1;
+                               }
+                       }
+               } else {
+                       b->free = (uintptr_t)scf__free_blocks;
+                       scf__free_blocks = b;
+                       printf("%s(), %d, b: %p\n", __func__, __LINE__, b);
+               }
+               return 0;
+       }
+
+       for (i = nblocks - 1; i >= 0; i--) {
+               if (bytes >= (64 << i))
+                       break;
+       }
+
+       b->free = (uintptr_t)scf__mblocks[i];
+       scf__mblocks[i] = b;
+
+       printf("%s(), %d, b: %p\n", __func__, __LINE__, b);
+       return 0;
+}
+
+uint8_t* scf__calloc(uintptr_t n, uintptr_t size)
+{
+       scf_mblock_t*  b;
+       uintptr_t      bytes;
+       uint8_t*       p;
+
+       size *= n;
+
+       p = scf__malloc(size);
+       if (!p)
+               return NULL;
+
+       b = (scf_mblock_t*)(p - sizeof(scf_mblock_t));
+
+       bytes  = b->cur_size;
+       bytes -= sizeof(scf_mblock_t);
+       printf("%s(),%d, calloc, b: %p, bytes: %ld\n", __func__, __LINE__, b, bytes);
+
+       memset(p, 0, bytes);
+
+       return p;
+}
+
+uint8_t* scf__realloc(uint8_t* p, uintptr_t size)
+{
+       scf_mblock_t*  b;
+       scf_mblock_t*  b2;
+       scf_mblock_t*  b3;
+       uintptr_t      bytes;
+       uint8_t*       p2;
+
+       b = (scf_mblock_t*)(p - sizeof(scf_mblock_t));
+
+       bytes  = b->cur_size;
+       bytes -= sizeof(scf_mblock_t);
+
+       if (bytes < size) {
+               p2 = scf__malloc(size);
+               if (!p2)
+                       return NULL;
+
+               memcpy(p2, p, bytes);
+               scf__free(p);
+
+               printf("%s(), %d, realloc: %p->%p, size: %ld\n", __func__, __LINE__, p, p2, size);
+               return p2;
+       }
+
+       size   = (sizeof(scf_mblock_t) + 63 + size) >> 6 << 6;
+       bytes +=  sizeof(scf_mblock_t);
+
+       if (bytes < size + 64)
+               return p;
+
+       b2 = (scf_mblock_t*)((uintptr_t)b + size);
+
+       b ->cur_size = size;
+       b2->cur_size = bytes - size;
+
+       if (b->prev_size & 0x2) {
+               b->prev_size &= ~0x2;
+               b2->prev_size = size | 0x2;
+       } else {
+               b3 = (scf_mblock_t*)((uintptr_t)b + bytes);
+
+               b2->prev_size = size;
+               b3->prev_size = (bytes - size) | (b3->prev_size & 0x7);
+       }
+
+       b2->magic = 0x10f0;
+
+       p2 = (uint8_t*)b2 + sizeof(scf_mblock_t);
+       scf__free(p2);
+
+       printf("%s(), %d, realloc: %p, free b2: %p, size: %ld\n", __func__, __LINE__, p, p2, size);
+       return p;
+}
+
+int main()
+{
+       uint8_t* p0 = scf__malloc(1000);
+       uint8_t* p1 = scf__malloc(1320);
+       uint8_t* p2 = scf__malloc(2510);
+       uint8_t* p3 = scf__malloc(4510);
+       uint8_t* p4 = scf__malloc(510);
+       uint8_t* p5 = scf__malloc(6510);
+       uint8_t* p6 = scf__malloc(510);
+       uint8_t* p7 = scf__malloc(11510);
+
+       scf__free(p0);
+
+       *p1 = 1;
+       scf__free(p1);
+
+       *p2 = 2;
+       *p4 = 4;
+
+       scf__free(p4);
+       scf__free(p5);
+       scf__free(p2);
+       scf__free(p6);
+       scf__free(p3);
+
+       scf__free(p7);
+       return 0;
+}
diff --git a/examples/string.c b/examples/string.c
new file mode 100644 (file)
index 0000000..81b522b
--- /dev/null
@@ -0,0 +1,136 @@
+include "../lib/scf_capi.c";
+
+struct string
+{
+       uint8_t* data;
+       int64_t  len;
+       int64_t  capacity;
+
+       int __init(string* this)
+       {
+               this->data = scf__auto_malloc(16);
+               if (!this->data)
+                       return -1;
+
+               this->data[0]  = '\0';
+               this->capacity = 16;
+               this->len      = 0;
+
+               return 0;
+       }
+
+       int __init(string* this, const char* s)
+       {
+               int64_t len = strlen(s);
+
+               this->data = scf__auto_malloc(len + 1);
+               if (!this->data)
+                       return -1;
+
+               memcpy(this->data, s, len);
+
+               this->data[len] = '\0';
+               this->capacity  = len;
+               this->len       = len;
+
+               return 0;
+       }
+
+       int __init(string* this, const char* s, int64_t len)
+       {
+               this->data = scf__auto_malloc(len + 1);
+               if (!this->data)
+                       return -1;
+
+               memcpy(this->data, s, len);
+
+               this->data[len] = '\0';
+               this->capacity  = len;
+               this->len       = len;
+
+               return 0;
+       }
+
+       int operator+=(string* this, string* that)
+       {
+               int64_t len = this->len + that->len;
+
+               if (len >= this->capacity) {
+                       uint8_t* p = scf__auto_malloc(len + 16);
+                       if (!p)
+                               return -1;
+
+                       memcpy(p, this->data, this->len);
+
+                       this->data = p;
+                       this->capacity = len + 15;
+               }
+
+               memcpy(this->data + this->len, that->data, that->len);
+
+               this->data[len] = '\0';
+               this->len       = len;
+
+               return 0;
+       }
+
+       string*, int operator+(string* this, string* that)
+       {
+               string* s;
+
+               s = create string();
+               if (!s)
+                       return NULL, -1;
+
+               int64_t len = this->len + that->len;
+
+               if (s->len < len) {
+                       s->data = scf__auto_malloc(len + 1);
+                       if (!s->data)
+                               return NULL, -1;
+               }
+
+               memcpy(s->data,  this->data, this->len);
+               memcpy(s->data + this->len,  that->data, that->len);
+
+               s->data[len] = '\0';
+               s->capacity  = len;
+               s->len       = len;
+
+               return s, 0;
+       }
+
+       int operator==(string* this, string* that)
+       {
+               if (this->len < that->len)
+                       return -1;
+               else if (this->len > that->len)
+                       return 1;
+               return memcmp(this->data, that->data, this->len);
+       }
+
+       void __release(string* this)
+       {
+               if (this->data)
+                       scf__auto_freep(&this->data, NULL);
+       }
+};
+
+int main()
+{
+       string* s0;
+       string* s1;
+       string* s2;
+       string* s3;
+       int err;
+
+       s0 = "hello";
+       s1 = " world";
+
+       s2 = s0 + s1;
+       s3 = "hello";
+
+       printf("### s0 == s3: %d, s0->data: %s, s2: %s\n", s0 == s3, s0->data, s2->data);
+       return 0;
+}
+
diff --git a/lib/scf_complex.c b/lib/scf_complex.c
new file mode 100644 (file)
index 0000000..430b600
--- /dev/null
@@ -0,0 +1,141 @@
+
+include "../lib/scf_capi.c";
+
+struct complex
+{
+       double real;
+       double imag;
+
+       int __init(complex* this, double real, double imag)
+       {
+               this->real = real;
+               this->imag = imag;
+               return 0;
+       }
+
+       int operator+=(complex* this, complex* that)
+       {
+               if (!this || !that)
+                       return -1;
+
+               this->real += that->real;
+               this->imag += that->imag;
+               return 0;
+       }
+
+       int operator-=(complex* this, complex* that)
+       {
+               if (!this || !that)
+                       return -1;
+
+               this->real -= that->real;
+               this->imag -= that->imag;
+               return 0;
+       }
+
+       int operator*=(complex* this, complex* that)
+       {
+               if (!this || !that)
+                       return -1;
+
+               double a = this->real;
+               double b = this->imag;
+               double c = that->real;
+               double d = that->imag;
+
+               this->real = a * c - b * d;
+               this->imag = a * d + b * c;
+               return 0;
+       }
+
+       int operator/=(complex* this, complex* that)
+       {
+               if (!this || !that)
+                       return -1;
+
+               double a = this->real;
+               double b = this->imag;
+               double c = that->real;
+               double d = that->imag;
+
+               this->real = (a * c + b * d) / (c * c + d * d);
+               this->imag = (b * c - a * d) / (c * c + d * d);
+               return 0;
+       }
+
+       complex*, int operator+(complex* this, complex* that)
+       {
+               if (!this || !that)
+                       return NULL, -1;
+
+               complex* res;
+
+               res = create complex(0.0, 0.0);
+               if (!res)
+                       return NULL, -1;
+
+               res->real = this->real + that->real;
+               res->imag = this->imag + that->imag;
+               return res, 0;
+       }
+
+       complex*, int operator-(complex* this, complex* that)
+       {
+               if (!this || !that)
+                       return NULL, -1;
+
+               complex* res;
+
+               res = create complex(0.0, 0.0);
+               if (!res)
+                       return NULL, -1;
+
+               res->real = this->real - that->real;
+               res->imag = this->imag - that->imag;
+               return res, 0;
+       }
+
+       complex*, int operator*(complex* this, complex* that)
+       {
+               if (!this || !that)
+                       return NULL, -1;
+
+               complex* res;
+
+               res = create complex(0.0, 0.0);
+               if (!res)
+                       return NULL, -1;
+
+               double a = this->real;
+               double b = this->imag;
+               double c = that->real;
+               double d = that->imag;
+
+               res->real = a * c - b * d;
+               res->imag = a * d + b * c;
+               return res, 0;
+       }
+
+       complex*, int operator/(complex* this, complex* that)
+       {
+               if (!this || !that)
+                       return NULL, -1;
+
+               complex* res;
+
+               res = create complex(0.0, 0.0);
+               if (!res)
+                       return NULL, -1;
+
+               double a = this->real;
+               double b = this->imag;
+               double c = that->real;
+               double d = that->imag;
+
+               res->real = (a * c + b * d) / (c * c + d * d);
+               res->imag = (b * c - a * d) / (c * c + d * d);
+               return res, 0;
+       }
+};
+
+
index acfe16c697b15a24813e5963be70b0095bdf7da8..1367eeaf410de1e5d363ad3fa5b9fcc9a9b1b8e1 100644 (file)
@@ -41,7 +41,8 @@ static int _include_action_path(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                return SCF_DFA_ERROR;
        }
 
-       scf_lex_close(parse->lex);
+       if (parse->lex)
+               scf_lex_close(parse->lex);
 
        parse->lex = lex;
        parse->ast->current_block = cur;