Skip to content

Commit

Permalink
Add C rand24
Browse files Browse the repository at this point in the history
  • Loading branch information
bbrk24 committed Nov 25, 2023
1 parent 6696153 commit b1b8a6c
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. See [Keep a

### Added

- RND (`$`) now works in compiled programs, though backed by a different source of randomness.
- GDT and GTM (`D` and `T`) now work in compiled programs.

## [1.6.2] - 2023-11-21
Expand Down
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,6 @@ When using the `-c` flag, the input program will be translated into C code. The

If the `-a` flag is additionally specified, the output program will use `getchar` and `putchar` for the `GTC` and `PTC` opcodes respectively. Otherwise, the output program will convert between UTF-8 and UTF-32 the same way the interpreter does.

Compiled programs cannot use multiple threads, and at this time cannot use the `RND`, `GTM`, and `GDT` opcodes.

## Sample programs

Here are some simple programs I've written.
Expand Down
12 changes: 10 additions & 2 deletions src/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ void compiler::write_state(std::ostream& os) {

os << header;

if (std::any_of(m_fragments->cbegin(), m_fragments->cend(), [](const auto& v) {
return std::any_of(v->begin(), v->end(), [](const auto& i) {
return i.m_op == instruction::operation::RND;
});
})) {
os << "srand(time(NULL));";
}

for (size_t i = 0; i < m_fragments->size(); ++i) {
const std::vector<instruction>& frag = *m_fragments->at(i);
for (size_t j = 0; j < frag.size(); ++j) {
Expand Down Expand Up @@ -138,8 +146,8 @@ 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);
os << "lws_push(stack, rand24());";
return;
case op::GDT:
os << "lws_push(stack, get_date());";
return;
Expand Down
32 changes: 32 additions & 0 deletions src/compiler/lightweight_stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,36 @@ static inline int32_t get_date() {
time_t t = time(NULL);
return (int32_t)(t / SECS_PER_DAY);
}

static inline int32_t rand24() {
#if RAND_MAX >= 0x00ffffff
#if (RAND_MAX | (RAND_MAX >> 1)) == RAND_MAX
return (int32_t)(rand() << 8) >> 8;
#else
// Unlikely, but not difficult
int x;
do {
x = rand();
} while (x > 0x00ffffff);
return (int32_t)(x << 8) >> 8;
#endif
#else
// RAND_MAX is [0x00007fff, 0x00ffffff)
// Uhh just use twelve bits from each call
#if (RAND_MAX | (RAND_MAX >> 1)) == RAND_MAX
int lowTwelve = rand() & 0x0fff;
int highTwelve = rand() & 0x0fff;
#else
// :(
int lowTwelve, highTwelve;
do {
lowTwelve = rand();
} while (lowTwelve > 0x0fff);
do {
highTwelve = rand();
} while (highTwelve > 0x0fff);
#endif
return (((int32_t)highTwelve << 20) | ((int32_t)lowTwelve << 8)) >> 8;
#endif
}
//)"

0 comments on commit b1b8a6c

Please sign in to comment.