From 6696153a1c9e13c631d83776c332cef38ffafd3f Mon Sep 17 00:00:00 2001 From: William Baker Date: Tue, 21 Nov 2023 21:46:25 -0500 Subject: [PATCH] add C time funcs --- CHANGELOG.md | 4 ++++ src/compiler.cpp | 8 ++++++-- src/compiler/lightweight_stack.h | 28 ++++++++++++++++++++++++---- trgc.sh | 2 +- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9e3dc21..3e4c781d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. See [Keep a ## Unreleased +### Added + +- GDT and GTM (`D` and `T`) now work in compiled programs. + ## [1.6.2] - 2023-11-21 ### Fixed diff --git a/src/compiler.cpp b/src/compiler.cpp index a2b1aad9..d0c65327 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -138,10 +138,14 @@ void compiler::get_c_code(const instruction& i, std::ostream& os, bool assume_as return; } case op::RND: + cerr << "Random number generation is not yet supported for compiled programs." << endl; + exit(EXIT_FAILURE); case op::GDT: + os << "lws_push(stack, get_date());"; + return; case op::GTM: - cerr << "Nondeterministic instructions are not yet supported for compiled programs." << endl; - exit(EXIT_FAILURE); + os << "lws_push(stack, get_time());"; + return; case op::EXP: os << "lws_push(stack, 1 << (lws_pop(stack) + 8) >> 8);"; return; diff --git a/src/compiler/lightweight_stack.h b/src/compiler/lightweight_stack.h index 16be9971..08488bd9 100644 --- a/src/compiler/lightweight_stack.h +++ b/src/compiler/lightweight_stack.h @@ -3,6 +3,7 @@ R"( #include #include #include +#include #ifndef __GNUC__ #define __builtin_expect(exp, c) exp @@ -53,7 +54,8 @@ static inline void lws_deinit(const lws stack) { free(stack->base); } -#define INVALID_CHAR 0xfffd +static const int32_t INVALID_CHAR = 0xfffd; + // Basically copied from parse_unichar in string_processing.hh static inline int32_t get_unichar() { unsigned char buf[4]; @@ -91,6 +93,8 @@ static inline int32_t get_unichar() { case 4: return ((buf[0] & 0x07) << 18) | ((buf[1] & 0x3f) << 12) | ((buf[2] & 0x3f) << 6) | (buf[3] & 0x3f); } + // Should be unreachable but the compiler doesn't know better + return INVALID_CHAR; } static inline void print_unichar(int32_t c) { @@ -98,13 +102,29 @@ static inline void print_unichar(int32_t c) { putchar(c); } else if (c <= 0x07ff) { char buffer[] = { 0xc0 | (c >> 6), 0x80 | (c & 0x3f), 0 }; - printf(buffer); + printf("%s", buffer); } else if (c <= 0xffff) { char buffer[] = { 0xe0 | (c >> 12), 0x80 | ((c >> 6) & 0x3f), 0x80 | (c & 0x3f), 0 }; - printf(buffer); + printf("%s", buffer); } else { char buffer[] = { 0xf0 | (c >> 18), 0x80 | ((c >> 12) & 0x3f), 0x80 | ((c >> 6) & 0x3f), 0x80 | (c & 0x3f), 0 }; - printf(buffer); + printf("%s", buffer); } } + +static const time_t SECS_PER_DAY = 86400; + +static inline int32_t get_time() { + struct timespec ts; + timespec_get(&ts, TIME_UTC); + const float UNITS_PER_NSEC = 9.709036e-8F; + const float UNITS_PER_SEC = 97.09036F; + float value = UNITS_PER_SEC * (float)(ts.tv_sec % SECS_PER_DAY) + UNITS_PER_NSEC * (float)ts.tv_nsec; + return (int32_t)value; +} + +static inline int32_t get_date() { + time_t t = time(NULL); + return (int32_t)(t / SECS_PER_DAY); +} //)" diff --git a/trgc.sh b/trgc.sh index a373faf2..d3059c4c 100755 --- a/trgc.sh +++ b/trgc.sh @@ -1,5 +1,5 @@ #!/bin/bash set -euo pipefail -./trilangle -c "$@" | "${CC:-gcc}" -o ./trg.out -xc - +./trilangle -c "$@" | tee out.c | "${CC:-gcc}" -o ./trg.out -xc - ./trg.out