Skip to content
This repository has been archived by the owner on Jul 27, 2020. It is now read-only.

Commit

Permalink
remove C-Perl-C tunnelling, in favor of modular C objects called from…
Browse files Browse the repository at this point in the history
… Perl _OR_ C-Guile
  • Loading branch information
GeneralGuy4872 committed Oct 9, 2019
1 parent 693a042 commit 9711de6
Show file tree
Hide file tree
Showing 4 changed files with 385 additions and 178 deletions.
111 changes: 54 additions & 57 deletions src/iwannaflycurses.messy
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,23 @@
* other documentation, as well as give a deeper understanding of the
* program because, ya'know, source code.
*
* note to imaginary future packagers: if packaged in binary form, a dummy header might
* still be required to support the obfuscated C syntax that is recommended for use
* with this library. if you don't know what "obfuscated" C is, look at the original
* unix v7 source of ye old bourne shell for the definative example.
* The engine provides the C libraries and Perl modules needed to write a game.
*
* the engine should be compiled as a shared object, and installed according to the
* values set in paths.h
*
* a game compiled for the engine should obey the following conventions:
* - it should provide the bulk of it's functions in a shared library in a private
* application directory
* - it should provide special use functions, such as events, as seperate shared objects,
* to be dynamically loaded at runtime.
* - it should provide special use constants likewise
* blocks of text, however, should be regular nfo or txt
* - it should store any dynamic constants in the savefile, as r<wordsize>, hex, tsv, csv, ini, txt, nfo
* - it should provide at least the following applications (in $PATH) :
* - the game itself
* - a seperate program for generating a new savefile
* - should use (int argc, char *argv[]) to provide bypassing of dotfile,
* path to a non-default dotfile, overrides of race, class, alignment prefs,
* and other flags as desired. parsed by a different parser from the dotfile.
* - a savefile editor
* a game using the engine should provide the following:
* - A newgame initializer perl script
* - Any Guile extensions and shared resources needed by events
* the resource files MUST follow the following naming conventions:
* - .hex or .hex## for packed unsigned byte arrays, where ## is a power of 8
* - .bin or .bin## for packed signed byte arrays, where ## is a power of 8
* - .dat for the custom data format
* - .tsv or .tab for tab seperated values
* - .csv for comma seperated values
* - .asc for a plaintext line-seperated record
* - .txt for a plaintext block of text
* - .ans for an ansi escaped line-seperated record
* - .nfo for an ansi escaped block of text
* - Guile extensions to generate rooms
* - Shared resources used by events
*
* enviromental requirements:
* - UTF-8 terminal of at least 24*80 characters
Expand Down Expand Up @@ -1804,48 +1798,51 @@ enttype *ent_ptr
mapobjtyp *obj_ptr
lightyp *lamp_ptr

