From 61b4f7fb29db2e8f8af266fcb0836b6b9232245a Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Sun, 31 Jan 2021 22:08:01 +0200 Subject: Initial commit --- stdlib/stdlib.h | 14 ++++++++++ stdlib/stdlib/console.cc | 28 ++++++++++++++++++++ stdlib/string.cc | 26 ++++++++++++++++++ stdlib/string.h | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ stdlib/types.h | 30 +++++++++++++++++++++ 5 files changed, 167 insertions(+) create mode 100644 stdlib/stdlib.h create mode 100644 stdlib/stdlib/console.cc create mode 100644 stdlib/string.cc create mode 100644 stdlib/string.h create mode 100644 stdlib/types.h (limited to 'stdlib') diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h new file mode 100644 index 0000000..3e6619d --- /dev/null +++ b/stdlib/stdlib.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +class Console { +public: + virtual void write(const String &msg) = 0; +}; + +void console_set(Console *ptr); + +void printk(const String &msg); + +__attribute__((__noreturn__)) void abort(); diff --git a/stdlib/stdlib/console.cc b/stdlib/stdlib/console.cc new file mode 100644 index 0000000..dbc9b86 --- /dev/null +++ b/stdlib/stdlib/console.cc @@ -0,0 +1,28 @@ +#include "stdlib.h" + +static Console *global_console = nullptr; + +void console_set(Console *ptr) { + if (ptr != nullptr) { + global_console = ptr; + } +} + +void printk(const String &msg) { + if (global_console == nullptr) + return; + + global_console->write(msg); +} + +void abort() { + /* + * On gcc, a 'while(true) {}' will infinitely loop + * but clang will optimize it away on -O2 if it's empty + * therefore, add no-op + */ + while (true) { + asm volatile("nop"); + } + __builtin_unreachable(); +} diff --git a/stdlib/string.cc b/stdlib/string.cc new file mode 100644 index 0000000..5cd4bb2 --- /dev/null +++ b/stdlib/string.cc @@ -0,0 +1,26 @@ +#include "string.h" + +// TODO + +// int strcpy(char *dst, const char *stc); +// void strcat(void *dst, const void *src); +// char* strncpy(char *dest, const char *src, int length); +// int strncmp(const char *s1, const char *s2, int c); + +/* strcmp - compare two C-strings */ +constexpr int strcmp(const char *s1, const char *s2) +{ + const auto s1_len = strlen(s1); + for(size_t i = 0; i < s1_len; ++i) { + if(s1[i] == s2[i]) continue; + if(s1[i] > s2[i]) return 1; + if(s1[i] < s2[i]) return -1; + } + return 0; +} + +static_assert(strcmp("one", "one") == 0); +static_assert(strcmp("one", "two") < 0); +static_assert(strcmp("foo", "bar") > 0); + + diff --git a/stdlib/string.h b/stdlib/string.h new file mode 100644 index 0000000..deb6fde --- /dev/null +++ b/stdlib/string.h @@ -0,0 +1,69 @@ +#pragma once +#include "types.h" + +constexpr size_t strlen(const char *str) { + int len = 0; + while (str[len]) + ++len; + return len; +} + +/* reverse: reverse string s in place */ +constexpr void reverse(char s[]) { + int i, j; + char c; + + for (i = 0, j = strlen(s) - 1; i < j; i++, j--) { + c = s[i]; + s[i] = s[j]; + s[j] = c; + } +} + +/* itoa: convert n to characters in s */ +template constexpr void itoa(int n, char s[]) { + int i, sign; + + if ((sign = n) < 0) /* record sign */ + n = -n; /* make n positive */ + + i = 0; + do { /* generate digits in reverse order */ + s[i++] = "0123456789abcdef"[n % base]; /* get next digit */ + } while ((n /= base) > 0); /* delete it */ + + if (sign < 0) + s[i++] = '-'; + + s[i] = '\0'; + + reverse(s); +} + +class String { +public: + class Iterator { + friend class String; + + public: + char next() { return p->buffer[pos++]; } + operator bool() const { return (pos < p->m_length); } + + private: + Iterator(const String *s) : p(s) {} + + size_t pos = 0; + const String *p; + }; + + friend class Iterator; + + String(const char *d) : buffer{d}, m_length{strlen(d)} {} + String(const char *d, size_t l) : buffer{d}, m_length{l} {} + + Iterator begin() const { return Iterator(this); } + +private: + const char *const buffer; + const size_t m_length; +}; diff --git a/stdlib/types.h b/stdlib/types.h new file mode 100644 index 0000000..0818342 --- /dev/null +++ b/stdlib/types.h @@ -0,0 +1,30 @@ +#pragma once + +typedef unsigned short size_t; +static_assert(sizeof(size_t) >= 2); + + +typedef unsigned char uint8_t; +static_assert(sizeof(uint8_t) == 1); + +typedef unsigned short uint16_t; +static_assert(sizeof(uint16_t) == 2); + +typedef unsigned int uint32_t; +static_assert(sizeof(uint32_t) == 4); + +//typedef unsigned long uint64_t; +//static_assert(sizeof(uint64_t) == 8); + + +typedef char int8_t; +static_assert(sizeof(int8_t) == 1); + +typedef short int16_t; +static_assert(sizeof(int16_t) == 2); + +typedef int int32_t; +static_assert(sizeof(int32_t) == 4); + +//typedef long int64_t; +//static_assert(sizeof(int64_t) == 8); -- cgit v1.2.1