Skip to content

Commit

Permalink
Add TRDS, currently only age of the universe supported
Browse files Browse the repository at this point in the history
  • Loading branch information
cwesson committed Aug 19, 2023
1 parent 10ff472 commit 270077e
Show file tree
Hide file tree
Showing 21 changed files with 129 additions and 64 deletions.
6 changes: 1 addition & 5 deletions src/Defunge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,11 +211,7 @@ Defunge::Error Defunge::peekCommand(std::istringstream& iss){
iss >> c;
if(c == 0){
for(size_t j = 0; j < stack->size(); ++j){
std::cout << "[0] ";
for(size_t i = stack->at(j).size(); i > 0; --i){
std::cout << stack->at(j).get(i) << " ";
}
std::cout << std::endl;
std::cout << stack->at(j) << std::endl;
}
}else{
size_t s = 0;
Expand Down
19 changes: 7 additions & 12 deletions src/Field.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,25 +259,20 @@ void Field::put(const Vector& p, inst_t v){
field.erase(find);
}
for(size_t i = 0; i < p.size(); ++i){
if(maxs[i] == p[i]){
// scan for new max
dim_t max = std::numeric_limits<dim_t>::min() ;
for(auto s = field.cbegin(); s != field.cend(); ++s){
if(s->first[i] > max){
max = s->first[i];
}
}
maxs[i] = max;
}
if(mins[i] == p[i]){
// scan for new min
if(maxs[i] == p[i] || mins[i] == p[i]){
// scan for new min/max
dim_t min = std::numeric_limits<dim_t>::max();
dim_t max = std::numeric_limits<dim_t>::min() ;
for(auto s = field.cbegin(); s != field.cend(); ++s){
if(s->first[i] < min){
min = s->first[i];
}
if(s->first[i] > max){
max = s->first[i];
}
}
mins[i] = min;
maxs[i] = max;
}
}
}else{
Expand Down
2 changes: 2 additions & 0 deletions src/FingerprintStrategy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "FingerprintSTRN.h"
#include "FingerprintSUBR.h"
#include "FingerprintTOYS.h"
#include "FingerprintTRDS.h"
#include "FungeUniverse.h"
#include <filesystem>

Expand Down Expand Up @@ -91,6 +92,7 @@ Fingerprint* FingerprintStrategy::loadBuiltin(uint64_t fingerprint){
case 0x5354524E: fing = new FingerprintSTRN(runner); break;
case 0x53554252: fing = new FingerprintSUBR(runner); break;
case 0x544F5953: fing = new FingerprintTOYS(runner); break;
case 0x54524453: fing = new FingerprintTRDS(runner); break;
case FingerprintDynamic::ID:
if(runner.getUniverse().getCreator() != nullptr){
fing = new FingerprintDynamic(runner, runner.getUniverse().getCreator());
Expand Down
6 changes: 2 additions & 4 deletions src/FishStrategy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ FungeError FishStrategy::instructionDiv(){
double x = pop(TOP);
double y = pop(TOP);
if(x == 0){
return ERROR_UNSPEC;
return ERROR_DIV0;
}
push(TOP, y / x);
return ERROR_NONE;
Expand All @@ -236,7 +236,7 @@ FungeError FishStrategy::instructionModu(){
stack_t x = pop(TOP);
stack_t y = pop(TOP);
if(x == 0){
return ERROR_UNSPEC;
return ERROR_DIV0;
}
push(TOP, y % x);
return ERROR_NONE;
Expand Down Expand Up @@ -511,8 +511,6 @@ FungeError FishStrategy::errorHandler(FungeError e){
return ERROR_NONE;
}
[[fallthrough]];
case ERROR_NOTAVAIL:
case ERROR_UNSPEC:
[[unlikely]] default:
std::cerr << "something smells fishy..." << std::endl;
runner.getUniverse().killAll(1);
Expand Down
3 changes: 0 additions & 3 deletions src/FungeRunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,6 @@ void FungeRunner::tick(){
break;
case ERROR_BLOCK:
break;
case ERROR_UNIMP:
case ERROR_NOTAVAIL:
case ERROR_UNSPEC:
[[unlikely]] default:
getUniverse().getDebugger().trap(*this);
if(errorHandler != nullptr){
Expand Down
56 changes: 32 additions & 24 deletions src/FungeUniverse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
namespace Funge {

FungeUniverse::FungeUniverse(std::istream& file, Field::FileFormat fmt, const FungeConfig& cfg):
age(0),
running(true),
exitcode(0),
config(cfg),
Expand All @@ -31,6 +32,7 @@ FungeUniverse::FungeUniverse(std::istream& file, Field::FileFormat fmt, const Fu
}

FungeUniverse::FungeUniverse(const FungeConfig& cfg):
age(0),
running(true),
exitcode(0),
config(cfg),
Expand All @@ -56,9 +58,9 @@ FungeUniverse::~FungeUniverse(){

std::lock_guard<std::mutex> guard(mutex);
while(threads.size() > 0){
std::thread* thread = threads.front();
thread->join();
delete thread;
std::thread* native = threads.front();
native->join();
delete native;
}
while(runners.size() > 0){
FungeRunner* runner = runners.front();
Expand Down Expand Up @@ -96,8 +98,8 @@ void FungeUniverse::addRunner(FungeRunner* runner){
std::lock_guard<std::mutex> guard(mutex);
runner->setMode(config.mode);
if(config.threads == THREAD_NATIVE){
std::thread* thread = new std::thread(std::ref(*runner));
threads.push(thread);
std::thread* native = new std::thread(std::ref(*runner));
threads.push(native);
}
runners.push_back(runner);
semaphore.release();
Expand All @@ -109,40 +111,42 @@ void FungeUniverse::operator()(){
if(config.threads == THREAD_NATIVE){
mutex.lock();
while(threads.size() > 0){
std::thread* thread = threads.front();
if(thread->joinable()){
std::thread* native = threads.front();
if(native->joinable()){
mutex.unlock();
thread->join();
native->join();
mutex.lock();
}
threads.pop();
delete thread;
delete native;
}
mutex.unlock();
}else{
mutex.lock();
while(runners.size() > 0){
FungeRunner* thread = runners.front();
for(auto it = runners.begin(); it != runners.end(); ){
FungeRunner* runner = *it;

mutex.unlock();
if(thread->isRunning()){
thread->tick();
}
mutex.lock();
mutex.unlock();
if(runner->isRunning()){
runner->tick();
}
mutex.lock();

runners.pop_front();
if(&thread->getUniverse() == this){
if(thread->isRunning()){
runners.push_back(thread);
if(&runner->getUniverse() == this){
if(runner->isRunning()){
++it;
}else{
debug.endThread(*runner);
it = runners.erase(it);
}
}else{
debug.endThread(*thread);
delete thread;
cv.notify_all();
it = runners.erase(it);
}
}else{
cv.notify_all();
}
++age;
}
cv.notify_all();
mutex.unlock();
}
}
Expand Down Expand Up @@ -251,6 +255,10 @@ FungeMode FungeUniverse::getMode() const {
return config.mode;
}

size_t FungeUniverse::getAge() const {
return age;
}

bool FungeUniverse::isMode(FungeMode m) const {
return !!(config.mode & m);
}
Expand Down
8 changes: 8 additions & 0 deletions src/Stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,12 @@ void Stack::setMode(FungeMode m){
mode = m;
}

std::ostream& operator<<(std::ostream& os, const Stack& rhs){
os << "[0] ";
for(auto i : rhs.stack){
os << i << " ";
}
return os;
}

}
4 changes: 2 additions & 2 deletions src/Unefunge98Strategy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ FungeError Unefunge98Strategy::instructionUnder(){
}
}
}else{
ret = ERROR_UNSPEC;
ret = ERROR_NOSTACK;
}
return ret;
}
Expand Down Expand Up @@ -228,7 +228,7 @@ FungeError Unefunge98Strategy::instructionEnd(){
}
stack.pop();
}else{
ret = ERROR_UNSPEC;
ret = ERROR_NOSTACK;
}

if(runner.isMode(FUNGE_MODE_SWITCH)){
Expand Down
27 changes: 27 additions & 0 deletions src/fingerprint/FingerprintTRDS.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* @file FingerprintTRDS.cpp
* IP travel in time and space.
* @author Conlan Wesson
*/

#include "FingerprintTRDS.h"
#include "FungeUniverse.h"

namespace Funge {

FingerprintTRDS::FingerprintTRDS(FungeRunner& r) :
Fingerprint(r, {'P'})
{}

FungeError FingerprintTRDS::execute(inst_t cmd){
switch(cmd){
case 'P':{
stack.top().push(runner.getUniverse().getAge());
} break;
default:
return ERROR_UNIMP;
}
return ERROR_NONE;
}

}
21 changes: 21 additions & 0 deletions src/fingerprint/include/FingerprintTRDS.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* @file FingerprintTRDS.h
* IP travel in time and space.
* @author Conlan Wesson
*/

#pragma once

#include "Fingerprint.h"

namespace Funge {

class FingerprintTRDS : public Fingerprint {
public:
explicit FingerprintTRDS(FungeRunner& r);
virtual ~FingerprintTRDS() = default;

virtual FungeError execute(inst_t cmd) override;
};

}
4 changes: 2 additions & 2 deletions src/include/FingerprintStrategy.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#include "FungeStrategy.h"
#include "Fingerprint.h"
#include <map>
#include <unordered_map>
#include <stack>

namespace Funge {
Expand All @@ -30,7 +30,7 @@ class FingerprintStrategy : public FungeStrategy {
std::string intToStr(uint64_t i);
void activate(Fingerprint* fing);

std::map<uint64_t, Fingerprint*> available;
std::unordered_map<uint64_t, Fingerprint*> available;
std::vector<uint64_t> loaded;
};

Expand Down
4 changes: 2 additions & 2 deletions src/include/FungeStateNormal.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include "FungeState.h"
#include "FungeStrategy.h"
#include "FungeSemantic.h"
#include <map>
#include <unordered_map>
#include <stack>

namespace Funge {
Expand All @@ -29,7 +29,7 @@ class FungeStateNormal : public FungeState {
FungeStateNormal& operator=(const FungeStateNormal&) = delete;

protected:
std::map<inst_t, std::stack<FungeSemantic*>> semantics;
std::unordered_map<inst_t, std::stack<FungeSemantic*>> semantics;
};

}
2 changes: 2 additions & 0 deletions src/include/FungeUniverse.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ class FungeUniverse {
void clearMode(FungeMode m);
void toggleMode(FungeMode m);
FungeMode getMode() const;
size_t getAge() const;
bool isMode(FungeMode m) const;
bool allowConcurrent() const;
bool allowExecute() const;
Expand All @@ -124,6 +125,7 @@ class FungeUniverse {
bool invertHL() const;

private:
size_t age;
bool running;
int exitcode;
FungeConfig config;
Expand Down
6 changes: 6 additions & 0 deletions src/include/Stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <cstddef>
#include <list>
#include <mutex>
#include <ostream>

namespace Funge {
class StackStack;
Expand Down Expand Up @@ -85,6 +86,11 @@ class Stack {
* @note FUNGE_MODE_INVERT pushes to the bottom of the stack.
*/
void setMode(FungeMode m);

/**
* Output stream operator.
*/
friend std::ostream& operator<<(std::ostream& os, const Stack& rhs);

private:
FungeMode mode;
Expand Down
5 changes: 4 additions & 1 deletion src/include/funge_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,12 @@ enum FungeError {
ERROR_NONE, ///< No error.
ERROR_SKIP, ///< Skip instruction.
ERROR_BLOCK, ///< Instruction blocked.
ERROR_UNIMP, ///< Unimplemented unstruction.
ERROR_UNIMP, ///< Unimplemented instruction.
ERROR_NOTAVAIL, ///< Feature not available.
ERROR_UNSPEC, ///< General execution error.
ERROR_DIV0, ///< Divide by zero.
ERROR_EMPTY, ///< Not enough elements in stack.
ERROR_NOSTACK, ///< Stack does not exist.
};

}
8 changes: 4 additions & 4 deletions src/util/include/FishUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@
/**
* Check if a stack exists.
* @param _s Stack index.
* @warning Returns ERROR_UNSPEC from the current function if the check fails.
* @warning Returns ERROR_NOSTACK from the current function if the check fails.
*/
#define check_selected(_s) if((_s) >= stack.size()) { return ERROR_UNSPEC; }
#define check_selected(_s) if((_s) >= stack.size()) { return ERROR_NOSTACK; }


/**
* Check if a stack exists and has enough elements.
* @param _s Stack index.
* @param _n Number of elements.
* @warning Returns ERROR_UNSPEC from the current function if the check fails.
* @warning Returns ERROR_EMPTY from the current function if the check fails.
*/
#define check_stack(_s, _n) if(stack._s().size() < (_n)) { return ERROR_UNSPEC; }
#define check_stack(_s, _n) if(stack._s().size() < (_n)) { return ERROR_EMPTY; }
Loading

0 comments on commit 270077e

Please sign in to comment.