/* .r8 : binary data that is organized into 8 bit segments
* .r16 : binary data that is organized into 16 bit segments
* .r32 : binary data that is...you get the picture, right?
* .hex : binary data that is unorganized
* .csv : UTF-8 text record deliminated with commas and line breaks
* .tsv : UTF-8 text record deliminated with tabs and line breaks
* .ini : UTF-8 text record of key=value pairs deliminated with line breaks
* .so : a shared object. a game may use as many of these as it wants. Placing single-use functions in LD_LOAD_PATH is DISCOURAGED; they should be placed in the game's private files.
* .dat : internal data from inside a savefile
* .txt : UTF-8 text document. usually stored in the program's static files, which is CAT-ed to provide dialouge; also used in dumps of primatives
* .nfo : UTF-8 text document (not CP437) containing SGR sequences. otherwise identical to txt.
* .tar.gz : each room is saved as a tar.gz file, as are linked lists and the player
* .tar.bz2 : each plane is saved as a tar.bz2 file.
* .sav : a save file. formatted as a .tar.bz2 file tree
* .man.# : a linux manpage
* .mdoc.# : a bsd manpage
* : documentation
* .html : documentation
* .texinfo : documentation
* .d : everything relating to a struct is stored in the same directory, and pointers to structs are stored as subdirectories with the name of that field. the tail element in a linked list has no subdirectory named "next"; "prev" pointers are "../" implicitly.
* .*rc : a configuration file, parsed with the runcommander
* .dump : a debugger data dump, with a format somwhere between JSON, INI, and C-like pseudocode. essentialy a dat file in readable (and non-raw) format.
/* *.bin : signed binary data that is organized into 8 bit segments
* *.bin# : signed binary data that is organized into n bit segments
* *.hex : unsigned binary data that is organized into 8 bit segments
* *.hex# : unsigned binary data that is organized into n bit segments
* *.csv : UTF-8 text record deliminated with commas and line breaks
* *.tsv : UTF-8 text record deliminated with tabs and line breaks
* *.tab : same as tsv
* *.so : a shared object. a game may use as many of these as it wants. Placing single-use functions in LD_LOAD_PATH is DISCOURAGED; they should be placed in the game's private files.
* *.dat : internal data from inside a savefile
* *.json : a less compact container format that does not allow linking
* *.asc : UTF-8 text record delimenated by newline.
* *.txt : UTF-8 text document. usually stored in the program's static files, which is CAT-ed to provide dialouge; also used in dumps of primatives
* *.ans : UTF-8 text record containing SGR sequences deleminated by newline.
* *.nfo : UTF-8 text document (not CP437) containing SGR sequences. otherwise identical to asc.
* *.tar.gz : each room is saved as a tar.gz file, as are linked lists and the player
* *.tar.bz2 : each plane is saved as a tar.bz2 file.
* *.sav : a save file. formatted as a .tar.bz2 file tree
* *.man.# : a linux manpage
* *.mdoc.# : a bsd manpage
* * : documentation
* *.html : documentation
* *.texinfo : documentation
* *.pod : perl documentation
* *.d : everything relating to a struct is stored in the same directory, and pointers to structs are stored as subdirectories with the name of that field. the tail element in a linked list has no subdirectory named "next"; "prev" pointers are "../" implicitly.
* *.conf : a configuration file, parsed with perl.
* *.*rc : a user's configuration file.
* *.dump : a debugger data dump, with a format somwhere between JSON, INI, and C-like pseudocode. essentialy a dat file in readable (and non-raw) format.
*
* if the following new extensions collide with anything, I will change them. I specifically chose ones that were not a TLA or EFLA to try and avoid this, because there have been TDMTLA since before I came along.
* .midibas : midiBASIC, to be parsed by the midi generator into a .h file. Represents a different subset of general midi than regular midi files, but does so in a human readable format.
*/

/* dat file format:
* BOM ESC ! @ IWannaFLyCurses DataFile NUL = Magic Cookie (no spaces)
* SOH name STX string ETX SEPERATOR = a text field
* SOH name DLE 16bit_length raw_data SEPERATOR = a numeric field
* SOH name ACK SEPERATOR = a boolean field that is true
* SOH name NAK SEPERATOR = a boolean field that is false
* SOH name XON path XOFF SEPERATOR = a pointer to the data at path
* SOH name SUB 8bit ... = array dimension
* an array will consist of either multiple bodys chained together without SEPERATOR or
* SOH name inbetween, or a single pointer to a r# or tsv file
* SOH name SOH name ... = a struct field
* EM = end of data
* SOH name BEL = struct field key
* STX string ETX = an ascii text field
* DLE s8bit raw_data = a numeric field, abs(n) bits long. a negative number indicates the field is signed.
* ACK = true
* NAK = false
* NUL = empty string
* XON path XOFF = a pointer to the data at path
*
* seperator may be one of FS, GS, RS, or US;
* lower levels are used to indicate a suboordinate struct
* SYN = start an array or add a diminsion to the array
* structs are terminated with ETB
* arrays may have up to 4 dimensions seperated with FS GS RS and US.
* arrays are ended with EM
*/

