From e11297ccfe04f15193719794b35ce9f8ffa8f1fe Mon Sep 17 00:00:00 2001 From: servostar Date: Sat, 25 May 2024 13:50:21 +0200 Subject: [PATCH] added io library --- lib/CMakeLists.txt | 20 +++++++++++++ lib/def.gem | 38 ++++++++++++++++++++++++ lib/def/def.h | 2 ++ lib/io.gem | 53 +++++++++++++++++++++++++++++++++ lib/io/io.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++ lib/io/io.h | 21 +++++++++++++ lib/std.gem | 2 +- run-lib-build.sh | 30 +++++++++++++++++++ 8 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 lib/CMakeLists.txt create mode 100644 lib/def.gem create mode 100644 lib/io.gem create mode 100644 lib/io/io.c create mode 100644 lib/io/io.h create mode 100755 run-lib-build.sh diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt new file mode 100644 index 0000000..e5aa8cf --- /dev/null +++ b/lib/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.15...3.25) + +project(gemstone_stdlib + VERSION 0.1.0 + DESCRIPTION "gemstone programming language standard library" + LANGUAGES C) + +set(CMAKE_C_STANDARD 23) +set(CMAKE_C_STANDARD_REQUIRED TRUE) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +include_directories(${PROJECT_SOURCE_DIR}) +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/../bin/std") + +# add native module libraries + +file(GLOB_RECURSE STDLIB_IO_SOURCE_FILES io/*.c) +add_library(io ${STDLIB_IO_SOURCE_FILES}) + diff --git a/lib/def.gem b/lib/def.gem new file mode 100644 index 0000000..232d474 --- /dev/null +++ b/lib/def.gem @@ -0,0 +1,38 @@ +# Author: Sven Vogel +# Edited: 25.05.2024 +# License: GPL-2.0 + +# ,----------------------------------------. +# | Standard Type definitions | +# `----------------------------------------` + +# Unsigned integrals + +type unsgined half half int: u8 +type unsgined half int: u16 +type unsgined int: u32 +type unsgined double int: u64 +type unsgined double double int: u128 + +# Signed integrals + +type signed u8: i8 +type signed u16: i16 +type signed u32: i32 +type signed u64: i64 +type signed u128: i128 + +# IEEE-754 floating point + +type signed half float: f16 +type signed float: f32 +type signed double float: f64 +type signed double double float: f128 + +# String constant + +type ref u8: str + +# C style void pointer replacement + +type ref u8: ptr diff --git a/lib/def/def.h b/lib/def/def.h index b1980a9..94ad84d 100644 --- a/lib/def/def.h +++ b/lib/def/def.h @@ -22,4 +22,6 @@ typedef double f64; typedef u8* str; +typedef u8* ptr; + #endif // GEMSTONE_STD_LIB_DEF_H_ diff --git a/lib/io.gem b/lib/io.gem new file mode 100644 index 0000000..bc2c553 --- /dev/null +++ b/lib/io.gem @@ -0,0 +1,53 @@ +# Author: Sven Vogel +# Edited: 25.05.2024 +# License: GPL-2.0 + +# ,----------------------------------------. +# | Generic Input/Output | +# `----------------------------------------` + +import "def.gem" + +# platform specific handle to an I/O device +# can a file, buffer, window or something else +# NOTE: this reference is not meant to be dereferenced +# which can lead to errors and undefined behavior +type ptr: handle + +# Returns a handle to this processes standard input I/O handle +# -- Implementation note +# On Linux this will return 0 as is it convention under UNIX (see: https://www.man7.org/linux/man-pages/man3/stdin.3.html) +# On Windows the library will call `GetStdHandle(STD_INPUT_HANDLE)` +fun getStdinHandle(out handle: stdin) + +# Returns a handle to this processes standard input I/O handle +# -- Implementation note +# On Linux this will return 1 as is it convention under UNIX (see: https://www.man7.org/linux/man-pages/man3/stdout.3.html) +# On Windows the library will call `GetStdHandle(STD_OUTPUT_HANDLE)` +fun getStdoutHandle(out handle: stdout) + +# Returns a handle to this processes standard input I/O handle +# -- Implementation note +# On Linux this will return 1 as is it convention under UNIX (see: https://www.man7.org/linux/man-pages/man3/stderr.3.html) +# On Windows the library will call `GetStdHandle(STD_OUTPUT_HANDLE)` +fun getStderrHandle(out handle: stderr) + +# Write `len` number of bytes from `buf` into the I/O resource specified +# by `dev`. Returns the number of bytes written. +# -- Implementation note +# On Linux this will use the syscall write +# On Windows this will use the WriteFile function +fun writeBytes(in handle: dev, in ref u8: buf, in ref u32: len)(out u32: written) + +# Read atmost `len` bytes to `buf` from the I/O resource specified by `dev` +# Returns the number of read bytes in `written` +# -- Implementation note +# On Linux this will use the syscall read +# On Windows this will use the ReadFile function +fun readBytes(in handle: dev, in ref u8: buf, in ref u32: len)(out u32: read) + +# Flushes the buffers of the I/O resource specified by `dev` +# -- Implementation note +# On Linux this will use the fsync function +# On Windows this will use the FlushFileBuffers function +fun flush(in handle: dev) diff --git a/lib/io/io.c b/lib/io/io.c new file mode 100644 index 0000000..f47dd6f --- /dev/null +++ b/lib/io/io.c @@ -0,0 +1,74 @@ + +#include +#include + +#if defined(_WIN32) || defined (_WIN64) + +// Compile for Windows + +#include + +// FIXME: error in case GetStdHandle return INVALID_HANDLE_VALUE +// FIXME: error in case functions return 0 + +void getStdinHandle(handle* stdin) { + *stdin = (handle) GetStdHandle(STD_INPUT_HANDLE); +} + +void getStdoutHandle(handle* stdout) { + *stdout = (handle) GetStdHandle(STD_OUTPUT_HANDLE); +} + +void getStderrHandle(handle* stderr) { + *stderr = (handle) GetStdHandle(STD_ERROR_HANDLE); +} + +void writeBytes(handle dev, u8* buf, u32 len, u32* bytesWritten) { + WriteFile((HANDLE) dev, buf, len, bytesRead, NULL); +} + +void readBytes(handle dev, u8* buf, u32 len, u32* bytesRead) { + ReadFile((HANDLE) dev, buf, len, bytesRead, NULL); +} + +void flush(handle dev) { + FlushFileBuffers((HANDLE) dev); +} + +#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__linux__) + +// Compile for Linux and BSD + +#include + +// savely cast a 64-bit pointer down to a 32-bit value +// this assumes that 64-bit system will use 32-bit handles +// which are stored as 64-bit by zero extending +#define TO_INT(x) ((int)(long int)(x)) + +void getStdinHandle(handle* stdin) { + *stdin = (handle) STDIN_FILENO; +} + +void getStdoutHandle(handle* stdout) { + *stdout = (handle) STDOUT_FILENO; +} + +void getStderrHandle(handle* stderr) { + *stderr = (handle) STDERR_FILENO; +} + +void writeBytes(handle dev, u8* buf, u32 len, u32* bytesWritten) { + *bytesWritten = write(TO_INT(dev), buf, len); +} + +void readBytes(handle dev, u8* buf, u32 len, u32* bytesRead) { + *bytesRead = read(TO_INT(dev), buf, len); +} + +void flush(handle dev) { + fsync(TO_INT(dev)); +} + + +#endif diff --git a/lib/io/io.h b/lib/io/io.h new file mode 100644 index 0000000..4e00856 --- /dev/null +++ b/lib/io/io.h @@ -0,0 +1,21 @@ + +#ifndef GEMSTONE_STD_LIB_IO_H_ +#define GEMSTONE_STD_LIB_IO_H_ + +#include + +typedef ptr handle; + +void getStdinHandle(handle* stdin); + +void getStdoutHandle(handle* stdout); + +void getStderrHandle(handle* stderr); + +void writeBytes(handle dev, u8* buf, u32 len, u32* written); + +void readBytes(handle dev, u8* buf, u32 len, u32* read); + +void flush(handle dev); + +#endif //GEMSTONE_STD_LIB_IO_H_ diff --git a/lib/std.gem b/lib/std.gem index 402bc1b..8f50d04 100644 --- a/lib/std.gem +++ b/lib/std.gem @@ -7,6 +7,6 @@ # `----------------------------------------` # standard type definitions -import "def/mod.gem" +import "def.gem" diff --git a/run-lib-build.sh b/run-lib-build.sh new file mode 100755 index 0000000..ccca62c --- /dev/null +++ b/run-lib-build.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +# Author: Sven Vogel +# Created: 25.05.2024 +# Description: Builds the standard library into bin/std + +echo "+--------------------------------------+" +echo "| CONFIGURE STD LIBRARY |" +echo "+--------------------------------------+" + +cmake lib +if [ ! $? -eq 0 ]; then + echo "===> failed to configure build" + exit 1 +fi + +echo "+--------------------------------------+" +echo "| BUILD STD LIBRARY |" +echo "+--------------------------------------+" + +cd lib || exit 1 +make -B +if [ ! $? -eq 0 ]; then + echo "===> failed to build standard library" + exit 1 +fi + +echo "+--------------------------------------+" +echo "| successfully build standard library |" +echo "+--------------------------------------+"