struct mapgen_bordertyp {
Expand Down
28 changes: 19 additions & 9 deletions src/modules/IWannaFly/Macro.pm
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,39 @@ FILTER_ONLY
code => sub { s/NIL/''/g };
FILTER_ONLY
code => sub { s/¤/\$/g };
FILTER_ONLY
code => sub { s/°/\$/g };
FILTER_ONLY
code => sub { s/¢/\$/g };
FILTER_ONLY
code => sub { s/£/\$/g };
FILTER_ONLY
code => sub { s//\$/g };
FILTER_ONLY
code => sub { s/§/\$/g };
FILTER_ONLY
code => sub { s//\$/g };
FILTER_ONLY
code => sub { s/‽(\()?/refaddr$1 /g };
code => sub { s//\$/g };
FILTER_ONLY
code => sub { s/OK(AY)?/0/g };
FILTER_ONLY
code => sub { s/OKAY/0/ig };
FILTER_ONLY
code => sub { s/ERR/-1/ig };
FILTER_ONLY
code => sub { s/«((?!»).*)»[\t]+:\(([\w]+)\)$/$1;\n\tgoto $2;\n/g };
code => sub { s/«((?!»).*)»[\W]*:\(([\w]+)\)$/$1;\n\tgoto $2;\n/g };
FILTER_ONLY
code => sub { s/«((?!»).*)»[\W]*:\{((?!\})\}$/$1;\n\t{$2};\n/g };
FILTER_ONLY
code => sub { s/«((?!»).*)»[\W]*:S\{((?!\}).*)\}\n$/if ( $1 ) {\n\t$2;\n\t}/g };
FILTER_ONLY
code => sub { s/«((?!»).*)»[\W]*:S\(([\w]+)\)\n$/if ( $1 ) {\n\tgoto $2;\n\t}/g };
FILTER_ONLY
code => sub { s/«((?!»).*)»[\W]*:S\{((?!\}).*)\}\n$/unless ( $1 ) {\n\t$2;\n\t}/g };
FILTER_ONLY
code => sub { s/«((?!»).*)»[\W]*:F\(([\w]+)\)\n$/unless ( $1 ) {\n\tgoto $2;\n\t}/g };
FILTER_ONLY
code => sub { s/«((?!»).*)»[\W]*:S\{((?!\}).*)\}F\{((?!\}))\}\n$/if ( $1 ) {\n\t$2;\n\t}\nelse {\n\t$3;\n\t}/g };
FILTER_ONLY
code => sub { s/«((?!»).*)»[\W]*:S\(((?!\)).*)\}F\{((?!\}))\}\n$/if ( $1 ) {\n\tgoto $2;\n\t}\nelse {\n\t$3;\n\t}/g };
FILTER_ONLY
code => sub { s/«((?!»).*)»[\W]*:S\{((?!\}).*)\}F\(((?!\)))\}\n$/if ( $1 ) {\n\t$2;\n\t}\nelse {\n\tgoto $3;\n\t}/g };
FILTER_ONLY
code => sub { s/«((?!»).*)»[\t]+:S\(([\w]+)\)F\(([\w]+)\)\n$/if ( $1 ) {\n\tgoto $2;\n} else {\n\tgoto $3;\n}/g };
code => sub { s/«((?!»).*)»[\W]*:S\(([\w]+)\)F\(([\w]+)\)\n$/if ( $1 ) {\n\tgoto $2;\n\t}\nelse {\n\tgoto $3;\n\t}/g };
FILTER_ONLY
code => sub { s/: int;/: optimize(int);/g };
164 changes: 52 additions & 112 deletions src/modules/IWannaFly/Main.pm
Original file line number Diff line number Diff line change
Expand Up @@ -13,82 +13,58 @@ our @EXPORT;
<!--keep track of what's where in local modules
with :: for directories and ' for files-->

# this program uses tight integration between C and Perl,
# using what I am terming "Black Magic" scalars
# (following the theme of the perl internal docs),
# as they are have the potential to aquire...ultimate power.
#
# the interaction these functions is Thus:
#
# C <+> Perl <+> C
# \________/
#
# The XSUB is able to _leak_ newly created variables back to the
# grandparent C program by throwing them on the heap. in theory.
# It may instead anger the MMU, but there should be ways around this...
# (Thread safety? what's that?)
# I call this tunneling.
#
# These scalars will use special sigils:
#
# £foo is a complicated struct object ref
# ¢foo is a singly, circularly linked list
# €foo is a doubly, half-circularly linked list object
# §foo is a doubly, circularly linked list object
#
# any struct pointer fields are converted to hash objects.
# a Ptr field and a SYNC method will be added to these objects.
#
# Similarly, prev, next, or other pointer fields may be NULL
# (a Filter::Simple macro in IWannaFly'Null, which wrapps the C NULL),
# and ANY field may be undef or absent if it is to be untouched.
# circularly linked list iteration is terminated when
# $HEAD->Ptr == $CURR->next->Ptr
# all other linked list iteration is terminated when
# !$CURR->next
#
# more mundane sigils are also added:
#
# ¤bar is a reference
# °bar is a C pointer
# ♯bar is a bitfield or boolean
# ‽$bar is the refaddr function
#
# all these extra sigils except ‽ are processed to $ by
# Filter::Simple in IWannaFly::Macro. they mearly provide
# disambiguation of special scalars/fields while inspecting code.
# since THEY ARE ALL INTERCHANGEABLE WITH EACHOTHER AND $, their usage
# is akin to a footnote comment that referrs back here.
# when declaring a new ♯, you should use it with ": optimize(int);"
# from optimize::int, or the Filter::Simple macro for it in
# IWannaFly'Macro, which is simply ": int;"
#
# scalars generated from primatives will require a complementery pointer
# to be provided in order to be synced, while this is built in to the
# object resulting from a struct.
#
# modules for providing type support will be provided.
# every type will provide an assciated class.
# they will provide malloc, calloc, new, and fetch(°)
# these must be called by full name.
#
# ::malloc and ::calloc are wrappers for the C functions.
# they create a tunnelable heap object and pass the pointer
#
# ::new creates a blank object
#
# ::fetch(°ptr) creates a hash or scaler from a given °ptr
#
# once an object is created, a ->SYNC method will be created for it,
# which writes to ->Ptr
#
# fields which contain circularly linked lists may call IndexFwd and
# IndexBack on the reference itself to change the object pointed to.
# calling this on a half-circularly linked list will break it.
# calling IndexFwd on a Singly linked list creates a memory leak,
# calling IndexBack on a Singly linked list is a Bad Idea.
#
# free(♯Ptr) is untyped, and provided blessed.
# £foo is a singly linked list object
# ¢fie is a singly, circularly linked list object
# ♮bam is a doubly linked list
# €baz is a doubly, half-circularly linked list
# §qux is a doubly, circularly linked list
# ¤zot is a reference
# ¶xyz is a regex

# Linked lists are provided using objects:
# ->Head is the first element; or an alias of ->Here for ¢ and §
# ->Tail is the last element, or an alias of ->Here->{prev} for §, or the ref whose ->{next} is equal to ->here for ¢
# ->Offset($) element $-offset from ->Head
# ->Here is the currently indexed element
# ->FromHere($) element $-offset from ->Here

# ->Adv advances ->Here by 1
# ->FFwd($) advances ->Here by $
# ->Back rewinds ->Here by 1
# ->Rew($) rewinds ->Here by $
# ->Reset resets ->Here to ->Head.
# ->Set($) set ->Here to ->Head + $.

# ->Push adds a new element after ->Tail
# ->PushHere adds a new element at ->Here
# ->PushAt($) adds a new element at ->Offset($)
# ->PushTo($) adds a new element at ->FromHere($)

# ->Pop removes ->Tail, or the node immidiately before ->Here for §
# ->PopHere removes ->Here
# ->PopAt($) removes ->Offset($)
# ->PopFrom($) removes ->FromHere($)

# ->Punt sends ->Here to ->Tail (Do not pass go do not collect 200 scalars.) Alias of ->Adv for §
# ->PuntAt($) sends ->Offset($) to ->Tail
# ->PuntFrom($) sends ->Fromhere($) to ->Tail, or to before ->Here for §

# The hashes in the objects are maintained as references.

# classes for the objects are:
# IWannaFly::LinkedList::Single
# IWannaFly::LinkedList::SingleCircle
# IWannaFly::LinkedList::Double
# IWannaFly::LinkedList::DoubleHalf
# IWannaFly::LinkedList::DoubleCircle

# each class supports:
# ::new makes an empty container with the methods above
# ::capture(\%) makes a container around a recursive hash, with members named
# ->{next} containing the recursion, as are created by the data file parsers.
# ->{prev} members may be overwritten, and if the formatting does not match,
# this could invoke the halting problem, i.e., capturing a circularly linked
# list with the non-circular class

<!--This is a comment. comments are comments-->

Expand All @@ -104,39 +80,3 @@ push(@EXPORT,'SGN');
sub INTVL($$$) {return MIN( MAX( $_[0],$_[1] ) ,$_[2] )}
push(@EXPORT,'INTVL');

<!-- MOVE THIS
sub DLLIST_NOCIRC_PUSH(€€) {
my (€HEAD,€PUSHY) = @_;
€PUSHY->prev = €HEAD->prev;
€PUSHY->prevptr = €HEAD->prevptr;
€HEAD->prev->next = €PUSHY;
€HEAD->prev->nextptr = €PUSHY->ptr;
€PUSHY->next = undef;
€PUSHY->nextptr = NULL;
€HEAD->prev = €PUSHY;
€HEAD->prevptr = €PUSHY->ptr;
}

sub DLLIST_NOCIRC_FREE(€€) {
my (€HEAD,€DEAD) = @_;
if (‽€HEAD->prev == ‽€DEAD) {
€HEAD->prev = €HEAD->prev->prev;
€HEAD->prev->next = undef;
€HEAD->prev->nextptr = NULL;
}
elsif (addrof(€HEAD) == addrof(§DEAD)) {
unless ((!€HEAD->next) || (€HEAD->next == NULL)) {
€HEAD = €HEAD->next;
€HEAD->prev = €DEAD->prev;
€HEAD->prevptr = €DEAD->prevptr;
}
else {
€DEAD->next->prev = €DEAD->prev;
€DEAD->next->prevptr = €DEAD->prevptr;
€DEAD->prev->next = €DEAD->next;
€DEAD->prev->nextptr = €DEAD->nextptr;
€DEAD->prev->next = €DEAD->next;
}
free(€DEAD);
}
-->
Loading

0 comments on commit 9711de6

Please sign in to comment.