├── LICENCE ├── cmd-help.txt ├── defs.h ├── docs ├── DISCUSSION └── README ├── help.txt ├── include ├── _end_shared.h ├── _shared_lib.h ├── algorithm ├── assert.h ├── cassert ├── cctype ├── classlib.h ├── climits ├── cmath ├── cstddef ├── cstdio ├── cstdlib ├── cstring ├── ctime ├── ctype.h ├── dirent.h ├── fnmatch.h ├── for.h ├── for_each.h ├── foreach2.h ├── fstream ├── fstream.h ├── ftw.h ├── glib.h ├── io.h ├── iostream ├── iostream.h ├── limits.h ├── list ├── list.new ├── listx ├── malloc.h ├── map ├── math.h ├── old-string ├── regexp.h ├── rx++.h ├── sstream ├── stdarg.h ├── stddef.h ├── stdio.h ├── stdlib.h ├── string ├── string.h ├── strstrea.h ├── strstream.h ├── sys │ ├── stat.h │ └── types.h ├── time.h ├── turtle.h ├── uc │ └── dir.h ├── uc_except.h ├── uc_save.h ├── uc_timer.h ├── ucri.h ├── ucri │ ├── persist.h │ ├── profile.h │ ├── refs.h │ ├── trace.h │ └── utils.h ├── utility ├── vector ├── vector.h ├── windows.h ├── wininet.h └── winuser.h ├── lib ├── self.imp ├── string_imp.cpp └── string_imp.h ├── linenoise-LICENCE ├── readme.md ├── src ├── breakpoints.cpp ├── breakpoints.h ├── class.cpp ├── class.h ├── classlib.h ├── code.cpp ├── code.h ├── common.cpp ├── common.h ├── config.h ├── configure ├── directcall.cpp ├── directcall.h ├── dissem.cpp ├── dll_entry.cpp ├── eh.h ├── engine.cpp ├── engine.h ├── engine.patch ├── entry.h ├── errors.cpp ├── errors.h ├── ex_fscanf.cpp ├── ex_vfscanf.cpp ├── ex_vfscanf.h ├── export.h ├── expressions.cpp ├── expressions.h ├── fblock.h ├── function.cpp ├── function.h ├── function_match.cpp ├── function_match.h ├── hard_except.cpp ├── hard_except.h ├── imports.cpp ├── imports.h ├── input.h ├── keywords.cpp ├── keywords.h ├── lakefile ├── lexer.cpp ├── linenoise.c ├── linenoise.h ├── loaded_module_list.h ├── main.cpp ├── main.h ├── makefile ├── makefile.in ├── mangle.cpp ├── mangle.h ├── mingw.mak ├── module.h ├── mstring.cpp ├── mstring.h ├── msvc.mak ├── new-defs.h ├── opcodes.h ├── operators.cpp ├── operators.h ├── ops.h ├── os.cpp ├── os.h ├── parser.h ├── parser.y ├── program.cpp ├── program.h ├── signature.h ├── stack.h ├── std_utils.h ├── subst.cpp ├── table.cpp ├── table.h ├── templates.cpp ├── templates.h ├── threads.cpp ├── threads.h ├── tokens.cpp ├── tokens.h ├── tparser.cpp ├── tparser.h ├── types.cpp ├── types.h ├── uc_tokens.cpp ├── uc_tokens.h ├── ucri.cpp ├── ucri.h ├── underc.man ├── utils.cpp ├── utils.h ├── version.h ├── xnames.awk └── xtrace.h └── verify ├── atexit.cpp ├── attrib.cpp ├── attrib.h ├── defs.h ├── except1.cpp ├── first.htm ├── first_c.htm ├── html.cpp ├── html.h ├── out.txt ├── t1.txt ├── t1c.txt ├── t2.txt ├── t2c.txt ├── t3.txt ├── t3c.txt ├── tag.cpp ├── tag.h ├── tests.cpp ├── xml.cpp └── xml.h /cmd-help.txt: -------------------------------------------------------------------------------- 1 | UnderC Command-line Options (available with --help) 2 | 3 | ucc { } 4 | 5 | Defaults to interactive mode if there's no source file specified; 6 | reads C++ definitions from defs.h, looking first in current directory 7 | and then in the UnderC home directory. 8 | 9 | -H Override UC_HOME 10 | 11 | -I Add an include path 12 | 13 | -D = Add a preprocessor macro 14 | 15 | -r Run in specified directory 16 | 17 | -T If a typedef is available for a complex type, use it in any error 18 | 19 | -i Force interactive mode, even if there is a source file specified 20 | 21 | -W Suppress linker warnings 22 | 23 | -R Switch on array checking on builtin arrays and vector<> 24 | 25 | -P Switch on pointer checking 26 | 27 | -F Attempt to optimize by inlining one-instruction functions 28 | 29 | -v Version 30 | 31 | --help This text 32 | -------------------------------------------------------------------------------- /defs.h: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | -------------------------------------------------------------------------------- /docs/README: -------------------------------------------------------------------------------- 1 | How to build UnderC 2 | 3 | Currently the version of UnderC working under Linux is console-mode only, 4 | unlike the Win32 version. Some of those Windows-only files are along for the 5 | ride, but aren't needed. You will need a reasonably fresh C++ compiler for 6 | this build to work; I'm using G++ 2.96. Old versions of GCC like 2.7 will not 7 | make the grade because of the extensive use of namespaces. 8 | 9 | By default this build makes a non-statically linked executable using the 10 | readline library for command editing. 'make STATIC=1' will build a static 11 | executable, but for some curious reason the O1 optimization level causes 12 | trouble. O1 is fine for the dynamically linked version, although O2 breaks 13 | the verification suite. After setting UC_HOME to the directory where the 14 | build took place, you can test UnderC by going up into the verify 15 | subdirectory and typing '../ucc tests.cpp', which should just print out 'ok'. 16 | Compared to the Win32 version, this verification suite does cause some 17 | problems. By the final test in tests.cpp, there seems to be some corruption 18 | and an attempt to open a text file results in the console being opened instead. 19 | This is puzzling but I leave it as an issue for more experienced Linux 20 | people to explore. 21 | 22 | I've included the C++ file generated by Bison from the grammar file parser.y, 23 | which is tparser.cpp. The makefile has a rule to generate this from parser.y 24 | except that I had some difficulty with using the bison.simple that came with 25 | the Linux Bison 1.24. (At least that's what --version said: the comment at 26 | the top of the output says 1.28). This is all probably due to the grammar 27 | being very stressed and full of conflicts. So use the environment variable 28 | BISON_SIMPLE to override the usual place for bison.simple (on my system it's 29 | usually /usr/lib; your mileage may vary) and use the bison.simple which I 30 | have included, which comes from the Win32 version of Bison 1.24. 31 | 32 | Getting this going on other unixes should be straightforward except that I am 33 | depending on the GCC predefined macro __linux__ to discriminate between 34 | Win32 and the rest. The idea is to keep any OS-specific stuff in os.cpp, 35 | hard_except.cpp, and directcall.cpp. This last file is where you would have 36 | to write a little bit of inline assembly to connect the stack engine with 37 | native routines. If anybody can do this in standard C++, then I would be 38 | most grateful. 39 | 40 | Please see the DISCUSSION document for more background on the code. 41 | 42 | Steve Donovan, 43 | December 2001 44 | 45 | -------------------------------------------------------------------------------- /help.txt: -------------------------------------------------------------------------------- 1 | UnderC Command Summary (available with #help) 2 | 3 | #q Quit session 4 | 5 | #ql Quit session, writing log file 6 | 7 | The temp file is of the form - 8 | 9 | #log Write to 10 | 11 | Currently only available in the Win32 GUI version (WCON) 12 | 13 | #cd Change current directory 14 | 15 | #pwd Show current directory 16 | 17 | #l Load 18 | 19 | #r Run current program 20 | 21 | This must have previously been loaded with #l 22 | 23 | #lib Load 24 | 25 | Any class declarations and function prototypes are 26 | then imported from the specified shared library or DLL. 27 | An optional import file can be used when linking DLLs without 28 | symbolic imformation. 29 | 30 | To end importing, it's important to say #lib (without a parm) 31 | Note: this is exactly the same as #pragma dlink 32 | 33 | #alias Create an Alias for a Command 34 | 35 | Aliases are defined like #define macros, but only substitute 36 | the first token on the line, and pick up their arguments 37 | separated by spaces. Commands or preprocessor directives can 38 | occur in the definition, and will be separated out; # has its 39 | usual meaning as the stringizing and token-pasting operators. 40 | 41 | For example, 42 | #alias cd(x) @cd x @pwd 43 | #alias D(obj,y,z) obj->set(y,z); 44 | #alias L(f) @include #f 45 | 46 | So the command "cd /test" is equivalent to 47 | #cd /test 48 | #pwd 49 | and 'D p 10 20' expands to 'p->set(10,20)' 50 | 51 | #opt Set Options 52 | 53 | For example, #opt t+ v+ 54 | 55 | o- Auto Dissemble 56 | t- Function Trace 57 | v- Verbose Mode 58 | s- Strict Mode (no implicit bool conversions) 59 | p- Pointer Check 60 | a- Access Control 61 | c- Strip Prompt when Copying (WCON only) 62 | C- C mode 63 | T- Use typedef names if possible 64 | L- Suppress Link Errors 65 | 66 | The 'use typedefs' option is an interesting UnderC feature where 67 | the compiler tries to use any defined typedefs instead of long 68 | complex type names. For example, if you have typedef'd IntMap 69 | to be map, then that type will appear as IntMap 70 | in any error messages. 71 | 72 | #lv Display all local variables 73 | 74 | #d Display Variable 75 | 76 | #v Information on Variable or Function 77 | 78 | #u Dissemble Function 79 | 80 | #rm Remove Symbol or Program 81 | 82 | With 'main' as a parameter, removes the program. 83 | 84 | #s Stop Program 85 | 86 | #mod List Modules, or Position of Function 87 | 88 | Without a parameter, lists all loaded modules 89 | If given a function name, gives the file name and line number 90 | 91 | #types List Types 92 | 93 | Can be given wildcards of the form pat* or *pat 94 | 95 | #funs List Functions 96 | 97 | Can be given wildcards of the form pat* or *pat 98 | 99 | #gt Set Temporary Breakpoint at 100 | 101 | #b Set Breakpoint at 102 | 103 | #bs List Breakpoints in 104 | 105 | This can also be used to set a number of breakpoints in a file, 106 | when they have already been set with #b. The new line numbers 107 | follow the file name 108 | 109 | #ff Set Frame 110 | 111 | #mc Clear All Macros 112 | 113 | This will also clean out the global namespace. -------------------------------------------------------------------------------- /include/_end_shared.h: -------------------------------------------------------------------------------- 1 | // Used to end a set of declarations involving a shared library 2 | // I've put this in its own header (see <_begin_shared.h>) since 3 | // we will probably change this to a special #pragma 4 | #lib 5 | -------------------------------------------------------------------------------- /include/_shared_lib.h: -------------------------------------------------------------------------------- 1 | // _shared_lib.h 2 | // UnderC Pocket C++ Library, Steve Donovan 2001. 3 | // *note: there's no #elif yet! 4 | #ifdef __win32__ 5 | #lib msvcrt40.dll 6 | #else 7 | #ifdef __linux__ 8 | #lib libc.so.6 9 | #else 10 | #lib libc.so 11 | #endif 12 | #endif 13 | -------------------------------------------------------------------------------- /include/assert.h: -------------------------------------------------------------------------------- 1 | // assert.h 2 | // UnderC Development Project, Steve Donovan, 2001 3 | #ifndef __ASSERT_H 4 | #define __ASSERT_H 5 | // 1.2.7 Now uses , __LINE__, and respects NDEBUG 6 | #include 7 | 8 | #define AS_STR(s) #s 9 | 10 | #ifndef NDEBUG 11 | #define assert(expr) if (!(expr)) \ 12 | __assert(#expr,__FILE__ ,__LINE__) 13 | #else 14 | #define assert(expr) 15 | #endif 16 | 17 | inline void __assert(char *expr, char* file, int line) 18 | { 19 | fprintf(stderr,"assertion failed %s %d %s\n",file,line,expr); 20 | //exit(-1); 21 | } 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /include/cassert: -------------------------------------------------------------------------------- 1 | #ifndef _STD_CASSERT 2 | #define _STD_CASSERT 3 | 4 | #include 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /include/cctype: -------------------------------------------------------------------------------- 1 | #ifndef _STD_CCTYPE 2 | #define _STD_CCTYPE 3 | namespace std { 4 | #include 5 | } 6 | #endif 7 | -------------------------------------------------------------------------------- /include/classlib.h: -------------------------------------------------------------------------------- 1 | // UnderC Development Project, 2001 2 | // standard library includes (default) 3 | #define __UC__ 4 | #include 5 | #include 6 | #ifndef _CONSOLE 7 | #include 8 | #endif 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | -------------------------------------------------------------------------------- /include/climits: -------------------------------------------------------------------------------- 1 | #ifndef _STD_CASSERT 2 | #define _STD_CASSERT 3 | 4 | #include 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /include/cmath: -------------------------------------------------------------------------------- 1 | #ifndef _STD_CMATH 2 | #define _STD_CMATH 3 | 4 | namespace std 5 | { 6 | #include 7 | }; 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /include/cstddef: -------------------------------------------------------------------------------- 1 | #ifndef _STD_CSTDDEF 2 | #define _STD_CSTDDEF 3 | 4 | #include 5 | 6 | namespace std { 7 | using size_t; 8 | } 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /include/cstdio: -------------------------------------------------------------------------------- 1 | #ifndef _STD_CSTDIO 2 | #define _STD_CSTDIO 3 | 4 | #include 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /include/cstdlib: -------------------------------------------------------------------------------- 1 | namespace std { 2 | 3 | #include 4 | 5 | } 6 | 7 | 8 | -------------------------------------------------------------------------------- /include/cstring: -------------------------------------------------------------------------------- 1 | #ifndef _STD_CSTRING 2 | #define _STD_CSTRING 3 | 4 | namespace std 5 | { 6 | #include 7 | }; 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /include/ctime: -------------------------------------------------------------------------------- 1 | #ifndef _STD_CTIME 2 | #define _STD_CTIME 3 | 4 | namespace std 5 | { 6 | #include 7 | }; 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /include/ctype.h: -------------------------------------------------------------------------------- 1 | // UnderC Development Project, 2001 2 | #ifndef __cctype_H 3 | #define __cctype_H 4 | #include <_shared_lib.h> 5 | extern "C" { 6 | int isalpha(int); 7 | int isalnum(int); 8 | int isdigit(int); 9 | int isspace(int); 10 | int isprint(int); 11 | char toupper(int); 12 | char tolower(int); 13 | int ispunct(int); 14 | int isupper(int); 15 | int isxdigit(int); 16 | int islower(int); 17 | int iscntrl(int); 18 | int isgraph(int); 19 | } 20 | #include <_end_shared.h> 21 | #endif 22 | -------------------------------------------------------------------------------- /include/dirent.h: -------------------------------------------------------------------------------- 1 | /* dirent.h 2 | */ 3 | #ifndef _DIRENT_H 4 | #define _DIRENT_H 5 | 6 | typedef unsigned int __ino_t; 7 | typedef unsigned int __off_t; 8 | 9 | // UC defaults to 32-bit alignment in structures 10 | #pragma pack(1) 11 | 12 | // this is implementation-dependent - POSIX only guarantees d_name 13 | struct dirent 14 | { 15 | __ino_t d_ino; 16 | __off_t d_off; 17 | unsigned short int d_reclen; 18 | unsigned char d_type; 19 | char d_name[256]; 20 | }; 21 | 22 | #pragma pack(4) 23 | 24 | typedef int DIR; 25 | 26 | #include <_shared_lib.h> 27 | extern "C" { 28 | DIR *opendir(const char *name); 29 | int closedir(DIR *dir); 30 | dirent *readdir(DIR *dir); 31 | } 32 | #lib 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /include/fnmatch.h: -------------------------------------------------------------------------------- 1 | /* fnmatch.h 2 | */ 3 | #ifndef _FNMATCH_H 4 | #define _FNMATCH_H 5 | 6 | #include <_shared_lib.h> 7 | extern "C" { 8 | int fnmatch(const char *pat, const char *str, int flags); 9 | } 10 | 11 | enum { 12 | FNM_PATHNAME = 1 << 0, 13 | FNM_NOESCAPE = 1 << 1, 14 | FNM_PERIOD = 1 << 2, 15 | FNM_LEADING_DIR = 1 << 3, 16 | FNM_CASEFOLD = 1 << 4 17 | } 18 | ; 19 | 20 | #endif 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /include/for.h: -------------------------------------------------------------------------------- 1 | #define FOR(i,n) for(int i = 0; i < (n); i++) 2 | -------------------------------------------------------------------------------- /include/for_each.h: -------------------------------------------------------------------------------- 1 | // UnderC Development project 2 | #ifndef __FOR_EACH_H 3 | #define __FOR_EACH_H 4 | 5 | template 6 | struct _ForEach { 7 | typename C::iterator m_it,m_end; 8 | T& m_var; 9 | _ForEach(C& c, T& t) : m_var(t) 10 | { m_it = c.begin(); m_end = c.end(); } 11 | 12 | bool get() { 13 | bool res = m_it != m_end; 14 | if (res) m_var = *m_it; 15 | return res; 16 | } 17 | 18 | void next() { ++m_it; } 19 | }; 20 | 21 | #define FOR_EACH(v,c) for(_ForEach _fe(c,v); \ 22 | _fe.get(); _fe.next()) 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /include/foreach2.h: -------------------------------------------------------------------------------- 1 | // foreach2.h: Implementing FOR_EACH without using typeof 2 | 3 | class IterBase { 4 | public: 5 | virtual bool next()=0; 6 | }; 7 | 8 | template 9 | class Iter: public IterBase { 10 | protected: 11 | V& _ref; 12 | C::iterator _ci, _ci_end; 13 | 14 | public: 15 | Iter(V& ref, C& con) 16 | : _ref(ref), _ci_end(con.end()), _ci(con.begin()) 17 | { } 18 | 19 | bool next () 20 | { 21 | if (_ci == _ci_end) return false; 22 | _ref = *_ci; 23 | _ci++; 24 | return true; 25 | } 26 | 27 | }; 28 | 29 | template 30 | IterBase *_make_iter(C::value_type& ref, C& con) 31 | { 32 | return new Iter (ref,con); 33 | } 34 | 35 | #define FOR_EACH(i,li) \ 36 | for(std::auto_ptr it(_make_iter(i,(li))); \ 37 | it->next();) 38 | -------------------------------------------------------------------------------- /include/fstream: -------------------------------------------------------------------------------- 1 | // FSTREAM 2 | // 'fake' or 'pocket' iostreams... 3 | // UnderC Development Project, 2001. 4 | 5 | #ifndef _FSTREAM_H 6 | #define _FSTREAM_H 7 | #include 8 | 9 | namespace std { 10 | 11 | class ofstream: public ostream { 12 | public: 13 | bool open(const char *file, int access = 0) { 14 | return open_file(file, access | ios::out); 15 | } 16 | 17 | ofstream(const char *file=0, int access = 0) 18 | { open(file, access); } 19 | 20 | ~ofstream() 21 | { close(); } 22 | }; 23 | 24 | 25 | class ifstream: public istream { 26 | public: 27 | bool open(const char *str, int access = 0) { 28 | return open_file(str, access | ios::in); 29 | } 30 | 31 | ifstream(const char *file = 0, int access = 0) 32 | { 33 | open(file, access); 34 | } 35 | 36 | ~ifstream() 37 | { close(); } 38 | }; 39 | 40 | } // namespace std 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /include/fstream.h: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /include/ftw.h: -------------------------------------------------------------------------------- 1 | // ftw.h 2 | #ifndef __FTW_H 3 | #define __FTW_H 4 | #include 5 | 6 | typedef int (*WALKFN)(const char *file, const stat *sb, int flag); 7 | 8 | #include <_shared_lib.h> 9 | extern "C" { 10 | int ftw(const char *dir, WALKFN fn, int depth); 11 | } 12 | #lib 13 | 14 | enum { 15 | FTW_F, // regular file 16 | FTW_D, // directory 17 | FTW_DNR, // unreadable directory 18 | FTW_NS, // unstatable file 19 | FTW_SL // symbolic link 20 | } 21 | ; 22 | 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /include/glib.h: -------------------------------------------------------------------------------- 1 | /* glib.h 2 | * Fake header for GTK+ imports 3 | */ 4 | 5 | #ifndef _GLIB_H 6 | #define _GLIB_H 7 | typedef char gchar; 8 | typedef unsigned char guchar; 9 | typedef int gboolean; 10 | typedef int gint; 11 | typedef unsigned int guint; 12 | typedef long glong; 13 | typedef unsigned long gulong; 14 | typedef short gshort; 15 | typedef unsigned short gushort; 16 | typedef float gfloat; 17 | typedef double gdouble; 18 | typedef void *gpointer; 19 | typedef void *gconstpointer; 20 | typedef int guint32; 21 | typedef short gint16; 22 | typedef unsigned short guint16; 23 | typedef char gint8; 24 | typedef unsigned char guint8; 25 | 26 | #define GINT_TO_POINTER(x) ((void *)x) 27 | 28 | /* Token types */ 29 | typedef enum 30 | { 31 | G_TOKEN_EOF = 0, 32 | 33 | G_TOKEN_LEFT_PAREN = '(', 34 | G_TOKEN_RIGHT_PAREN = ')', 35 | G_TOKEN_LEFT_CURLY = '{', 36 | G_TOKEN_RIGHT_CURLY = '}', 37 | G_TOKEN_LEFT_BRACE = '[', 38 | G_TOKEN_RIGHT_BRACE = ']', 39 | G_TOKEN_EQUAL_SIGN = '=', 40 | G_TOKEN_COMMA = ',', 41 | 42 | G_TOKEN_NONE = 256, 43 | 44 | G_TOKEN_ERROR, 45 | 46 | G_TOKEN_CHAR, 47 | G_TOKEN_BINARY, 48 | G_TOKEN_OCTAL, 49 | G_TOKEN_INT, 50 | G_TOKEN_HEX, 51 | G_TOKEN_FLOAT, 52 | G_TOKEN_STRING, 53 | 54 | G_TOKEN_SYMBOL, 55 | G_TOKEN_IDENTIFIER, 56 | G_TOKEN_IDENTIFIER_NULL, 57 | 58 | G_TOKEN_COMMENT_SINGLE, 59 | G_TOKEN_COMMENT_MULTI, 60 | G_TOKEN_LAST 61 | } GTokenType; 62 | 63 | 64 | typedef unsigned int GQuark; 65 | typedef guint GMutex; 66 | typedef int GScanner; 67 | //typedef int GList; 68 | typedef int GHashTable; 69 | typedef int GSList; 70 | typedef int GData; 71 | typedef unsigned int GMemChunk; 72 | typedef int GDestroyNotify; 73 | typedef int GNode; 74 | typedef void (*GCompareFunc)(); 75 | typedef void *va_list; 76 | 77 | // stuff to go in fake GLIB header 78 | #define G_STMT_START 79 | #define G_STMT_END 80 | #define g_print printf 81 | 82 | typedef struct _GList GList; 83 | 84 | struct _GList 85 | { 86 | gpointer data; 87 | GList *next; 88 | GList *prev; 89 | }; 90 | 91 | 92 | 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /include/io.h: -------------------------------------------------------------------------------- 1 | #ifndef _IO_H 2 | #define _IO_H 3 | 4 | #ifndef _TIME_T_DEFINED 5 | typedef long time_t; /* time value */ 6 | typedef unsigned long _fsize_t; 7 | #define _TIME_T_DEFINED /* avoid multiple def's of time_t */ 8 | #endif 9 | struct _finddata_t { 10 | unsigned int attrib; 11 | time_t time_create; /* -1 for FAT file systems */ 12 | time_t time_access; /* -1 for FAT file systems */ 13 | time_t time_write; 14 | _fsize_t size; 15 | char name[260]; 16 | }; 17 | 18 | /* File attribute constants for _findfirst() */ 19 | 20 | #define _A_NORMAL 0x00 /* Normal file - No read/write restrictions */ 21 | #define _A_RDONLY 0x01 /* Read only file */ 22 | #define _A_HIDDEN 0x02 /* Hidden file */ 23 | #define _A_SYSTEM 0x04 /* System file */ 24 | #define _A_SUBDIR 0x10 /* Subdirectory */ 25 | #define _A_ARCH 0x20 /* Archive file */ 26 | 27 | #lib msvcrt40.dll 28 | extern "C" { 29 | long _findfirst(char* path, _finddata_t* info); 30 | int _findnext(long handle, _finddata_t* info); 31 | int _findclose(long handle); 32 | } 33 | #lib 34 | 35 | #endif -------------------------------------------------------------------------------- /include/iostream.h: -------------------------------------------------------------------------------- 1 | #include 2 | using std::istream; 3 | using std::ostream; 4 | using std::ifstream; 5 | using std::ofstream; 6 | using std::cout; 7 | using std::cerr; 8 | using std::cin; 9 | using std::endl; 10 | -------------------------------------------------------------------------------- /include/limits.h: -------------------------------------------------------------------------------- 1 | /* limits.h 2 | */ 3 | #ifndef __LIMITS_H 4 | #define __LIMITS_H 5 | 6 | 7 | #define CHAR_BIT 8 8 | #define SCHAR_MIN (-128) 9 | #define SCHAR_MAX 127 10 | #define UCHAR_MAX 0xff 11 | 12 | #define CHAR_MIN SCHAR_MIN 13 | #define CHAR_MAX SCHAR_MAX 14 | 15 | #define MB_LEN_MAX 5 16 | #define SHRT_MIN (-32768) 17 | #define SHRT_MAX 32767 18 | #define USHRT_MAX 0xffffU 19 | #define INT_MIN (-2147483647 - 1) 20 | #define INT_MAX 2147483647 21 | #define UINT_MAX 0xffffffffU 22 | #define LONG_MIN (-2147483647L - 1) 23 | #define LONG_MAX 2147483647L 24 | #define ULONG_MAX 0xffffffffUL 25 | 26 | #define _I8_MIN (-127 - 1) 27 | #define _I8_MAX 127 28 | #define _UI8_MAX 0xffu 29 | 30 | #define _I16_MIN (-32767 - 1) 31 | #define _I16_MAX 32767 32 | #define _UI16_MAX 0xffffu 33 | 34 | #define _I32_MIN (-2147483647 - 1) 35 | #define _I32_MAX 2147483647 36 | #define _UI32_MAX 0xffffffffu 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /include/malloc.h: -------------------------------------------------------------------------------- 1 | /*dummy include file*/ 2 | -------------------------------------------------------------------------------- /include/math.h: -------------------------------------------------------------------------------- 1 | // math.h 2 | // UnderC Pocket C++ Library, Steve Donovan 2001-2003 3 | // UC already has as builtins: 4 | // sin cos tan atan2 pow exp log sqrt atof 5 | #ifndef __MATH_H 6 | #define __MATH_H 7 | #include <_shared_lib.h> 8 | extern "C" { 9 | /* From Appendix B4 of K&R2 */ 10 | // double sin(double); 11 | //double cos(double); 12 | //double tan(double); 13 | double asin(double); 14 | double acos(double); 15 | double atan(double); 16 | //double atan2(double, double); 17 | double sinh(double); 18 | double cosh(double); 19 | double tanh(double); 20 | //double exp(double); 21 | //double log(double); 22 | double log10(double); 23 | //double pow(double, double); 24 | //double sqrt(double); 25 | double ceil(double); // was typed as 'ciel' 26 | double floor(double); 27 | double fabs(double); 28 | double ldexp(double, int); 29 | double frexp(double, int *); 30 | //* double mod(double, double *); *not in Linux?* 31 | double fmod(double, double); 32 | } 33 | #include <_end_shared.h> 34 | #endif 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /include/regexp.h: -------------------------------------------------------------------------------- 1 | // regexp.h 2 | // UnderC Development Project, 2002 3 | // These are the POSIX regular expression functions. 4 | // (Interface to the GNU RX library) 5 | 6 | #ifndef __REGEXP_H 7 | #define __REGEXP_H 8 | 9 | #ifndef __unix__ 10 | #pragma dlink regex2.dll 11 | #else 12 | #pragma dlink libc.so.6 13 | #endif 14 | 15 | #ifndef _SIZE_T_DEF 16 | #define _SIZE_T_DEF 17 | typedef unsigned int size_t; 18 | #endif 19 | 20 | // really aren't interested in all the other fields... 21 | struct regex_t { 22 | unsigned long int allocated; 23 | unsigned long int used; 24 | size_t re_nsub; 25 | char rest[20]; 26 | }; 27 | 28 | /* Type for byte offsets within the string. POSIX mandates this. */ 29 | typedef int regoff_t; 30 | 31 | struct regmatch_t 32 | { 33 | regoff_t rm_so; // Byte offset from string's start to substring's start. 34 | regoff_t rm_eo; // Byte offset from string's start to substring's end. 35 | }; 36 | 37 | // POSIX `cflags' bits (i.e., information for `regcomp'). 38 | const int REG_EXTENDED = 1, REG_ICASE = 1 << 1, REG_NEWLINE = 1 << 2, REG_NOSUB = 1 << 3; 39 | 40 | // POSIX 'eflags' biits (for regexec) 41 | const int REG_NOTBOL = 1, REG_NOTEOL = 1 << 1, REG_ALLOC_REGS = 1 << 2; 42 | 43 | typedef enum 44 | { 45 | REG_NOERROR = 0, /* Success. */ 46 | REG_NOMATCH, /* Didn't find a match (for regexec). */ 47 | 48 | /* POSIX regcomp return error codes. (In the order listed in the 49 | standard.) */ 50 | REG_BADPAT, /* Invalid pattern. */ 51 | REG_ECOLLATE, /* Inalid collating element. */ 52 | REG_ECTYPE, /* Invalid character class name. */ 53 | REG_EESCAPE, /* Trailing backslash. */ 54 | REG_ESUBREG, /* Invalid back reference. */ 55 | REG_EBRACK, /* Unmatched left bracket. */ 56 | REG_EPAREN, /* Parenthesis imbalance. */ 57 | REG_EBRACE, /* Unmatched \{. */ 58 | REG_BADBR, /* Invalid contents of \{\}. */ 59 | REG_ERANGE, /* Invalid range end. */ 60 | REG_ESPACE, /* Ran out of memory. */ 61 | REG_BADRPT, /* No preceding re for repetition op. */ 62 | 63 | /* Error codes we've added. */ 64 | REG_EEND, /* Premature end. */ 65 | REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */ 66 | REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */ 67 | } reg_errcode_t; 68 | 69 | extern "C" { 70 | int regcomp (regex_t * preg, const char * pattern, int cflags); 71 | int regerror (int errcode, const regex_t *preg, 72 | char *errbuf, size_t errbuf_size); 73 | int regexec (const regex_t *preg, const char *str, 74 | size_t nmatch, regmatch_t pmatch[], int eflags); 75 | void regfree (regex_t *preg); 76 | } 77 | 78 | #pragma dlink 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /include/rx++.h: -------------------------------------------------------------------------------- 1 | // rx++ 2 | // A simple C++ regexp class based on the 3 | // GNU RX library 4 | 5 | #ifndef __RXPLUS_H 6 | #define __RXPLUS_H 7 | 8 | #include "regexp.h" 9 | 10 | const int _NM_ = 20; 11 | 12 | class Regexp { 13 | private: 14 | regex_t m_rx; 15 | int m_ret; 16 | char* m_str; 17 | regmatch_t* m_rm; 18 | bool m_advance; 19 | 20 | public: 21 | Regexp(char *pat = NULL, int flags = 0) { 22 | m_advance = false; 23 | m_ret = regcomp(&m_rx,pat,flags); 24 | m_rm = new regmatch_t[_NM_]; 25 | } 26 | 27 | ~Regexp() { 28 | regfree(&m_rx); 29 | delete m_rm; 30 | } 31 | 32 | bool is_ok() { return m_ret == 0; } 33 | void set_str(char *str) { m_str = str; m_advance = false; } 34 | 35 | bool match(char *str, int flags = 0) 36 | { 37 | m_str = str; 38 | m_ret = regexec(&m_rx,m_str,_NM_,m_rm,flags); 39 | return m_ret == 0; 40 | } 41 | 42 | bool match(const string& s, int flags = 0) 43 | { return match(s.c_str(),flags); } 44 | 45 | int index(int idx = 0) { 46 | return m_rm[idx].rm_so; 47 | } 48 | 49 | int end_match(int idx = 0) { 50 | return m_rm[idx].rm_eo; 51 | } 52 | 53 | bool next_match(int flags = 0) 54 | { 55 | if (m_advance) m_str += end_match(0); 56 | m_ret = regexec(&m_rx,m_str,_NM_,m_rm,flags); 57 | m_advance = m_ret == 0; 58 | return m_advance; 59 | } 60 | 61 | bool operator= (char *p) { return match(p); } 62 | bool operator= (const string& s) { return match(s); } 63 | 64 | string matched(int idx = 0) 65 | { 66 | int start = index(idx); 67 | int finish = end_match(idx); 68 | if (start == -1) return ""; 69 | string s = m_str; 70 | return s.substr(start,finish - start); 71 | } 72 | 73 | void get_error(string& err) 74 | { 75 | int len = regerror(m_ret,&m_rx,NULL,0); // how big is error string? 76 | char *buff = new char[len]; 77 | regerror(m_ret,&m_rx,buff,len); // fetch the error... 78 | err = buff; 79 | delete buff; 80 | } 81 | }; 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /include/sstream: -------------------------------------------------------------------------------- 1 | // STRINGSTREAM 2 | // UnderC Development Project, 2001 3 | 4 | #ifndef __STRINGSTREAM_ 5 | #define __STRINGSTREAM_ 6 | 7 | #include 8 | #include 9 | 10 | void _dout_callback(char*); 11 | 12 | namespace std { 13 | 14 | class istringstream: public istream { 15 | public: 16 | istringstream(string& s) { 17 | _str_cpy(&s,1); 18 | hand = _get_std_stream(4); 19 | m_redirect = true; 20 | } 21 | 22 | bool eof() { return _str_eof(0); } 23 | }; 24 | 25 | class ostringstream: public ostream { 26 | public: 27 | ostringstream(string s = 0) { // = "" doesn't work!! 28 | _str_cpy(&s,3); 29 | hand = _get_std_stream(5); 30 | m_redirect = true; 31 | } 32 | 33 | string str() { 34 | string s; 35 | _str_cpy(&s,2); 36 | return s; 37 | } 38 | 39 | // *fix 1.2.3 Override flush to do nothing 40 | void flush() { } 41 | }; 42 | 43 | struct _Ends_ 44 | { int t; }; 45 | 46 | _Ends_ ends; 47 | 48 | // *add 1.2.3 A simple redirectable output class for the shared library 49 | #ifdef _USRDLL 50 | class oredirect_stream: public ostringstream { 51 | public: 52 | void flush() { 53 | string s = str(); 54 | _dout_callback(s.c_str()); 55 | s = ""; 56 | _str_cpy(&s,3); // reset the string... 57 | } 58 | }; 59 | 60 | oredirect_stream dout; 61 | #endif 62 | 63 | } // namespace std 64 | 65 | std::ostream& operator<< (std::ostream& os,std::_Ends_& e) 66 | { 67 | // actually isn't needed with this weird implementation.... 68 | return os; 69 | } 70 | 71 | #endif 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /include/stdarg.h: -------------------------------------------------------------------------------- 1 | //stdarg.h 2 | #ifndef __STDARG_H 3 | #define __STDARG_H 4 | // *fix 1.2.3b va_list is now char* for compatibility, 5 | // and the args are at increasing addresses (was broken by stack direction change) 6 | typedef char *va_list; 7 | #define va_start(ap,p) ap = (char*)&p + 4 8 | #define va_arg(ap,T) *((T*&)ap)++ 9 | #define va_end(ap) 10 | #endif 11 | 12 | 13 | -------------------------------------------------------------------------------- /include/stddef.h: -------------------------------------------------------------------------------- 1 | /* stddef.h 2 | */ 3 | #ifndef __STDDEF_H 4 | #define __STDDEF_H 5 | 6 | #ifndef _SIZE_T_DEF 7 | #define _SIZE_T_DEF 8 | typedef unsigned int size_t; 9 | #endif 10 | 11 | #ifndef NULL 12 | #ifdef __cplusplus 13 | #define NULL 0 14 | #else 15 | #define NULL ((void *)0) 16 | #endif 17 | #endif 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /include/stdio.h: -------------------------------------------------------------------------------- 1 | /* 2 | this file is deliberately empty (the stdio functions are built-in) 3 | * but FILE is often needed... 4 | */ 5 | #ifndef __stdio_h 6 | #define __stdio_h 7 | typedef int FILE; 8 | FILE *stdin = _get_std_stream(1); 9 | FILE *stdout = _get_std_stream(2); 10 | FILE *stderr = _get_std_stream(3); 11 | 12 | #include <_shared_lib.h> 13 | extern "C" { 14 | int fputc(int c, FILE *stream); 15 | int fputs(const char *s, FILE *stream); 16 | int putc(int c, FILE *stream); 17 | int putchar(int c); 18 | // int puts(const char *s); 19 | } 20 | #lib 21 | #endif 22 | 23 | -------------------------------------------------------------------------------- /include/stdlib.h: -------------------------------------------------------------------------------- 1 | // UnderC Development Project, 2001 2 | #ifndef __STDLIB_H 3 | #define __STDLIB_H 4 | 5 | typedef void (*VOIDFN)(); 6 | typedef int (*COMPAREFN) (const void *, const void *); 7 | #ifndef _SIZE_T_DEF 8 | #define _SIZE_T_DEF 9 | typedef unsigned int size_t; 10 | #endif 11 | 12 | #include <_shared_lib.h> 13 | extern "C" { 14 | // char *getenv(char *); 15 | //double atof(const char *); 16 | //int atoi(const char *); 17 | long atol(const char *); 18 | double strtod(const char *, char **); 19 | long strtol(const char *, char **, int); 20 | unsigned long strtoul(const char *s, char **, int); 21 | //int rand(void); 22 | int srand(unsigned int); 23 | void *malloc(size_t); 24 | void *realloc(void *, size_t); 25 | void free(void *); 26 | void exit(int); 27 | void abort(void); 28 | 29 | int atexit (VOIDFN); 30 | void *bsearch(const void *, const void *, 31 | size_t, size_t, COMPAREFN); 32 | void qsort(void *, size_t, size_t, COMPAREFN); 33 | int abs(int); 34 | long labs(long); 35 | 36 | struct div_t { 37 | int quot; 38 | int rem; 39 | }; 40 | div_t div(int, int); 41 | 42 | struct ldiv_t { 43 | long quot; 44 | long rem; 45 | }; 46 | ldiv_t ldiv(long, long); 47 | } 48 | #lib 49 | #endif 50 | -------------------------------------------------------------------------------- /include/string: -------------------------------------------------------------------------------- 1 | // UnderC Development Project, 2001 2 | // A simplified standard string class 3 | 4 | #ifndef __STRING_ 5 | #define __STRING_ 6 | 7 | #ifndef NEW_STRING 8 | #ifdef __UNDERC__ 9 | #include 10 | #else 11 | #include "old-string" 12 | #endif 13 | #else 14 | #include 15 | #ifndef NULL 16 | #define NULL 0 17 | #endif 18 | 19 | #ifdef __UNDERC__ 20 | #define EXPORT 21 | namespace std { 22 | #else 23 | #define EXPORT __declspec(dllexport) 24 | #endif 25 | 26 | #pragma dlink string_imp.dll 27 | 28 | class EXPORT string { 29 | protected: 30 | char *m_str; 31 | unsigned int m_len; 32 | public: 33 | typedef unsigned long size_type; 34 | typedef char *iterator; 35 | typedef const char *const_iterator; 36 | enum { npos = 0xFFFFFFFF }; 37 | 38 | char *c_str() const { return m_str; } 39 | size_type length() const { return m_len; } 40 | size_type size() const { return m_len; } 41 | bool empty() const { return m_len == 0; } 42 | // *hack 0.9.5 These aren't really const methods (but!) 43 | iterator begin() const { return m_str; } 44 | iterator end() const { return m_str + m_len; } 45 | 46 | void resize(size_type sz); 47 | void append(char *s); 48 | void push_back(char ch); 49 | void copy(char *str); 50 | string(const char *str); 51 | string(const char *str, int sz); 52 | string(); 53 | string(size_type sz, char ch); 54 | string(const string& s); 55 | string& operator= (const string& s); 56 | string& operator= (char *str); 57 | string& operator+= (char *str); 58 | string& operator+= (const string& s); 59 | string& operator+= (char ch); 60 | ~string(); 61 | size_type find(char *str) const; 62 | size_type find(const string& s) const; 63 | size_type find(char ch) const; 64 | size_type rfind(char ch) const; 65 | size_type bound(size_type n) const; 66 | string substr(size_type start, size_type n = npos) const; 67 | string& replace(size_type is, size_type n, char *repl); 68 | string& replace(size_type is, size_type n, const string& repl); 69 | void insert(size_type idx, const string& repl); 70 | char& operator[] (size_type i); 71 | #ifndef __UNDERC__ 72 | char operator[] (size_type i) const; 73 | #endif 74 | 75 | int compare(const string& s) const; 76 | // *hack 0.9.7 used to be non-member, but that won't work for now! 77 | bool operator== (const string& s2) const; 78 | }; 79 | 80 | #ifdef __UNDERC__ 81 | } // namespace std 82 | #define _string std::string 83 | #else 84 | #define _string string 85 | #endif 86 | 87 | //*SJD* Currently we aren't doing overloading with functions which 88 | // span different namespaces. So putting operator+ in std would 89 | // mean being unable to overload it for any other type. 90 | EXPORT bool operator != (const _string& s1, const _string& s2); 91 | EXPORT bool operator> (const _string& s1, const _string& s2); 92 | EXPORT bool operator< (const _string& s1, const _string& s2); 93 | EXPORT _string operator+ (const _string& s1, const _string& s2); 94 | EXPORT _string operator+ (const _string& s1, char *str2); 95 | 96 | #pragma dlink 97 | 98 | #define LINESIZE 512 99 | 100 | std::ostream& operator<< (std::ostream& os, const std::string& s) 101 | { 102 | os << s.c_str(); 103 | return os; 104 | } 105 | 106 | std::istream& operator>> (std::istream& is, std::string& s) 107 | { 108 | char buff[LINESIZE]; 109 | is >> buff; 110 | s = buff; 111 | return is; 112 | } 113 | 114 | std::istream& getline(std::istream& is, std::string& s) 115 | { 116 | char buff[LINESIZE]; 117 | is.getline(buff,LINESIZE); 118 | s = buff; 119 | return is; 120 | } 121 | #endif 122 | #endif 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /include/string.h: -------------------------------------------------------------------------------- 1 | #ifndef _STRING_H 2 | #define _STRING_H 3 | #include <_shared_lib.h> 4 | #include 5 | /* From Appendix B3, String Functions, of K&R2 */ 6 | /* Commented functions are implemented as built-ins */ 7 | extern "C" { 8 | //char *strcpy(char *, const char *); 9 | //char *strncpy(char *, const char *, size_t); 10 | //char *strcat(char *, const char *); 11 | char *strncat(char *, const char *, size_t); 12 | //int strcmp(const char *, const char *); 13 | int strncmp(const char *, const char *, size_t); 14 | //char *strchr(const char *, int); 15 | //char *strrchr(const char *, int); 16 | size_t strspn(const char *, const char *); 17 | size_t strcspn(const char *, const char *); 18 | char *strpbrk(const char *, const char *); 19 | //char *strstr(const char *, const char *); 20 | //size_t strlen(const char *); 21 | char *strerror(size_t); 22 | //char *strtok(char *, const char *); 23 | void memcpy(char *, const char *, size_t); 24 | void memmove(char *, const char *, size_t); 25 | int memcmp(const char *, const char *, size_t); 26 | void *memchr(const char *, int, size_t); 27 | void memset(void *, int, size_t); 28 | } 29 | #lib 30 | #endif 31 | 32 | -------------------------------------------------------------------------------- /include/strstrea.h: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /include/strstream.h: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /include/sys/stat.h: -------------------------------------------------------------------------------- 1 | // sys/stat.h 2 | #ifndef _SYS_STAT_H 3 | #define _SYS_STAT_H 4 | #include 5 | typedef unsigned short ushort; 6 | 7 | /* note: this is unlikely to work for anything except x86 Linux. */ 8 | 9 | #pragma pack(1) 10 | struct stat 11 | { 12 | dev_t st_dev; /* device */ 13 | ushort _pad1; 14 | ino_t st_ino; /* inode */ 15 | mode_t st_mode; /* protection */ 16 | nlink_t st_nlink; /* number of hard links */ 17 | uid_t st_uid; /* user ID of owner */ 18 | gid_t st_gid; /* group ID of owner */ 19 | dev_t st_rdev; /* device type (if inode device) */ 20 | ushort _pad2; 21 | uint _padx; 22 | off_t st_size; /* total size, in bytes */ 23 | unsigned long st_blksize; /* blocksize for filesystem I/O */ 24 | unsigned long st_blocks; /* number of blocks allocated */ 25 | time_t st_atime; /* time of last access */ 26 | uint _pad3; 27 | time_t st_mtime; /* time of last modification */ 28 | uint _pad4; 29 | time_t st_ctime; /* time of last change */ 30 | uint _pad5; 31 | uint _pad6; 32 | uint _pad7; 33 | }; 34 | 35 | #include <_shared_lib.h> 36 | extern "C" { 37 | int __lxstat(int vs, const char *file_name, struct stat *buf); 38 | int __xstat(int vs, const char *file_name, struct stat *buf); 39 | #lib 40 | 41 | // see for this bit of redirection 42 | #define lstat(f,b) __lxstat(3,f,b) 43 | 44 | const int 45 | S_IFMT = 0170000, // bitmask for the file type bitfields 46 | S_IFSOCK = 0140000, // socket 47 | S_IFLNK = 0120000, // symbolic link 48 | S_IFREG = 0100000, // regular file 49 | S_IFBLK = 0060000, // block device 50 | S_IFDIR = 0040000, // directory 51 | S_IFCHR = 0020000, // character device 52 | S_IFIFO = 0010000, // fifo 53 | S_ISUID = 0004000, // set UID bit 54 | S_ISGID = 0002000, // set GID bit (see below) 55 | S_ISVTX = 0001000, // sticky bit (see below) 56 | S_IRWXU = 00700, // mask for file owner permissions 57 | S_IRUSR = 00400, // owner has read permission 58 | S_IWUSR = 00200, // owner has write permission 59 | S_IXUSR = 00100, // owner has execute permission 60 | S_IRWXG = 00070, // mask for group permissions 61 | S_IRGRP = 00040, // group has read permission 62 | S_IWGRP = 00020, // group has write permission 63 | S_IXGRP = 00010, // group has execute permission 64 | S_IRWXO = 00007, // mask for permissions for others (not in group) 65 | S_IROTH = 00004, // others have read permission 66 | S_IWOTH = 00002, // others have write permisson 67 | S_IXOTH = 00001; // others have execute permission 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /include/sys/types.h: -------------------------------------------------------------------------------- 1 | // sys/types.h 2 | #ifndef _SYS_TYPES_H 3 | #define _SYS_TYPES_H 4 | 5 | typedef unsigned int uint; 6 | struct int64 7 | { 8 | int low,high; 9 | }; 10 | 11 | typedef int64 dev_t; 12 | typedef uint ino_t; 13 | typedef uint mode_t; 14 | typedef uint nlink_t; 15 | typedef uint uid_t; 16 | typedef uint gid_t; 17 | typedef uint off_t; 18 | 19 | // no. of seconds since midnight Jan 1, 1970 20 | #ifndef _TIME_T_DEFINED 21 | typedef long time_t; /* time value */ 22 | typedef unsigned long _fsize_t; 23 | #define _TIME_T_DEFINED /* avoid multiple def's of time_t */ 24 | #endif 25 | 26 | #endif 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /include/time.h: -------------------------------------------------------------------------------- 1 | // UnderC Development Project, 2001 2 | #ifndef __TIME_H 3 | #define __TIME_H 4 | 5 | // no. of seconds since midnight Jan 1, 1970 6 | #ifndef _TIME_T_DEFINED 7 | typedef long time_t; /* time value */ 8 | typedef long clock_t; 9 | typedef unsigned long _fsize_t; 10 | #ifdef __win32__ 11 | #define CLOCKS_PER_SEC 1000 12 | #else 13 | #define CLOCKS_PER_SEC 1000000 14 | #endif 15 | #define _TIME_T_DEFINED /* avoid multiple def's of time_t */ 16 | #endif 17 | 18 | // depends on C mode! This hack relies on the fact that C mode defines delete as a macro 19 | #ifndef delete 20 | # define _STRUCT 21 | #else 22 | # define _STRUCT struct 23 | #endif 24 | 25 | struct tm { 26 | int tm_sec; /* seconds after the minute - [0,59] */ 27 | int tm_min; /* minutes after the hour - [0,59] */ 28 | int tm_hour; /* hours since midnight - [0,23] */ 29 | int tm_mday; /* day of the month - [1,31] */ 30 | int tm_mon; /* months since January - [0,11] */ 31 | int tm_year; /* years since 1900 */ 32 | int tm_wday; /* days since Sunday - [0,6] */ 33 | int tm_yday; /* days since January 1 - [0,365] */ 34 | int tm_isdst; /* daylight savings time flag */ 35 | }; 36 | 37 | #include <_shared_lib.h> 38 | extern "C" { 39 | time_t clock(); 40 | time_t time(time_t *); 41 | char * ctime(time_t *); 42 | _STRUCT tm* localtime(time_t *); 43 | _STRUCT tm* gmtime(time_t *); 44 | char *asctime( const _STRUCT tm *timeptr ); 45 | int strftime( char *strDest, int maxsize, const char *format, const _STRUCT tm *timeptr ); 46 | } 47 | #lib 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /include/uc/dir.h: -------------------------------------------------------------------------------- 1 | #ifndef _UC_DIR_H 2 | #define _UC_DIR_H 3 | 4 | #include 5 | #include 6 | 7 | class DirInfo { 8 | _finddata_t* m_pfd; 9 | public: 10 | DirInfo(_finddata_t* pfd = NULL) 11 | : m_pfd(pfd) { } 12 | 13 | char* name() 14 | { return m_pfd->name; } 15 | 16 | long size() 17 | { return m_pfd->size; } 18 | 19 | time_t created() 20 | { return m_pfd->time_create; } 21 | 22 | time_t accessed() 23 | { return m_pfd->time_access; } 24 | 25 | time_t written() 26 | { return m_pfd->time_write; } 27 | 28 | bool is_read_only() 29 | { return m_pfd->attrib & _A_NORMAL; } 30 | 31 | bool is_directory() 32 | { return m_pfd->attrib & _A_SUBDIR; } 33 | 34 | bool is_archive() 35 | { return m_pfd->attrib & _A_ARCH; } 36 | 37 | operator char*() { return m_pfd->name; } 38 | }; 39 | 40 | class DirPaths { 41 | _finddata_t m_fd; 42 | long m_hand; 43 | bool m_ok; 44 | char* m_path; 45 | public: 46 | void close() 47 | { _findclose(m_hand); } 48 | 49 | bool open(char* file = NULL) 50 | { 51 | if (file) m_path = file; 52 | if (m_hand != 0) close(); 53 | m_dir = opendir(file); 54 | 55 | m_ok = m_hand != 0; 56 | return m_ok; 57 | } 58 | 59 | DirPaths(char* file = NULL) 60 | { 61 | m_hand = 0; 62 | if (file) open(file); 63 | } 64 | 65 | ~DirPaths() 66 | { close(); } 67 | 68 | DirInfo info() 69 | { 70 | return DirInfo(&m_fd); 71 | } 72 | 73 | void next() 74 | { 75 | m_ok = _findnext(m_hand,&m_fd) == 0; 76 | } 77 | 78 | bool ok() 79 | { return m_ok; } 80 | 81 | class iterator { 82 | DirPaths* m_dir; 83 | public: 84 | void next() { 85 | m_dir->next(); 86 | if (! m_dir->ok()) m_dir = NULL; 87 | } 88 | iterator(DirPaths* dir=0) 89 | : m_dir(dir) {} 90 | bool operator!=(const iterator& it) 91 | { return m_dir != it.m_dir; } 92 | 93 | void operator++() { next(); } 94 | void operator++(int) { next(); } 95 | //char* operator*() { return m_dir->name(); } 96 | DirInfo operator*() { return m_dir->info(); } 97 | }; 98 | 99 | iterator begin() { /*open();*/ return iterator(this); } 100 | iterator end() { return iterator(0); } 101 | 102 | }; 103 | -------------------------------------------------------------------------------- /include/uc_except.h: -------------------------------------------------------------------------------- 1 | // uc_except.h 2 | // Maps Win32 structured exceptions (SE) or Linux signals 3 | // onto C++ exceptions 4 | #ifndef _uc_except_h 5 | #define _uc_except_h 6 | 7 | class Exception { 8 | private: 9 | char *m_what; 10 | public: 11 | Exception(char *msg="unknown") : m_what(msg) {} 12 | char *what() { return m_what; } 13 | static void initialize(); 14 | }; 15 | 16 | class HardwareException: public Exception { 17 | public: 18 | HardwareException(char *msg) : Exception(msg) { } 19 | }; 20 | 21 | class IntOverflow: public HardwareException { 22 | public: 23 | IntOverflow() : HardwareException("integer overflow") {} 24 | }; 25 | 26 | class FloatOverflow: public HardwareException { 27 | public: 28 | FloatOverflow() : HardwareException("floating point overflow") {} 29 | }; 30 | 31 | class IntDivByZero: public HardwareException { 32 | public: 33 | IntDivByZero() : HardwareException("integer division by zero") {} 34 | }; 35 | 36 | class FloatDivByZero: public HardwareException { 37 | public: 38 | FloatDivByZero() : HardwareException("floating point division by zero") {} 39 | }; 40 | 41 | class AccessViolation: public HardwareException { 42 | public: 43 | AccessViolation() : HardwareException("access violation") {} 44 | }; 45 | #endif 46 | -------------------------------------------------------------------------------- /include/uc_save.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class RestoreUCWin { 5 | 6 | RestoreUCWin() 7 | { 8 | HWND h = GetActiveWindow(); 9 | if (! h) return; 10 | RECT rt; 11 | std::ifstream in("/_pos.txt"); 12 | if (in) { 13 | in >> rt.left >> rt.top >> rt.right >> rt.bottom; 14 | MoveWindow(h,rt.left,rt.top,rt.right-rt.left,rt.bottom-rt.top,1); 15 | } 16 | } 17 | 18 | ~RestoreUCWin() 19 | { 20 | HWND h = GetActiveWindow(); 21 | if (! h) return; 22 | RECT rt; 23 | GetWindowRect(h,&rt); 24 | std::ofstream out("/_pos.txt"); 25 | out << rt.left << ' ' << rt.top << ' ' << rt.right << ' ' << rt.bottom << std::endl; 26 | } 27 | 28 | }; 29 | 30 | RestoreUCWin __uc__; 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /include/uc_timer.h: -------------------------------------------------------------------------------- 1 | // UC_TIMER.H 2 | 3 | #ifndef __UC_TIMER_H 4 | #define __UC_TIMER_H 5 | 6 | // import GetTickCount() (no of msec since begining of session) 7 | #lib kernel32.dll 8 | extern "C" { 9 | __API unsigned long GetTickCount(); 10 | } 11 | #lib 12 | 13 | class Timer { 14 | unsigned long m_start; 15 | char* m_msg; 16 | public: 17 | Timer() { } 18 | void start(char* msg) { 19 | m_msg = msg; 20 | m_start = GetTickCount(); 21 | } 22 | void stop() { 23 | unsigned long elapsed = GetTickCount() - m_start; 24 | printf("%s: time %lf sec\n",m_msg,elapsed/1000.0); 25 | } 26 | }; 27 | 28 | #endif 29 | 30 | 31 | -------------------------------------------------------------------------------- /include/ucri.h: -------------------------------------------------------------------------------- 1 | // UCRI.H 2 | // Reflection Interface for UnderC. 3 | // Please note the location of the actual header, 4 | // which is shared with the UC code base. 5 | // UnderC Development Project, 2001-2002 6 | #ifndef __UCRI_INC_H 7 | #define __UCRI_INC_H 8 | #lib $self self.imp 9 | #include "../src/ucri.h" 10 | #lib 11 | #endif 12 | -------------------------------------------------------------------------------- /include/ucri/profile.h: -------------------------------------------------------------------------------- 1 | /* A simple profiler for UnderC 2 | * This uses the custom trace facility to monitor every function in the system 3 | */ 4 | 5 | #ifndef __UCRI_PROFILE_H 6 | #define __UCRI_PROFILE_H 7 | #include 8 | #include 9 | 10 | unsigned long* g_pic; 11 | 12 | // XProfiler is a custom trace class which is attached to every function; 13 | // it updates the called count and the total cycles used by the function. 14 | class XProfiler: public XTrace { 15 | int m_kount; 16 | int m_cycles; 17 | int m_start; 18 | public: 19 | int kount() { return m_kount; } 20 | 21 | XProfiler() : m_kount(0),m_cycles(0),XTrace(true) { } 22 | 23 | int cycles() { return m_cycles; } 24 | 25 | void enter(XExecState* xs) 26 | { 27 | m_kount++; 28 | m_start = *g_pic; 29 | } 30 | 31 | void leave(XExecState* xs) 32 | { 33 | m_cycles += (*g_pic - m_start); 34 | } 35 | }; 36 | 37 | struct ProfileItem { 38 | XFunction* fun; 39 | int count; 40 | float percent; 41 | }; 42 | 43 | typedef std::list ItemList; 44 | 45 | // we want to sort these guys in reverse order, hence this eccentric definition! 46 | bool operator< (ProfileItem& p1, ProfileItem& p2) 47 | { 48 | return p1.percent > p2.percent; 49 | } 50 | 51 | class Profiler { 52 | XFunctions m_fl; 53 | ItemList m_item_list; 54 | XClass* m_self; 55 | public: 56 | Profiler() 57 | { 58 | uc_ucri_init() 59 | m_self = uc_global()->lookup_class("Profiler"); 60 | } 61 | 62 | // to start the profiler, attach a TProfiler tracer to each function 63 | // and switch on profiling and tracing. 64 | void start() 65 | { 66 | XFunction* fn; 67 | XFunction::set_tracing(false); 68 | UCRI::grab_all_functions(m_fl,m_self); 69 | FOR_EACH(fn,m_fl) 70 | fn->set_trace(new XProfiler()); 71 | g_pic = ucri_instruction_counter(true); 72 | XFunction::set_tracing(true); 73 | } 74 | 75 | // to stop, extract the trace objects and switch off tracing for each function. 76 | void stop() 77 | { 78 | XFunction::set_tracing(false); 79 | XFunction* fn; 80 | ProfileItem pitem; 81 | double total = *g_pic/100.0, frac; 82 | m_item_list.clear(); 83 | FOR_EACH(fn, m_fl) { 84 | XProfiler* pi = (XProfiler*)fn->get_trace(); 85 | if (pi) { 86 | fn->set_trace(NULL); 87 | frac = pi->cycles()/total; 88 | if (frac > 0.2) { // only consider contributions greater than 0.2% 89 | pitem.fun = fn; 90 | pitem.count = pi->kount(); 91 | pitem.percent = frac; 92 | m_item_list.push_back(pitem); 93 | } 94 | delete pi; 95 | } 96 | } 97 | std::sort(m_item_list.begin(), m_item_list.end()); 98 | } 99 | 100 | void report(int n = 10) 101 | { 102 | ProfileItem pitem; 103 | int k = 0; 104 | cout << "Function\tPercent\tCount" << endl; 105 | FOR_EACH(pitem,m_item_list) { 106 | cout << pitem.fun->name() << '\t' << pitem.percent << '\t' << pitem.count << endl; 107 | if (++k > n) break; 108 | } 109 | } 110 | }; // class Profiler 111 | #endif 112 | -------------------------------------------------------------------------------- /include/ucri/refs.h: -------------------------------------------------------------------------------- 1 | /* Find all references to a function or static variable/constant 2 | * Basically, look at the pcode of all functions in the system 3 | * and find any 'direct' references to the address. (Direct addresses are 4 | * actually 22-bit offsets into the global data segment; this is how 5 | * we fit them into a 32-bit instruction). The address of a function is 6 | * its function block, which contains a reference to the actual pcode. 7 | */ 8 | 9 | #ifndef __UCRI_REFS_H 10 | #define __UCRI_REFS_H 11 | #include 12 | 13 | namespace UCRI { 14 | 15 | class XPosition { 16 | XFunction* m_fun; 17 | XInstruction* m_ip; 18 | public: 19 | XPosition(XFunction* fun, XInstruction* ip) 20 | : m_fun(fun), m_ip(ip) { } 21 | XPosition() { } 22 | XFunction* fun() { return m_fun; } 23 | XInstruction* ip() { return m_ip; } 24 | string file() { 25 | string fs; 26 | m_fun->where(fs); 27 | return fs; 28 | } 29 | int ip_offs() { return m_ip - m_fun->pcode(); } 30 | int line() { return m_fun->ip_to_line(m_ip); } 31 | }; 32 | typedef list XPositions; 33 | 34 | class References { 35 | XFunctions g_fl; 36 | XPositions g_pos_list; 37 | XClass* g_self; 38 | XNTable* g_context; 39 | public: 40 | void update() 41 | { 42 | grab_all_functions(g_fl,g_self); 43 | } 44 | 45 | References() 46 | { 47 | uc_ucri_init(); 48 | g_self = uc_global()->lookup_class("References"); 49 | g_context = uc_global(); 50 | update(); 51 | } 52 | 53 | void set_context(XNTable* context) 54 | { g_context = context; } 55 | 56 | void generate(int target_data) 57 | { 58 | // for all functions _excluding_ the methods of this class! 59 | XFunction* fn; 60 | FOR_EACH(fn,g_fl) { 61 | // look at the pcode for any direct addressing of the given offset 62 | XInstruction* pp = fn->pcode(); 63 | if (pp) 64 | while (pp->opcode != 0) { 65 | if (pp->rmode == DIRECT && pp->data == target_data) 66 | g_pos_list.push_back(XPosition(fn,pp)); 67 | pp++; 68 | } 69 | } 70 | } 71 | 72 | void dump() 73 | { 74 | XPosition pos; 75 | FOR_EACH(pos,g_pos_list) { 76 | cout << pos.file() << ": " << pos.line() << ' ' 77 | << pos.fun()->name() << ' ' << pos.ip_offs() << endl; 78 | } 79 | } 80 | 81 | void go(int data) 82 | { 83 | g_pos_list.clear(); 84 | generate(data); 85 | dump(); 86 | } 87 | 88 | bool set_function(XFunction* pf) 89 | { 90 | // find the offset of the function block in the global data segment 91 | int data = uc_global()->offset(pf->fblock()); 92 | go(data); 93 | return true; 94 | } 95 | 96 | bool set_function(string name, int k = 1) 97 | { 98 | XFunction* fn = lookup_fun(name,k); 99 | if (fn) return set_function(fn); 100 | else return false; // no overloaded function w/ this index... 101 | } 102 | 103 | bool set_global(string name) 104 | { 105 | // we fail if this reference either doesn't exist, or doesn't use 106 | // direct addressing. 107 | XEntry* xe = g_context->lookup(name.c_str()); 108 | if (! xe || xe->addr_mode() != DIRECT) return false; 109 | go(xe->data()); 110 | return true; 111 | } 112 | 113 | }; // class References 114 | 115 | } // namespace UCRI 116 | 117 | #endif 118 | -------------------------------------------------------------------------------- /include/ucri/trace.h: -------------------------------------------------------------------------------- 1 | /* Functions to make using the UnderC custom trace facility easier. 2 | * For example, 3 | * add_trace_to_funs("string::*",new XTrace()); 4 | * will start a standard trace on every member function of class string. 5 | * add_trace_expr() is a particularly convenient way of attaching 6 | * an expression which will be evaluated whenever a function (or functions) 7 | * is entered. 8 | * This can be used to force a function to immediately return a specified 9 | * value, or to call another function altogether. 10 | * For example, given a function fred() returning an integer, 11 | * add_trace_expr("fred","RET4(xs,0)"); 12 | * is the same as a _temporary_ redefinition of fred() as just { return 10; } 13 | * Afterwards, 14 | * remove_trace("fred"); 15 | * will restore previous behaviour. 16 | */ 17 | 18 | #ifndef __UCRI_TRACE_H 19 | #define __UCRI_TRACE_H 20 | 21 | #include 22 | 23 | namespace UCRI { 24 | 25 | void set_fun_trace(XFunction* f, void* ptr) 26 | { 27 | f->set_trace((XTrace*)ptr); 28 | } 29 | 30 | void add_trace_to_funs(const string& fun_pat, XTrace* pt) 31 | { 32 | uc_ucri_init(); 33 | XFunction::set_tracing(false); 34 | apply_op_to_funs(fun_pat, set_fun_trace, pt); 35 | XFunction::set_tracing(true); 36 | } 37 | 38 | void remove_trace(const string& fun_pat) 39 | { 40 | add_trace_to_funs(fun_pat,NULL); 41 | } 42 | 43 | int kount = 1; 44 | 45 | string tmp_name() 46 | { 47 | char buff[80]; 48 | sprintf(buff,"__TT%d",kount++); 49 | return buff; 50 | } 51 | 52 | bool add_trace_expr(string fun_pat, string expr) 53 | { 54 | string cname = tmp_name(); 55 | string cx = "struct " + cname + ": XTrace { "; 56 | cx += " void enter(XExecState* xs) { " + expr + "; } };"; 57 | if (uc_exec(cx.c_str())==0) { 58 | XClass* pc = uc_global()->lookup_class(cname.c_str()); 59 | XTrace* pt = (XTrace*)pc->create(); 60 | add_trace_to_funs(fun_pat, pt); 61 | return true; 62 | } else return false; 63 | } 64 | 65 | XInstruction ret0_instr = {8,0,0}; // RET 66 | XInstruction ret4_instr = {9,0,0}; // RETI 67 | 68 | #define RET4(val) xs->sp = xs->sp-2; xs->ip = &ret4_instr; *(xs->sp) = val 69 | #define RET0 xs->ip = &ret0_instr 70 | #define CHAIN(fn) xs->fb = &fn; xs->ip = xs->fb->pstart 71 | 72 | void dump_fun_args(XExecState* xs) 73 | { 74 | XFunction* xf = XFunction::from_fb(xs->fb); 75 | XTList tl; 76 | XStringList args; 77 | xf->get_args(&tl,&args); 78 | string name,s; 79 | FOR_EACH(name,args) { 80 | XEntry* pe = xf->lookup_local(name.c_str()); 81 | cout << name << " = "; 82 | pe->type()->val_as_str(s,pe->data()+xs->bp); 83 | cout << s << ' '; 84 | } 85 | cout << endl; 86 | } 87 | 88 | } // namespace UCRI 89 | 90 | #endif 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /include/ucri/utils.h: -------------------------------------------------------------------------------- 1 | /* A set of utilities for working with functions using UCRI. 2 | */ 3 | 4 | #ifndef __UCRI_UTILS_H 5 | #define __UCRI_UTILS_H 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace UCRI { 12 | 13 | XNTable* context_from_pattern(string& pat, XNTable* context = NULL) 14 | { 15 | int i = pat.find("::"); 16 | if (context==NULL) context=uc_global(); 17 | if (i != string::npos) { 18 | string class_name = pat.substr(0,i); 19 | pat = pat.substr(i+2,999); 20 | context = context->lookup_class(class_name.c_str()); 21 | } 22 | return context; 23 | } 24 | 25 | XFunction* lookup_fun(string name, int k = 1, XNTable* context = NULL) 26 | { 27 | context = context_from_pattern(name,context); 28 | if (! context) return NULL; 29 | XEntry* xe = context->lookup(name.c_str()); 30 | if (xe->nfun() >= k) return xe->function(k); 31 | else return NULL; 32 | } 33 | 34 | int get_matching_functions(string fun_pat, XFunctions& fl, XNTable* context = NULL) 35 | { 36 | context = context_from_pattern(fun_pat,context); 37 | if (! context) return 0; 38 | context->get_functions(fl,0,fun_pat.c_str()); 39 | return fl.size(); 40 | } 41 | 42 | int get_matching_classes(const string& clss_pat, XClasses& cl, XNTable* context = NULL) 43 | { 44 | XEntries xl; 45 | if (context==NULL) context=uc_global(); 46 | context->get_variables(xl,CLASSES | NAMESPACES, clss_pat.c_str()); 47 | XEntry* xe; 48 | cl.clear(); 49 | FOR_EACH(xe,xl) 50 | cl.push_back(xe->type()->as_class()); 51 | return cl.size(); 52 | } 53 | 54 | int grab_all_functions(XFunctions& fl, XClass* exclude_context=NULL) 55 | { 56 | XFunctions cl_fl; 57 | XClass* context; 58 | XClasses cl; 59 | get_matching_functions("*",fl); 60 | get_matching_classes("*",cl); 61 | FOR_EACH(context,cl) 62 | if (context != exclude_context) { 63 | get_matching_functions("*",cl_fl,context); 64 | fl.splice(fl.begin(),cl_fl); // append the methods to the function list 65 | } 66 | return fl.size(); 67 | } 68 | 69 | void dump_functions(XFunctions& fl) 70 | { 71 | XFunction* f; 72 | string s; 73 | FOR_EACH(f,fl) { 74 | f->as_str(s); 75 | cout << s << ';' << endl; 76 | } 77 | } 78 | 79 | void dump_entries(XEntries& xl) 80 | { 81 | XEntry* xe; 82 | int k = 0; 83 | FOR_EACH(xe,xl) { 84 | cout << xe->name(); 85 | if (++k % 5 != 0) cout << '\t'; 86 | else cout << endl; 87 | } 88 | cout << endl; 89 | } 90 | 91 | void dump_classes(XClasses& xl) 92 | { 93 | XClass* xc; 94 | FOR_EACH(xc,xl) 95 | cout << xc->name() << endl; 96 | } 97 | 98 | void dump_function(ostream& out, void* fblk) 99 | { 100 | XFunction* f = XFunction::from_fb(fblk); 101 | string s; 102 | f->as_str(s); 103 | out << s; 104 | } 105 | 106 | XFunctions fns; 107 | 108 | void testf(string pat) 109 | { 110 | get_matching_functions(pat,fns); 111 | dump_functions(fns); 112 | } 113 | 114 | typedef void (*FUN_OP)(XFunction* f, void* ptr); 115 | typedef XFunction* PXFunction; 116 | 117 | // note: this is encoded somewhat elaborately because we want to guarantee 118 | // that _only_ fun_op() will be called in the iteration loop. Otherwise 119 | // one gets interesting results with operations which affect function behaviour 120 | // like tracing, profiling, etc. 121 | int apply_op_to_funs(string fun_pat, FUN_OP fun_op, void* arg) 122 | { 123 | XFunctions fl; 124 | XFunction* pf; 125 | get_matching_functions(fun_pat,fl); 126 | int n = fl.size(); 127 | XFunction** temp_fns = new PXFunction[n]; 128 | std::copy(fl.begin(),fl.end(),temp_fns); 129 | for (int i = 0; i < n; i++) 130 | fun_op(temp_fns[i],arg); 131 | delete temp_fns; 132 | return n; 133 | } 134 | 135 | } // namespace UCRI 136 | 137 | #endif -------------------------------------------------------------------------------- /include/utility: -------------------------------------------------------------------------------- 1 | // UnderC Development Project 2 | #ifndef __UTILITY_ 3 | #define __UTILITY_ 4 | 5 | namespace std { 6 | 7 | namespace rel_ops { 8 | 9 | template< class Type > 10 | bool operator!=( const Type &x, const Type &y ) 11 | { 12 | return !( x == y ); 13 | } 14 | 15 | template< class Type > 16 | bool operator>( const Type &x, const Type &y ) 17 | { 18 | return( y < x ); 19 | } 20 | 21 | template< class Type > 22 | bool operator<=( const Type &x, const Type &y ) 23 | { 24 | return( !( y < x ) ); 25 | } 26 | 27 | template< class Type > 28 | bool operator>=( const Type &x, const Type &y ) 29 | { 30 | return( !( x < y ) ); 31 | } 32 | 33 | } // namespace rel_ops 34 | 35 | 36 | // Pair support 37 | 38 | template< class Type1, class Type2> 39 | struct pair { 40 | typedef Type1 first_type; 41 | typedef Type2 second_type; 42 | 43 | Type1 first; 44 | Type2 second; 45 | 46 | pair() {} 47 | 48 | pair( const Type1 &x, const Type2 &y ) : 49 | first( x ), second( y ) 50 | { } 51 | 52 | //Is not correct and could be modified when 53 | //embedded template is implemented 54 | pair( const pair< Type1, Type2 > &other ) : 55 | first( other.first ), second( other.second ) 56 | { } 57 | }; 58 | 59 | template< class Type1, class Type2 > 60 | inline 61 | bool operator==( const pair< Type1, Type2 > &x, 62 | const pair< Type1, Type2 > &y ) 63 | { 64 | return( x.first == y.first && x.second == y.second ); 65 | } 66 | 67 | template< class Type1, class Type2 > 68 | inline 69 | bool operator<( const pair< Type1, Type2 > &x, 70 | const pair< Type1, Type2 > &y ) 71 | { 72 | return( x.first < y.first || 73 | ( !( y.first < x.first ) && x.second < y.second ) ); 74 | } 75 | 76 | template< class Type1, class Type2 > 77 | inline 78 | bool operator!=( const pair< Type1, Type2 > &x, 79 | const pair< Type1, Type2 > &y ) 80 | { 81 | return( !(x == y) ); 82 | } 83 | 84 | template< class Type1, class Type2 > 85 | inline 86 | bool operator>( const pair< Type1, Type2 > &x, 87 | const pair< Type1, Type2 > &y ) 88 | { 89 | return( y < x ); 90 | } 91 | 92 | template< class Type1, class Type2 > 93 | inline 94 | bool operator>=( const pair< Type1, Type2 > &x, 95 | const pair< Type1, Type2 > &y ) 96 | { 97 | return( !(x < y) ); 98 | } 99 | 100 | template< class Type1, class Type2 > 101 | inline 102 | bool operator<=( const pair< Type1, Type2 > &x, 103 | const pair< Type1, Type2 > &y ) 104 | { 105 | return( !(y < x) ); 106 | } 107 | 108 | template< class Type1, class Type2 > 109 | inline 110 | pair< Type1, Type2 > make_pair( const Type1 &x, const Type2 &y ) 111 | { //This implementation is incorrect 112 | Type1 i1 = x; 113 | Type2 i2 = y; 114 | pair< Type1, Type2 > pair_them(x, y); 115 | return( pair_them ); 116 | } 117 | 118 | } // namespace std 119 | 120 | #endif 121 | -------------------------------------------------------------------------------- /include/vector: -------------------------------------------------------------------------------- 1 | // A simplified version of the std::vector class 2 | // UnderC Development Project, 2001-2003 3 | // *add 1.2.5 Optional range checking (controlled by -R) 4 | // *fix 1.2.5 now uses delete[]; defines NULL if necessary. 5 | 6 | #ifndef _VECTOR_H 7 | #define _VECTOR_H 8 | 9 | #include 10 | 11 | #ifdef _RANGE_CHECK 12 | #define _RC(sz,i) _range_check(sz,i) 13 | #else 14 | #define _RC(sz,i) 15 | #endif 16 | 17 | namespace std { 18 | 19 | template 20 | class vector 21 | { 22 | T *m_begin; 23 | T *m_end; 24 | unsigned int m_size; 25 | unsigned int m_cap; 26 | public: 27 | typedef T * iterator; 28 | typedef const T * const_iterator; 29 | typedef T value_type; 30 | typedef size_t size_type; 31 | 32 | iterator begin() const { return m_begin; } 33 | iterator end() const { return m_end; } 34 | size_type size() const { return m_size; } 35 | size_type capacity() const { return m_cap; } 36 | bool empty() const { return m_size == 0; } 37 | 38 | T& operator[] (size_type i) { 39 | _RC(m_size,i); 40 | return m_begin[i]; 41 | } 42 | 43 | void raw_copy(T *tmp, T *old_ptr, size_type sz) { 44 | for(size_type i = 0; i < sz; i++) tmp[i] = old_ptr[i]; 45 | } 46 | 47 | void alloc(size_type new_sz, T *old_ptr) { 48 | T *tmp = new T[new_sz]; 49 | // reallocating case 50 | if (m_size && old_ptr==NULL && m_begin != NULL) { 51 | raw_copy(tmp, m_begin, m_size); 52 | delete[] m_begin; 53 | } 54 | // copying case 55 | else if (old_ptr != NULL) 56 | raw_copy(tmp, old_ptr, new_sz); 57 | m_begin = tmp; 58 | m_end = m_begin + new_sz; 59 | } 60 | 61 | void copy(const vector& v) { 62 | m_cap = v.m_cap; 63 | m_size = v.m_size; 64 | alloc(v.m_size, v.m_begin); 65 | } 66 | 67 | void grow(T *data = NULL) { 68 | m_cap = m_size + 10; 69 | alloc(m_cap, data); 70 | m_end = m_begin + m_size; 71 | } 72 | 73 | void resize(size_type sz) { 74 | T *tmp = new T[sz]; 75 | for (size_type i = 0; i < sz && i < m_size; ++i) 76 | tmp[i] = m_begin[i]; 77 | alloc(sz, tmp); 78 | m_cap = m_size = sz; 79 | } 80 | 81 | void resize(size_type sz, const value_type& t) { 82 | T *tmp = new T[sz]; 83 | for (size_type i = 0; i < sz; ++i) 84 | tmp[i] = (i >= m_size) ? m_begin[i] : t; 85 | alloc(sz, tmp); 86 | m_cap = m_size = sz; 87 | } 88 | 89 | void reserve(size_type sz) { 90 | if (sz > m_cap) 91 | { 92 | alloc(sz, m_begin); 93 | m_cap = sz; 94 | } 95 | } 96 | 97 | vector() { 98 | m_begin = NULL; 99 | m_size = 0; 100 | grow(); 101 | } 102 | 103 | explicit vector(size_type sz) { 104 | m_begin = NULL; 105 | m_size = sz; 106 | grow(); 107 | } 108 | 109 | vector(size_type sz, const value_type& t) { 110 | m_begin = NULL; 111 | m_size = sz; 112 | T *tmp = new T[sz]; 113 | for (size_type i = 0; i < sz; ++i) 114 | tmp[i] = t; 115 | grow(tmp); 116 | } 117 | 118 | vector(const vector& v) { 119 | m_size = 0; 120 | m_begin = NULL; 121 | copy(v); 122 | } 123 | 124 | vector& operator= (const vector& v) { 125 | copy(v); 126 | return *this; 127 | } 128 | 129 | bool operator== (const vector& v) const { 130 | if (m_size != v.m_size) return false; 131 | bool equal = true; 132 | T *op = v.m_begin; 133 | for(size_type i = 0; i < m_size; i++) 134 | equal = equal && m_begin[i]==op[i]; 135 | return equal; 136 | } 137 | 138 | void clear() { 139 | if (m_size > 0) { 140 | delete[] m_begin; 141 | m_size = 0; 142 | m_cap = 0; 143 | } 144 | } 145 | 146 | ~vector() { clear(); } 147 | 148 | void push_back(const value_type& t) { 149 | if (m_size+1 > m_cap) grow(); 150 | m_size++; 151 | *m_end++ = t; 152 | } 153 | 154 | iterator erase(iterator pos) 155 | { 156 | iterator it(pos); 157 | while (pos + 1 != m_end) 158 | { 159 | *pos = *(pos + 1); 160 | ++pos; 161 | } 162 | m_end--; m_size--; 163 | return it; 164 | } 165 | 166 | iterator erase(iterator i1, iterator i2) 167 | { 168 | iterator it(i1); 169 | int removed = i2 - i1; 170 | while (i2 != m_end) 171 | { 172 | *i1 = *i2; 173 | ++i1; ++i2; 174 | } 175 | m_end -= removed; 176 | m_size -= removed; 177 | return it; 178 | } 179 | 180 | template 181 | void assign(It start, It end) { 182 | clear(); 183 | for(; start != end; ++start) 184 | push_back(*start); 185 | } 186 | 187 | void pop_back() { m_end--; m_size--; } 188 | T& back() { return *(m_end-1); } 189 | T& front() { return *m_begin; } 190 | T * data() { return m_begin; } 191 | void bonzo() { } 192 | 193 | }; 194 | 195 | } // namespace std 196 | 197 | #endif 198 | -------------------------------------------------------------------------------- /include/vector.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevedonovan/UnderC/e69b44f7269b084495ae06a5829aed8ce4b5fa15/include/vector.h -------------------------------------------------------------------------------- /include/windows.h: -------------------------------------------------------------------------------- 1 | // UnderC Development Project, 2001 2 | #ifndef _WINDOWS_H 3 | #define _WINDOWS_H 4 | typedef unsigned long DWORD, *PDWORD; 5 | typedef char *LPSTR; 6 | typedef const char *LPCSTR; 7 | typedef void *PVOID; 8 | typedef int BOOL; 9 | typedef unsigned short WORD; 10 | typedef void* HWND; 11 | #define WINAPI __API 12 | 13 | #include 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /include/wininet.h: -------------------------------------------------------------------------------- 1 | // UnderC Development Project, 2001 2 | #ifndef _WININET_H 3 | #define _WININET_H 4 | #include 5 | typedef void *HINTERNET; 6 | typedef WORD INTERNET_PORT,*LPINTERNET_PORT; 7 | 8 | #define INTERNET_OPEN_TYPE_PRECONFIG 0 9 | #define INTERNET_OPEN_TYPE_DIRECT 1 10 | #define INTERNET_OPEN_TYPE_PROXY 3 11 | #define INTERNET_DEFAULT_FTP_PORT 21 12 | #define INTERNET_DEFAULT_HTTP_PORT 80 13 | #define INTERNET_SERVICE_FTP 1 14 | #define INTERNET_SERVICE_HTTP 3 15 | 16 | // flags 17 | #define INTERNET_FLAG_RELOAD 0x80000000 18 | #define INTERNET_FLAG_RAW_DATA 0x40000000 19 | #define INTERNET_FLAG_EXISTING_CONNECT 0x20000000 20 | #define INTERNET_FLAG_ASYNC 0x10000000 21 | #define INTERNET_FLAG_PASSIVE 0x08000000 22 | #define INTERNET_FLAG_NO_CACHE_WRITE 0x04000000 23 | #define INTERNET_FLAG_DONT_CACHE INTERNET_FLAG_NO_CACHE_WRITE 24 | #define INTERNET_FLAG_MAKE_PERSISTENT 0x02000000 25 | #define INTERNET_FLAG_OFFLINE 0x1000000 26 | #define INTERNET_FLAG_SECURE 0x800000 27 | #define INTERNET_FLAG_KEEP_CONNECTION 0x400000 28 | #define INTERNET_FLAG_NO_AUTO_REDIRECT 0x200000 29 | #define INTERNET_FLAG_READ_PREFETCH 0x100000 30 | #define INTERNET_FLAG_NO_COOKIES 0x80000 31 | #define INTERNET_FLAG_NO_AUTH 0x40000 32 | #define INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP 0x8000 33 | #define INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS 0x4000 34 | #define INTERNET_FLAG_IGNORE_CERT_DATE_INVALID 0x2000 35 | #define INTERNET_FLAG_IGNORE_CERT_CN_INVALID 0x1000 36 | #define INTERNET_FLAG_MUST_CACHE_REQUEST 16 37 | #define INTERNET_FLAG_RESYNCHRONIZE 0x800 38 | #define INTERNET_FLAG_HYPERLINK 0x400 39 | 40 | #define FTP_TRANSFER_TYPE_UNKNOWN 0 41 | #define FTP_TRANSFER_TYPE_ASCII 1 42 | #define FTP_TRANSFER_TYPE_BINARY 2 43 | #define FTP_TRANSFER_TYPE_MASK (FTP_TRANSFER_TYPE_ASCII | FTP_TRANSFER_TYPE_BINARY) 44 | 45 | 46 | #lib WININET.DLL 47 | // Note that UCW requires the attribute _in front_... 48 | extern "C" { 49 | WINAPI HINTERNET InternetOpenA(LPCSTR,DWORD,LPCSTR,LPCSTR,DWORD); 50 | WINAPI BOOL InternetCloseHandle(HINTERNET); 51 | WINAPI HINTERNET InternetConnectA(HINTERNET,LPCSTR,INTERNET_PORT,LPCSTR,LPCSTR,DWORD,DWORD,DWORD); 52 | WINAPI BOOL InternetReadFile(HINTERNET,PVOID,DWORD,PDWORD); 53 | WINAPI HINTERNET HttpOpenRequestA(HINTERNET,LPCSTR,LPCSTR,LPCSTR,LPCSTR,LPCSTR *,DWORD,DWORD); 54 | WINAPI BOOL HttpSendRequestA(HINTERNET,LPCSTR,DWORD,PVOID,DWORD); 55 | // FTP stuff 56 | WINAPI HINTERNET FtpFindFirstFileA(HINTERNET,LPCSTR,LPWIN32_FIND_DATA,DWORD,DWORD); 57 | WINAPI BOOL FtpGetFileA(HINTERNET,LPCSTR,LPCSTR,BOOL,DWORD,DWORD,DWORD); 58 | WINAPI BOOL FtpPutFileA(HINTERNET,LPCSTR,LPCSTR,DWORD,DWORD); 59 | WINAPI BOOL FtpDeleteFileA(HINTERNET,LPCSTR); 60 | WINAPI BOOL FtpRenameFileA(HINTERNET, LPCSTR,LPCSTR); 61 | WINAPI HINTERNET FtpOpenFileA(HINTERNET,LPCSTR,DWORD,DWORD,DWORD); 62 | WINAPI BOOL FtpCreateDirectoryA(HINTERNET,LPCSTR); 63 | WINAPI BOOL FtpRemoveDirectoryA(HINTERNET,LPCSTR); 64 | WINAPI BOOL FtpSetCurrentDirectoryA(HINTERNET,LPCSTR); 65 | WINAPI BOOL FtpGetCurrentDirectoryA(HINTERNET,LPSTR,PDWORD); 66 | WINAPI BOOL FtpCommandA(HINTERNET,BOOL,DWORD,LPCSTR,DWORD); 67 | 68 | } 69 | #define HttpSendRequest HttpSendRequestA 70 | #define InternetOpen InternetOpenA 71 | #define HttpOpenRequest HttpOpenRequestA 72 | #define InternetConnect InternetConnectA 73 | 74 | #define FtpFindFirstFile FtpFindFirstFileA 75 | #define FtpGetFile FtpGetFileA 76 | #define FtpPutFile FtpPutFileA 77 | #define FtpDeleteFile FtpDeleteFileA 78 | #define FtpRenameFile FtpRenameFileA 79 | #define FtpOpenFile FtpOpenFileA 80 | #define FtpCreateDirectory FtpCreateDirectoryA 81 | #define FtpRemoveDirectory FtpRemoveDirectoryA 82 | #define FtpSetCurrentDirectory FtpSetCurrentDirectoryA 83 | #define FtpCommand FtpCommandA 84 | 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /include/winuser.h: -------------------------------------------------------------------------------- 1 | #ifndef __WINUSER_H 2 | #define __WINUSER_H 3 | #include 4 | 5 | struct RECT { 6 | int left; 7 | int top; 8 | int right; 9 | int bottom; 10 | }; 11 | typedef RECT* LPRECT; 12 | typedef int (*WNDENUMPROC) (void*,long); 13 | 14 | #lib user32.dll 15 | extern "C" { 16 | WINAPI HWND GetActiveWindow(); 17 | WINAPI BOOL GetWindowRect(HWND,LPRECT); 18 | WINAPI BOOL MoveWindow(HWND,int,int,int,int,BOOL); 19 | WINAPI int GetWindowTextA(HWND,LPSTR,int); 20 | WINAPI BOOL SetWindowTextA(HWND,LPSTR); 21 | WINAPI HWND FindWindowA(LPSTR,LPSTR); 22 | WINAPI BOOL EnumWindows(WNDENUMPROC callback, int lparam); 23 | WINAPI int SendMessageA(HWND,int,int,int); 24 | WINAPI BOOL InvalidateRect(HWND,LPRECT,BOOL); 25 | } 26 | 27 | #lib 28 | #endif 29 | 30 | 31 | -------------------------------------------------------------------------------- /lib/string_imp.h: -------------------------------------------------------------------------------- 1 | // UnderC Development Project, 2001 2 | // A simplified standard string class 3 | 4 | #ifndef __STRING_ 5 | #define __STRING_ 6 | 7 | #include 8 | #ifndef NULL 9 | #define NULL 0 10 | #endif 11 | 12 | const int MAX_LINE=1024; 13 | 14 | #ifndef MSC_VER 15 | #define EXPORT 16 | #else 17 | #define EXPORT __declspec(dllexport) 18 | #endif 19 | 20 | #ifdef __UNDERC__ 21 | namespace std { 22 | #endif 23 | 24 | #pragma dlink string_imp.dll 25 | 26 | class EXPORT string { 27 | protected: 28 | char *m_str; 29 | unsigned int m_len; 30 | public: 31 | typedef unsigned long size_type; 32 | typedef char *iterator; 33 | typedef const char *const_iterator; 34 | enum { npos = 0xFFFFFFFF }; 35 | 36 | char *c_str() const { return m_str; } 37 | size_type length() const { return m_len; } 38 | size_type size() const { return m_len; } 39 | bool empty() const { return m_len == 0; } 40 | // *hack 0.9.5 These aren't really const methods (but!) 41 | iterator begin() const { return m_str; } 42 | iterator end() const { return m_str + m_len; } 43 | 44 | void resize(size_type sz); 45 | void append(char *s); 46 | void push_back(char ch); 47 | void copy(char *str); 48 | string(const char *str); 49 | string(const char *str, int sz); 50 | string(); 51 | string(size_type sz, char ch); 52 | string(const string& s); 53 | string& operator= (const string& s); 54 | string& operator= (char *str); 55 | string& operator+= (char *str); 56 | string& operator+= (const string& s); 57 | string& operator+= (char ch); 58 | ~string(); 59 | size_type find(char *str) const; 60 | size_type find(const string& s) const; 61 | size_type find(char ch) const; 62 | size_type rfind(char ch) const; 63 | size_type bound(size_type n) const; 64 | string substr(size_type start, size_type n = npos) const; 65 | string& replace(size_type is, size_type n, char *repl); 66 | string& replace(size_type is, size_type n, const string& repl); 67 | void insert(size_type idx, const string& repl); 68 | char& operator[] (size_type i); 69 | #ifndef __UNDERC__ 70 | char operator[] (size_type i) const; 71 | #endif 72 | 73 | int compare(const string& s) const; 74 | // *hack 0.9.7 used to be non-member, but that won't work for now! 75 | bool operator== (const string& s2) const; 76 | }; 77 | 78 | #ifdef __UNDERC__ 79 | } // namespace std 80 | #define _string std::string 81 | #else 82 | #define _string string 83 | #endif 84 | 85 | //*SJD* Currently we aren't doing overloading with functions which 86 | // span different namespaces. So putting operator+ in std would 87 | // mean being unable to overload it for any other type. 88 | EXPORT bool operator != (const _string& s1, const _string& s2); 89 | EXPORT bool operator> (const _string& s1, const _string& s2); 90 | EXPORT bool operator< (const _string& s1, const _string& s2); 91 | EXPORT _string operator+ (const _string& s1, const _string& s2); 92 | EXPORT _string operator+ (const _string& s1, char *str2); 93 | 94 | #pragma dlink 95 | 96 | std::ostream& operator<< (std::ostream& os, const std::string& s) 97 | { 98 | os << s.c_str(); 99 | return os; 100 | } 101 | 102 | std::istream& operator>> (std::istream& is, std::string& s) 103 | { char buff[MAX_LINE]; 104 | is >> buff; 105 | s = buff; 106 | return is; 107 | } 108 | 109 | std::istream& getline(std::istream& is, std::string& s) 110 | { 111 | char buff[MAX_LINE]; 112 | is.getline(buff,MAX_LINE); 113 | s = buff; 114 | return is; 115 | } 116 | 117 | #endif 118 | 119 | 120 | -------------------------------------------------------------------------------- /linenoise-LICENCE: -------------------------------------------------------------------------------- 1 | / * 2 | * * Redistributions of source code must retain the above copyright 3 | * notice, this list of conditions and the following disclaimer. 4 | * 5 | * * Redistributions in binary form must reproduce the above copyright 6 | * notice, this list of conditions and the following disclaimer in the 7 | * documentation and/or other materials provided with the distribution. 8 | * 9 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 10 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 11 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 12 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 13 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 14 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 15 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 16 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 17 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 18 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 19 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 20 | */ 21 | 22 | https://github.com/antirez/linenoise 23 | 24 | -------------------------------------------------------------------------------- /src/breakpoints.h: -------------------------------------------------------------------------------- 1 | // breakpoints.h 2 | #ifndef __BREAKPOINTS_H 3 | #define __BREAKPOINTS_H 4 | #include "classlib.h" 5 | #include "common.h" 6 | #include "engine.h" 7 | #include 8 | 9 | const int MAX_BREAKPOINTS = 20; 10 | 11 | class Breakpoint; 12 | typedef std::list BreakpointList; 13 | 14 | class Breakpoint { 15 | private: 16 | int m_ip; 17 | int m_id; 18 | int m_line; 19 | Function *m_pf; 20 | bool m_paused, m_persistent, m_set; 21 | PInstruction m_pi; 22 | Instruction m_saved_instruction; 23 | 24 | public: 25 | typedef BreakpointList::iterator iterator; 26 | 27 | Breakpoint(int id, bool persist, Function *pf, int lineno); 28 | ~Breakpoint(); 29 | 30 | Instruction saved_instruction() { return m_saved_instruction; } 31 | int line() { return m_line; } 32 | Function * function() { return m_pf; } 33 | 34 | static iterator find_in_function(Function *pf); 35 | static void toggle(char *file, int lineno, bool is_persistent, std::ostream& out); 36 | static void group(char *file, int *lines, int& sz, bool do_get); 37 | static iterator find_in_file(const string& file); 38 | static iterator end_list(); 39 | static Breakpoint *create(const string& filename, int lineno, bool persist); 40 | static Breakpoint *from_id(int id); 41 | static Breakpoint *exists_at(const string& filename, int lineno); 42 | static void remove_all(); 43 | 44 | bool set_line(int l); 45 | void set_break(); 46 | void restore_instruction(); 47 | bool execute(); 48 | }; 49 | #endif 50 | -------------------------------------------------------------------------------- /src/class.h: -------------------------------------------------------------------------------- 1 | /* CLASS.H 2 | */ 3 | 4 | #ifndef __CLASS_H 5 | #define __CLASS_H 6 | #include "table.h" 7 | #include "imports.h" 8 | #include "function.h" 9 | 10 | class NamedObject { 11 | string m_name; 12 | public: 13 | NamedObject(string name) : m_name(name) { } 14 | string name() 15 | { return m_name; } 16 | void set_name(string s) 17 | { m_name = s; } 18 | }; 19 | 20 | class Enum: public NamedObject { 21 | EntryList m_entries; 22 | PEntry m_entry; 23 | public: 24 | Enum(string name) : NamedObject(name) { } 25 | void add_entry(PEntry); 26 | Table* context(); 27 | string lookup_value(int val); 28 | PEntry entry() { return m_entry; } 29 | void entry(PEntry pe) { m_entry = pe; } 30 | }; 31 | 32 | const int MAX_VMT_ENTRIES = 250, IS_STRUCT=TABLE+10; 33 | 34 | class Function; // forward... 35 | 36 | struct MethodBody { 37 | Function* pf; 38 | string body; 39 | 40 | MethodBody(Function* _pf, string _body) 41 | : pf(_pf),body(_body) { } 42 | }; 43 | 44 | class Class: public NamedTable { 45 | protected: 46 | TypeList m_from_list, m_to_list; 47 | std::list m_friend_objects; 48 | std::list m_from_fn, m_to_fn; 49 | std::list m_vtable_slots; 50 | FunctionList m_vtable_funs; 51 | std::list m_DeferedBodies; 52 | int m_vtable_size; 53 | EntryList m_obj_list,m_field_list,m_entries; 54 | Class **m_VMT; 55 | int m_slot_id; 56 | PEntry m_base_entry; 57 | TemplateInstance *m_templ_info; 58 | int m_base_access, m_access_mode, m_abstract; 59 | bool m_simple_struct, m_has_constructors,m_finalized, m_imported, m_struct, m_is_union; 60 | Function *m_default_constructor, *m_copy_constructor, *m_destructor; 61 | ImportScheme *m_import; 62 | 63 | public: 64 | enum { NOT_RELATED = 999 }; 65 | 66 | Class(Table *parent, int access) ; 67 | void set_base_class(Class *base, int access); 68 | 69 | PEntry add(const string& name); // override Table::add() 70 | void list_entries(EntryList &el, int flags); // and Table::list_entries() 71 | Namespace *inside_namespace(); 72 | Function *default_constructor(); 73 | Function *copy_constructor(); 74 | Function *destructor(); 75 | bool has_constructors(); 76 | void add_constructor(Function *fn, bool no_implicit_type_conversion); 77 | void destructor(Function *fn); 78 | void construct_VMT(); 79 | void clear(); 80 | 81 | string constructor_name(); 82 | string destructor_name(); 83 | bool is_anonymous_union(); // *add 1.2.6 support for anonymous unions 84 | void set_anonymous_union(); 85 | 86 | bool simple_struct(); 87 | bool is_struct(); 88 | void make_struct(); 89 | 90 | // stuff to do with imported classes 91 | ImportScheme *import_scheme(); 92 | // *add 1.1.3 Directly fooling w/ the class; hack alert! 93 | void set_import_scheme(ImportScheme *is); 94 | bool imported(); 95 | int vtable_size(); 96 | bool derived_from_import(); 97 | void set_imported(); 98 | void update_vtable(void *obj); 99 | void *check_object_pointer(void *p); 100 | 101 | // generating the lists of _non-static members_ 102 | bool build_obj_list(); 103 | 104 | // auto contruction/destruction code generation 105 | void compile_methods(); 106 | void add_defered_method_body(Function* fn, char* body_buff); 107 | bool auto_construct(bool make_method); 108 | void auto_destruct(bool make_method); 109 | void auto_assign_copy(bool is_assign); 110 | void add_class_init_list(PEntry pe, PExprList pel); 111 | 112 | // inheritance relationships 113 | bool inherits_from(Class *pc); 114 | int distance_from(Class *pc); 115 | Class *base_class(); 116 | 117 | // finishing off class creation 118 | PEntry get_constructor(); 119 | void finalize(); 120 | int size(); 121 | 122 | //*TEMP* 123 | void set_from_type_list(TypeList& tl); 124 | void set_to_type_list(TypeList& tl); 125 | 126 | // user-defined conversions to & from this class 127 | void set_conversion_to(Function *fn); 128 | bool get_from_type_list(TypeList& tl); 129 | bool get_to_type_list(TypeList& tl); 130 | void copy_convert_to_list(); 131 | Function *get_conversion_to(Type t); 132 | Function *get_conversion_from(Type t); 133 | 134 | //access control 135 | void set_access_mode(int mode); 136 | int get_access_mode(); 137 | int base_access_mode(); 138 | bool is_friend_class(Class *pc); 139 | bool is_friend_function(void *fn); 140 | void add_friend_object(void *pc, bool is_class); 141 | 142 | // virtual method management 143 | Class** get_VMT(); 144 | int last_slot(); 145 | int next_slot(); 146 | bool has_VMT(); 147 | void set_slot(int id, Function *data); 148 | PFBlock get_slot(int id); 149 | void make_abstract(); 150 | bool is_abstract(); 151 | 152 | void attach_VMT(void *obj, PPClass vmt=NULL); 153 | static PPClass find_VMT(void *obj); 154 | bool has_true_VMT(); 155 | 156 | // general utilities & template info 157 | //*SJD* No longer override base routine... 158 | // void dump_entries(ostream& os, int depth); 159 | void add_line_no(const string& file, int line); 160 | static Class *generate_try_block_handler(); 161 | bool make_available(); 162 | bool is_template(); 163 | TemplateInstance *get_template(); 164 | void set_template(TemplateInstance *pti); 165 | }; 166 | 167 | typedef Class *PClass, **PPClass; 168 | 169 | 170 | #endif 171 | -------------------------------------------------------------------------------- /src/classlib.h: -------------------------------------------------------------------------------- 1 | // CLASSLIB.H 2 | // This concentrates all the assumptions about the iostreams 3 | // and string libraries being used. Personally I prefer the classic 4 | // iostreams in console mode, and a hand-rolled string; the std 5 | // versions are too expensive in compilation time and executable size. 6 | // The alternative libraries are all kept in the same directory to 7 | // prevent confusion about include paths. 8 | #ifndef _CLASSLIB_H 9 | #define _CLASSLIB_H 10 | 11 | #include 12 | 13 | 14 | # ifdef _CONSOLE 15 | // *add 1.2.4 Redirection of cmsg and cerr is by redefining them to be pointer references 16 | // (see errors.cpp for the implementation) 17 | extern std::ostream* _cmsg_out; 18 | extern std::ostream* _cerr_out; 19 | # define cmsg *_cmsg_out 20 | # define cerr *_cerr_out 21 | # else 22 | // this is how the DLL redirects output... 23 | # define cmsg str_cmsg 24 | # undef cerr 25 | # define cerr str_cerr 26 | # undef cout 27 | # define cout cmsg 28 | extern std::ostringstream str_cmsg, str_cerr; 29 | # endif 30 | 31 | 32 | // disable warnings about template names being too long for the debugger.. 33 | #pragma warning(disable:4786) 34 | #pragma warning(disable:4800) 35 | #include "mstring.h" 36 | 37 | // a useful pattern for using STL containers 38 | #define FORALL(i,ls) for(i = (ls).begin(); i != (ls).end(); ++i) 39 | 40 | // *ch 1.2.9 patch 41 | #ifndef _WIN32 42 | // iscsym() and iscsymf() are useful extensions found only on Windows 43 | #define iscsym(x) (isalnum(x) || (x) == '_') 44 | #define iscsymf(x) (isalpha(x) || (x) == '_') 45 | // ditto for itoa() 46 | char *itoa(int, char *,int); 47 | #define __STDCALL 48 | #else 49 | #define __STDCALL __stdcall 50 | #endif 51 | 52 | // *fix 1.2.7 The GCC 3.2 library is more uptodate, and doesn't 53 | // have nocreate. However, for earlier versions we do need it explicitly! 54 | #if __GNUC__ == 3 55 | #define IOS_IN_FLAGS ios::in 56 | #else 57 | #define IOS_IN_FLAGS ios::nocreate 58 | #endif 59 | 60 | #endif 61 | 62 | -------------------------------------------------------------------------------- /src/code.h: -------------------------------------------------------------------------------- 1 | // CODE.H 2 | #ifndef __CODE_H 3 | #define __CODE_H 4 | 5 | typedef std::list InstructionList; 6 | typedef InstructionList::iterator LI; 7 | typedef int (*CALLFN)(); 8 | 9 | class UCContext; 10 | 11 | class Label { 12 | int m_offset; 13 | InstructionList m_refs; 14 | UCContext* m_code; 15 | Table* m_context; 16 | public: 17 | Label(UCContext *code) 18 | { m_offset = -1; m_code = code; m_context = NULL; } 19 | 20 | void context(Table* cntxt) { m_context = cntxt; } 21 | Table* context() { return m_context; } 22 | bool addr_is_set() { return m_offset > -1; } 23 | void here(int offs = 0); 24 | int addr(); 25 | void remove(Instruction *pi); 26 | void patch_with_NOP(); 27 | }; 28 | 29 | 30 | typedef std::list IntList; 31 | 32 | class SwitchBlock { 33 | protected: 34 | IntList m_list; 35 | int m_default_jmp; 36 | UCContext *m_code; 37 | Instruction *m_start; 38 | public: 39 | SwitchBlock(UCContext *code); 40 | void add_jump(int val); 41 | void add_default(); 42 | SwitchBlock *construct(); 43 | }; 44 | 45 | struct JIncBlock { 46 | int num; 47 | int idx; 48 | int size; 49 | int *ptr; 50 | int jmp; 51 | int flags; 52 | }; 53 | 54 | class ConstructBlock { 55 | private: 56 | PClass cls; 57 | PPClass vmt; 58 | int no,sz; 59 | PFBlock pfb; 60 | int flags; 61 | public: 62 | static int make(PExpr er, int sz, bool is_dynamic, FBlock *pfb); 63 | PPClass get_VMT() { return vmt; } 64 | bool dynamic() { return flags & 2; } 65 | bool load_ODS() { return flags & 1; } 66 | bool static_object() { return flags & 4; } 67 | PFBlock fblock() { return pfb; } 68 | PClass class_ptr() { return cls; } 69 | int size() { return sz; } 70 | int num() { return no; } 71 | }; 72 | 73 | 74 | const int LVALUE = 1, DROP_VALUE = 2, AS_PTR = 4, AS_REF = 8; 75 | 76 | class UCContext: public CodeGenerator { 77 | public: 78 | static void init(); 79 | static int builtin_conversion(Type t, Type te); 80 | void emit(int opcode, PExpr e); 81 | void emit(int opcode, int rm=0, int data=0); 82 | void emit_data_instruction(int opcode, unsigned long data); 83 | void emit_push_int(int sz); 84 | void emit_reference(PExpr ex, int flags, int tcode); 85 | void jump(int op, Label *lbl); 86 | void emit_stack_op(int op, Type t); 87 | void emit_type_instr(int opcode, Type t); 88 | void emit_except_throw(Type t); 89 | void emit_dynamic_cast(Type t); 90 | void emit_return(Type rt); 91 | void emit_native_function_call(Function *pfn, CALLFN fn); 92 | void compile(PExpr ex, int flags = 0); 93 | }; 94 | 95 | 96 | #endif 97 | 98 | -------------------------------------------------------------------------------- /src/config.h: -------------------------------------------------------------------------------- 1 | /* This file is automatically generated by configure. Do not edit */ 2 | #define UC_HOME "/home/steve/c/UnderC" 3 | -------------------------------------------------------------------------------- /src/configure: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #----------------------------------------------------------------------- 3 | # underC configure script to generate makefile from makefile.in 4 | # Charles F. Randall, cfr@pobox.com 5 | #----------------------------------------------------------------------- 6 | # Extract _UCV_ from version.h for use in makefile 7 | # - find the line, print the third field, strip the double quotes 8 | version_file=version.h 9 | UC_VERSION=`awk '/^[ \t]*#define[ \t]+_UCV_[ \t]+/ { print $3}' $version_file \ 10 | | sed 's/\"//g'` 11 | 12 | if [ -z "$UC_VERSION" ] 13 | then 14 | echo Unable to extract _UCV_ from $version_file 15 | fi 16 | echo Configuring underC version $UC_VERSION ... 17 | 18 | # Set UC_HOME based on current directory 19 | # - get pwd and chop off last directory (same as .. from here) 20 | UC_HOME=`pwd | sed 's|/src$||'` 21 | 22 | if [ -z "$UC_HOME" ] 23 | then 24 | echo "Unable to determine UC_HOME (pwd or sed failed?)" 25 | exit 1 26 | fi 27 | echo Setting UC_HOME to $UC_HOME 28 | 29 | # Looks like a BSD variant? 30 | uname -s | grep BSD > /dev/null 31 | if [ $? = 0 ] 32 | then 33 | BSD="BSD=1" 34 | fi 35 | 36 | # generating config.h 37 | config_h="config.h" 38 | rm -f $config_h 39 | echo "/* This file is automatically generated by configure. Do not edit */" \ 40 | > $config_h || ("Could not create $config_h. Exiting" && exit 1) 41 | echo "#define UC_HOME \"$UC_HOME\"" >> $config_h 42 | 43 | # replace variables in makefile.in 44 | echo Generating makefile from makefile.in 45 | tmpfile=makefile.$$ 46 | sed "s|\@\@UC_VERSION\@\@|$UC_VERSION|g; \ 47 | s|\@\@UC_HOME\@\@|$UC_HOME|g; 48 | s|\@\@BSD\@\@|$BSD|g;" \ 49 | makefile.in > $tmpfile \ 50 | && mv $tmpfile makefile && echo Done. Now run make. && exit 51 | echo "Substitution failed. Exiting." 52 | rm -f $tmpfile 53 | exit 1 54 | -------------------------------------------------------------------------------- /src/directcall.h: -------------------------------------------------------------------------------- 1 | // DIRECTCALL.H 2 | #ifndef __DIRECTCALL_H 3 | #define __DIRECTCALL_H 4 | 5 | typedef int (*CALLFN) (void); 6 | 7 | // flags for calling callfn() 8 | enum { 9 | DC_CDECL = 1, 10 | DC_QWORD = 2, 11 | DC_NOWORD = 4, 12 | DC_RET_OBJ = 8, 13 | DC_RET_VAL = 16 + 8 14 | }; 15 | 16 | class Function; 17 | 18 | struct NFBlock { 19 | CALLFN pfn; // the function to be called 20 | int nargs; // dwords in call (-1 means use TOS) 21 | int flags; // cdecl or stdcall? returns dword or qword? 22 | static int create(Function *pfn, CALLFN fn); 23 | }; 24 | 25 | void callfn(CALLFN fn, int args[], int argc, void *optr, int flags, void *buff); 26 | 27 | #include "types.h" 28 | struct Sig { 29 | Type m_type; 30 | char *m_arg_name; 31 | Sig(Type t) : m_type(t),m_arg_name(NULL) {} 32 | Sig& operator << (Type t); 33 | Sig& operator << (char *arg_name); 34 | void set_const(bool t); 35 | }; 36 | 37 | #define IMPLICIT_LINK ((void *)-1) 38 | 39 | namespace Builtin { 40 | void init(); 41 | int alloc_size(void *p); 42 | void bad_ptr_check(void *p); 43 | FBlock *imported_fblock_from_function(void *pfn); 44 | FBlock *import_vmethod(CALLFN fn, PFBlock pf); 45 | bool add_dll_function(Function *pfn, int modifier, string& name); 46 | void *get_dll_handle(); 47 | void set_direct_import(void* p); 48 | void set_dll_handle(void *dl); 49 | void unload_lib(void *hlib); 50 | bool set_current_lib_file(char *file); 51 | string get_current_lib_file(); 52 | void finis(); 53 | void *generate_native_stub(Function *pfn); 54 | int range_check_function(); 55 | 56 | bool using_ordinal_lookup(); 57 | bool lookup_is_ordinal(); 58 | int lookup_ordinal(const char *name); 59 | bool generate_ordinal_lookup(const char *index_file); 60 | void cleanup_ordinal_lookup(); 61 | } 62 | 63 | 64 | #endif 65 | 66 | -------------------------------------------------------------------------------- /src/dissem.cpp: -------------------------------------------------------------------------------- 1 | /* DISSEM.CPP 2 | * Stackcode Dissembler 3 | * UnderC C++ interpreter 4 | * Steve Donovan, 2001 5 | * This is GPL'd software, and the usual disclaimers apply. 6 | * See LICENCE 7 | */ 8 | #include "common.h" 9 | #include "opcodes.h" 10 | #include "breakpoints.h" 11 | #include "directcall.h" 12 | 13 | extern const Instruction *end_of_code; // shared w/ ENGINE 14 | extern char *mDataSeg; 15 | 16 | string get_opcode_name(int op); // at end of this module... 17 | 18 | char *data_ptr(int offs) 19 | { return mDataSeg + offs; } 20 | 21 | void dissemble(PFBlock fb) 22 | { 23 | Opcodes opcode; 24 | int rmode,rdata, k = 0; 25 | string name; 26 | Instruction *pi = fb->pstart; 27 | while (pi != end_of_code) { 28 | opcode = (Opcodes)pi->opcode; 29 | // *add 1.2.4 HALT+data is not always a breakpoint! 30 | // (it is used as a NOP + ) 31 | if (opcode == HALT) { 32 | if (pi->data < MAX_BREAKPOINTS) { 33 | Breakpoint *pb = Breakpoint::from_id(pi->data); 34 | Instruction ai = pb->saved_instruction(); 35 | std::cout << "*"; 36 | opcode = (Opcodes)ai.opcode; 37 | rmode = ai.rmode; rdata = ai.data; 38 | } else { opcode = NOP; rdata = pi->data; } 39 | } else { 40 | rmode = pi->rmode; rdata = pi->data; 41 | } 42 | name = get_opcode_name(opcode); 43 | std::cout << k++ << ' ' << name << '\t'; 44 | if (opcode == CCALL || opcode == CALL || opcode == CALLD || opcode == CALLN) { 45 | FBlock* pfb; 46 | void *data = data_ptr(rdata); 47 | if (opcode == CALLN) 48 | pfb = Builtin::imported_fblock_from_function((void*)((NFBlock *)data)->pfn); 49 | else pfb = PFBlock(data_ptr(rdata)); 50 | if (pfb) Function::from_fun_block(pfb)->dump(std::cout); 51 | } else 52 | if (opcode == JSWITCH) { 53 | int *swb = (int *)data_ptr(rdata); 54 | int sz = *swb++; 55 | int def = *swb++; 56 | std::cout << '(' << sz << ',' << def << ") "; 57 | for (int i = 0; i < sz; i++) std::cout << *swb++ << ' ' << *swb++ << ' '; 58 | } 59 | else 60 | if (opcode == TOSD || opcode == TPODS) { 61 | PClass pc = *(PClass *)data_ptr(rdata); 62 | std::cout << pc->name(); 63 | } 64 | else { 65 | if (rmode) 66 | switch(rmode) { 67 | case DIRECT: std::cout << "D "; break; 68 | case SREL: std::cout << "R "; break; 69 | case OREL: std::cout << "S "; break; 70 | } 71 | if (rdata != 0) std::cout << rdata; 72 | } 73 | std::cout << std::endl; 74 | if (opcode == RET || opcode == RETI || opcode == RETD) break; 75 | pi++; 76 | } 77 | } 78 | 79 | #include 80 | typedef std::map NameMap; 81 | NameMap opc_map; 82 | 83 | string get_opcode_name(int op) 84 | { 85 | return opc_map[op]; 86 | } 87 | 88 | void opcode_add(char *name, int id) 89 | { 90 | opc_map[id] = name; 91 | } 92 | 93 | #include "opcodes.h" 94 | 95 | #define TOK(n) 96 | #define TNAME(n) 97 | 98 | void dissembler_init() 99 | { 100 | #define OP0(n) opcode_add(#n,n); 101 | #define OP1 OP0 102 | #define JOP(n) opcode_add(#n,n); 103 | # include "ops.h" 104 | } 105 | 106 | -------------------------------------------------------------------------------- /src/eh.h: -------------------------------------------------------------------------------- 1 | // Win32 Exception stuff 2 | 3 | typedef void (__cdecl *terminate_function)(); 4 | typedef void (__cdecl *unexpected_function)(); 5 | typedef void (__cdecl *terminate_handler)(); 6 | typedef void (__cdecl *unexpected_handler)(); 7 | 8 | struct _EXCEPTION_POINTERS; 9 | typedef void (__cdecl *_se_translator_function)(unsigned int, struct _EXCEPTION_POINTERS*); 10 | 11 | _CRTIMP _se_translator_function __cdecl _set_se_translator(_se_translator_function); 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/engine.h: -------------------------------------------------------------------------------- 1 | // ENGINE.H 2 | #ifndef __ENGINE_H 3 | #define __ENGINE_H 4 | 5 | #include "class.h" 6 | 7 | struct FBlock; 8 | 9 | struct ArgBlock { 10 | char *OPtr; 11 | int no; 12 | int values[20]; 13 | int ret1; 14 | double ret2; 15 | long ret_addr; 16 | long esi_ptr; 17 | long edi_ptr; 18 | int flags; 19 | }; 20 | 21 | namespace Engine { 22 | bool paused(); 23 | bool running(); 24 | void kill(int retcode = 0); 25 | void object_ptr(void *); 26 | void *object_ptr(); 27 | char **object_ptr_addr(); 28 | int __STDCALL execute(FBlock *fb,int flags = 0, ArgBlock *xargs = NULL); 29 | int __STDCALL stub_execute(FBlock* _fb, int flags, ArgBlock *xargs); 30 | void set_data_seg(void *ptr); 31 | void global_unwind(); 32 | void set_frame(int i,bool verbose); 33 | void attach_main_context(char *fct); 34 | int retval(); 35 | bool set_single_stepping(bool yesno); 36 | void reset_single_stepping(); 37 | enum {RESUME=1,ARGS_PASSED=2,METHOD_CALL=4,RETURN_32=8,RETURN_64=16,FROM_OUTSIDE=32}; 38 | 39 | }; 40 | 41 | const int TMP_BUFF_SIZE = 24; 42 | 43 | typedef unsigned int uint; 44 | 45 | // 32-bit instruction record 46 | struct Instruction { 47 | uint opcode: 8; 48 | uint rmode: 2; 49 | int data: 22; 50 | }; 51 | typedef Instruction *PInstruction; 52 | 53 | // these functions define the Virtual Method Table structure of UC 54 | 55 | class Class; 56 | typedef Class **PPClass; 57 | 58 | inline PPClass *VMT(void *p) 59 | { 60 | return (PPClass *)( (char *)p - 4 ); 61 | } 62 | 63 | 64 | ///// interface used by the parser to drive the code generation 65 | const int CODE_BUFFSIZE = 1000; 66 | class CodeGenerator { 67 | Instruction _code_buff_[CODE_BUFFSIZE]; 68 | Instruction *pcode; 69 | int NC, mTotal; 70 | 71 | public: 72 | 73 | CodeGenerator() : NC(0), mTotal(0), pcode(_code_buff_) { } 74 | 75 | void begin_code(); 76 | Instruction *current_pi(); 77 | Instruction *last_pi(); 78 | int total_instructions(); 79 | int ip_offset(); 80 | void backspace(); 81 | void emitc(int opc, RMode rm=NONE, int data=0); 82 | void out(Instruction *is); 83 | Instruction *end_code(); 84 | static Instruction *instruction_with_pointer(int opcode, void *ptr); 85 | // *add 1.2.3a Returns non-NULL ptr to instruction if this function 86 | // has exactly one instruction 87 | static Instruction* has_one_instruction(Function* pf); 88 | }; 89 | 90 | struct CatchBlock { 91 | Type type; 92 | int ip_offset; 93 | }; 94 | 95 | typedef std::list CatchBlockList; 96 | class Label; 97 | 98 | class CatchHandler { 99 | private: 100 | CatchBlockList m_catch_blocks; 101 | FBlock *m_fb; 102 | Label *m_end_label; 103 | void *m_thrown_object; 104 | Type m_thrown_type; 105 | public: 106 | CatchHandler(FBlock *fb); 107 | void add_catch_block(Type t, int ip_offs); 108 | int match_thrown_object(Type t, void *obj); 109 | 110 | Label *label() { return m_end_label; } 111 | FBlock *fun_block() { return m_fb; } 112 | void *thrown_object() { return m_thrown_object; } 113 | Type thrown_type() { return m_thrown_type; } 114 | 115 | }; 116 | 117 | 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /src/engine.patch: -------------------------------------------------------------------------------- 1 | *** engine.cpp Thu Mar 21 10:42:23 2002 2 | --- new/engine.cpp Sat Mar 23 12:27:15 2002 3 | *************** 4 | *** 21,31 **** 5 | #endif 6 | 7 | // #define TRACK_ODS 8 | ! #ifndef __linux__ 9 | #define EXPORT extern "C" __declspec(dllexport) 10 | - #else 11 | - #define EXPORT extern "C" __attribute__((dllexport)) 12 | - #endif 13 | EXPORT char *sh_fun(); // debug function 14 | 15 | int current_ip(); 16 | --- 21,28 ---- 17 | #endif 18 | 19 | // #define TRACK_ODS 20 | ! // 21 | #define EXPORT extern "C" __declspec(dllexport) 22 | EXPORT char *sh_fun(); // debug function 23 | 24 | int current_ip(); 25 | *************** 26 | *** 290,302 **** 27 | Instruction *ppcode; 28 | FBlock *fb; 29 | int *baseSP; 30 | ! bool cntxt_pushed; 31 | 32 | void set(Instruction *_ppcode, FBlock *_fb, int *_baseSP, bool cpushed) 33 | { ppcode = _ppcode; fb = _fb; baseSP = _baseSP; cntxt_pushed = cpushed; } 34 | 35 | ! void get(Instruction *&_ppcode, FBlock *&_fb, int *&_baseSP, bool& cpushed) 36 | ! { _ppcode = ppcode; _fb = fb; _baseSP = baseSP; cpushed = cntxt_pushed; } 37 | 38 | }; 39 | 40 | --- 287,300 ---- 41 | Instruction *ppcode; 42 | FBlock *fb; 43 | int *baseSP; 44 | ! bool cntxt_pushed; 45 | ! ArgBlock *xargs; 46 | 47 | void set(Instruction *_ppcode, FBlock *_fb, int *_baseSP, bool cpushed) 48 | { ppcode = _ppcode; fb = _fb; baseSP = _baseSP; cntxt_pushed = cpushed; } 49 | 50 | ! void get(Instruction *&_ppcode, FBlock *&_fb, int *&_baseSP, bool& cpushed, ArgBlock *&args) 51 | ! { _ppcode = ppcode; _fb = fb; _baseSP = baseSP; cpushed = cntxt_pushed; args = xargs; } 52 | 53 | }; 54 | 55 | *************** 56 | *** 1105,1123 **** 57 | Instruction *old_ppcode = ppcode; 58 | int *old_mSP = mSP; 59 | try { 60 | ! if (flags & ARGS_PASSED) { // only if execute() is called from outside UC 61 | ! if (flags & METHOD_CALL) opush(xargs->OPtr); 62 | ! for(int i=0,n = xargs->no; i < n; i++) // these are globals set by the native stub!! 63 | push(xargs->values[i]); 64 | } 65 | - 66 | if (flags & RESUME) { 67 | bool context_pushed; 68 | ! resume_state.get(ppcode,fb,baseSP, context_pushed); 69 | ! if (context_pushed) Parser::state.pop_context(); 70 | ! resume_state.fb = NULL; // flag us as NOT paused 71 | Parser::immediate_code_ptr(old_immediate_code); // and restore immediate execution context! 72 | - //dissemble(Parser::immediate_code_block()); 73 | } else { 74 | mStartFB = _fb; 75 | fb = START_FB; 76 | --- 1103,1122 ---- 77 | Instruction *old_ppcode = ppcode; 78 | int *old_mSP = mSP; 79 | try { 80 | ! if (flags & ARGS_PASSED) { // only if execute() is called from outside UC 81 | ! xargs->flags = flags; // *fix 1.1.1 save flags and arg block so we can resume properly! 82 | ! resume_state.xargs = xargs; 83 | ! if (flags & METHOD_CALL) opush(xargs->OPtr); // the 'this' pointer 84 | ! for(int i=0,n = xargs->no; i < n; i++) // these are set by the native stub!! 85 | push(xargs->values[i]); 86 | } 87 | if (flags & RESUME) { 88 | bool context_pushed; 89 | ! resume_state.get(ppcode,fb,baseSP,context_pushed,xargs); 90 | ! if (xargs) flags = xargs->flags; // *fix 1.1.1 restore flags and arg block as well! 91 | ! if (context_pushed) Parser::state.pop_context(); // i.e, we were halted by a breakpoint, which pushed the context.. 92 | ! resume_state.fb = NULL; // flag us as NOT paused 93 | Parser::immediate_code_ptr(old_immediate_code); // and restore immediate execution context! 94 | } else { 95 | mStartFB = _fb; 96 | fb = START_FB; 97 | -------------------------------------------------------------------------------- /src/entry.h: -------------------------------------------------------------------------------- 1 | // ENTRY.H 2 | 3 | #ifndef __ENTRY_H 4 | #define __ENTRY_H 5 | #include "types.h" 6 | 7 | struct Entry { 8 | string name; // ref. to the actual name 9 | Type type; // actual type 10 | RMode rmode; // address mode 11 | int data; // usually an offset 12 | int size; // total size of object (useful for arrays) 13 | Table *context; // used to store a ptr to the owner of this entry! 14 | 15 | bool m_typename; 16 | int m_access; 17 | 18 | bool is_typename() { return m_typename; } 19 | bool is_constant() { return ( name.size() == 0 ); } 20 | bool is_class() { return m_typename && size == 0; } 21 | bool is_typedef() { return m_typename && size != 0; } 22 | bool is_namespace() { return is_class() && data != 0; } 23 | void set_class() { size = 0; } 24 | int access() { return m_access; } 25 | void set_access(int a) { m_access = a; } 26 | void *global_ptr(); 27 | char* object_ptr(char *obj); 28 | bool is_stack_relative() { return rmode == SREL;} 29 | bool is_direct() { return rmode==DIRECT; } 30 | bool is_object_relative() { return rmode >= OREL; } 31 | bool is_bitfield() { return rmode == OREL_F; } 32 | void set_bit_field(int offs, int bit_offs, int bit_size); 33 | void get_bit_field(int& offs, int& bit_offs, int& bit_size); 34 | 35 | }; 36 | #endif 37 | 38 | -------------------------------------------------------------------------------- /src/errors.h: -------------------------------------------------------------------------------- 1 | #ifndef __ERRORS_H 2 | #define __ERRORS_H 3 | namespace Errors { 4 | char *get_redirect_buffer(int which); 5 | void redirect_output(bool to_buff, bool main_console = true); 6 | bool output_is_redirected(); 7 | int get_stop_position(char *filename); 8 | void set_halt_state(string msg, string fname, string file, int lineno, bool was_error); 9 | void reset_error_state(); 10 | int check_output(); 11 | } 12 | #endif 13 | 14 | -------------------------------------------------------------------------------- /src/ex_fscanf.cpp: -------------------------------------------------------------------------------- 1 | /* A simplified vfscanf that uses a custom text grabber 2 | * UnderC C++ interpreter 3 | * Steve Donovan, 2001 4 | * This is GPL'd software, and the usual disclaimers apply. 5 | * See LICENCE 6 | */ 7 | 8 | -------------------------------------------------------------------------------- /src/ex_vfscanf.cpp: -------------------------------------------------------------------------------- 1 | /* A simplified vfscanf that uses a custom text grabber 2 | * UnderC C++ interpreter 3 | * Steve Donovan, 2001 4 | * This is GPL'd software, and the usual disclaimers apply. 5 | * See LICENCE 6 | */ 7 | 8 | #include "classlib.h" 9 | #include "ex_vfscanf.h" 10 | 11 | #include 12 | #include 13 | 14 | struct UCString { 15 | char *m_str; 16 | int m_sz; 17 | }; 18 | 19 | static UCString in_buff; 20 | static string out_buff; 21 | void *_str_in = (void *)&in_buff, *_str_out = (void *)&out_buff; 22 | 23 | void str_gets(char *buff) 24 | { 25 | char *ps = in_buff.m_str, *op = buff; 26 | if (! *ps) ps = NULL; 27 | else { 28 | while (*ps && *ps != '\n') *op++ = *ps++; 29 | } 30 | *op++ = '\0'; 31 | in_buff.m_str = ps; 32 | } 33 | 34 | int str_eof(int) 35 | { 36 | return in_buff.m_str == NULL; 37 | } 38 | 39 | #ifndef _WCON 40 | // NOTE(10); 41 | int con_fprintf(FILE *out, char *fmt, ...) 42 | { 43 | va_list ap; 44 | int ich; 45 | va_start(ap,fmt); 46 | if (out==_str_out) ich = str_vprintf(fmt,ap); // NOTE(10) wuz ap 47 | else ich = vfprintf(out,fmt,ap); 48 | va_end(ap); 49 | return ich; 50 | } 51 | 52 | char *con_fgets(char *buff, int sz, FILE *in) 53 | { 54 | if(in==_str_in) str_gets(buff); 55 | else { 56 | if (! fgets(buff,sz,in)) 57 | return NULL; 58 | } 59 | return buff; 60 | } 61 | 62 | int con_fscanf(FILE *in, char *fmt,...) 63 | // ONLY used to do i/o on strings! 64 | { 65 | va_list ap; 66 | int ret; 67 | va_start(ap,fmt); 68 | ret = ex_vfscanf(str_getter,fmt,ap); 69 | va_end(ap); 70 | return ret; 71 | } 72 | #endif 73 | 74 | //NOTE(10) 75 | 76 | void *_new_ex(int sz); // in directcall.cpp 77 | 78 | void *str_cpy(void *_ptr, int mode) 79 | { 80 | UCString *ptr = (UCString *)_ptr; 81 | switch(mode) { 82 | case 1: // copy user string into our input buffer 83 | in_buff = *ptr; 84 | break; 85 | case 2: // copy our output buffer to user string 86 | // *fix 1.1.0 Use the official allocator, since this will be disposed of automatically... 87 | ptr->m_str = (char *)_new_ex(out_buff.length()+1); 88 | strcpy(ptr->m_str, out_buff.c_str()); 89 | ptr->m_sz = out_buff.length(); 90 | break; 91 | case 3: // copy user string to our output buffer 92 | out_buff = ptr->m_str; 93 | break; 94 | } 95 | return _ptr; 96 | } 97 | 98 | static char con_obuff[1024]; //*NOTE* 99 | 100 | // NOTE(10) 101 | int str_vprintf(char *fmt,va_list args) 102 | { 103 | int ich = vsprintf(con_obuff,fmt,args); 104 | out_buff += con_obuff; 105 | return ich; 106 | } 107 | 108 | char *skip_ws(char *s) 109 | { 110 | while (*s != '\0' && isspace(*s)) s++; 111 | return s; 112 | } 113 | 114 | char *str_getter(char *p) 115 | { 116 | if (p != NULL) in_buff.m_str = p; 117 | else { 118 | p = in_buff.m_str; 119 | if (p == NULL) return NULL; 120 | p = skip_ws(p); 121 | if (*p == '\0') p = NULL; 122 | in_buff.m_str = p; 123 | } 124 | return p; 125 | } 126 | 127 | int ex_vfscanf(BUFFGETTER getter, char *fmt, va_list va) 128 | { 129 | // A simplified vfscanf implementation, 130 | // Only recognizes %d, %u, %ld, %lu, %lg, %f, %lf and 131 | // whitespace. 132 | int k=0; 133 | char *s = NULL; 134 | 135 | while (1) 136 | { 137 | if (fmt[0]=='%') { 138 | int n; 139 | s = getter(NULL); 140 | if (s == NULL) return 0; 141 | if (fmt[1]=='d') { 142 | k+=sscanf(s,"%d%n",va_arg(va,int*),&n); 143 | s+=n; 144 | fmt+=2; 145 | } else 146 | if (fmt[1]=='s') { 147 | k+=sscanf(s,"%s%n",va_arg(va,char*),&n); 148 | s+=n; 149 | fmt+=2; 150 | } 151 | else if (fmt[1]=='u') { 152 | k+=sscanf(s,"%u%n",va_arg(va,int*),&n); 153 | s+=n; 154 | fmt+=2; 155 | } 156 | else if (fmt[1]=='l' && fmt[2]=='d') { 157 | k+=sscanf(s,"%ld%n",va_arg(va,long*),&n); 158 | s+=n; 159 | fmt+=3; 160 | } 161 | else if (fmt[1]=='l' && fmt[2]=='u') { 162 | k+=sscanf(s,"%lu%n",va_arg(va,long*),&n); 163 | s+=n; 164 | fmt+=3; 165 | } 166 | else if (fmt[1]=='l' && (fmt[2]=='g' || fmt[2]=='f')) { 167 | double *ptr = va_arg(va,double*); 168 | k+=sscanf(s,"%lg%n",ptr,&n); 169 | s+=n; 170 | fmt+=3; 171 | } 172 | else if (fmt[1]=='f') { 173 | k+=sscanf(s,"%f%n",va_arg(va,float*),&n); 174 | s+=n; 175 | fmt+=2; 176 | } 177 | else { 178 | fprintf(stderr,"scanf: unsupported format '%s'\n",fmt); 179 | return k; 180 | }; 181 | } 182 | else if (isspace(*fmt)) { 183 | //s = skip_and_grab(in,s); 184 | fmt++; 185 | } 186 | else if (*fmt=='\0') { 187 | return k; 188 | } else { 189 | fprintf(stderr,"scanf: unexpected char in format '%s'\n",fmt); 190 | return k; 191 | } 192 | getter(s); 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/ex_vfscanf.h: -------------------------------------------------------------------------------- 1 | /* A simplified vfscanf that uses a custom text grabber 2 | * UnderC C++ interpreter 3 | * Steve Donovan, 2001 4 | * This is GPL'd software, and the usual disclaimers apply. 5 | * See LICENCE 6 | */ 7 | #ifndef __EX_VFSCANF 8 | #define __EX_VFSCANF 9 | #include 10 | #include 11 | 12 | typedef char *( *BUFFGETTER )(char *); 13 | 14 | int ex_vfscanf(BUFFGETTER getter, char *fmt, va_list va); 15 | 16 | int con_fprintf(FILE *out, char *fmt, ...); 17 | char *con_fgets(char *buff, int sz, FILE *in); 18 | int con_fscanf(FILE *in, char *fmt,...); 19 | 20 | int str_vprintf(char *fmt,va_list args); 21 | char *skip_ws(char *s); 22 | char *str_getter(char *p); 23 | void str_gets(char *buff); 24 | int str_eof(int); 25 | void *str_cpy(void *_ptr, int mode); 26 | 27 | extern void *_str_out, *_str_in; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/export.h: -------------------------------------------------------------------------------- 1 | // export.h 2 | 3 | #ifndef __EXPORT_H 4 | #define __EXPORT_H 5 | 6 | #define CEXPORT extern "C" EXPORT 7 | 8 | // *ch 1.2.9 patch 9 | #ifndef _WIN32 10 | # ifndef __BEOS__ 11 | # define __declspec(x) 12 | # endif 13 | # define XAPI 14 | #else 15 | # define XAPI __stdcall 16 | #endif 17 | 18 | #ifdef WITHIN_UC 19 | # define EXPORT __declspec(dllexport) 20 | #else 21 | # ifdef __UNDERC__ 22 | # include 23 | using std::string; 24 | # define EXPORT 25 | # else 26 | // using this to import into a C++ prg from the DLL 27 | # define EXPORT __declspec(dllimport) 28 | # include "mstring.h" 29 | # endif 30 | #endif 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/expressions.h: -------------------------------------------------------------------------------- 1 | // Expressions.h 2 | 3 | #ifndef __EXPRESSIONS_H 4 | #define __EXPRESSIONS_H 5 | #include "types.h" 6 | #include "function.h" 7 | #include 8 | 9 | const int NIL = 0, EXPR = -1, IREF = 1, BCAST = 2, ECONST = 3; 10 | // extra operations MUST NOT CONFLICT w/ tparser.h! 11 | // Fortunately, the value of TOKEN is 258, so there's plenty 12 | // of room. 13 | const int INCR_PTR = 10, DECR_PTR = 11, COPY_BLOCK = 12, 14 | CCONTEXT = 13, INIT_REF = 14, METHOD_CALL = 15, 15 | EXPR_METHOD = 16, APPEND = 17, 16 | DYNACAST = 18, REF_STUB = 19, 17 | DCALL = 20, PASS_BY_VALUE = 21, 18 | DCONTEXT = 22, VCONTEXT = 23, FCONTEXT = 24, 19 | LAST_OP = 100 20 | ; 21 | 22 | // forward dcl of Expr, etc in function.h above! 23 | // note the convention that a NULL function is 24 | // an expr list. 25 | class Expr { 26 | protected: 27 | int m_op; 28 | Type m_type; // type of this item or subexpression 29 | PExpr m_arg1; 30 | PExpr m_arg2; 31 | public: 32 | Expr(int op=0,Type type=t_void,void *arg1=NULL,void *arg2=NULL) 33 | : m_op(op), m_type(type), m_arg1((PExpr)arg1),m_arg2((PExpr)arg2) 34 | {} 35 | 36 | int op() { return m_op; } 37 | void set_op(int op){ m_op = op; } 38 | Type type() { return m_type; } 39 | void set_type(Type t) { m_type = t; } 40 | bool is_expr() { return m_op == EXPR; } 41 | bool is_entry() { return m_op == IREF; } 42 | bool is_nil() { return m_op == NIL; } 43 | bool is_const() { return m_op == ECONST; } 44 | bool is_function(); 45 | bool is_variable(); 46 | bool is_bcast() { return m_op == BCAST; } 47 | bool is_expr_list(); 48 | bool is_brace_list(); 49 | PExpr arg1() { return m_arg1; } 50 | PExpr arg2() { return m_arg2; } 51 | void arg1(PExpr e) { m_arg1 = e; } 52 | void arg2(PExpr e) { m_arg2 = e; } 53 | PEntry entry() { /*assert(is_entry());*/ return (PEntry)m_arg1; } 54 | PExpr expr() { /*assert(is_expr());*/ return m_arg1; } 55 | Function *function() { /*assert(is_function());*/ return (Function *)m_arg1; } 56 | PExprList arg_list() { return (PExprList) m_arg2; } 57 | PExprList expr_list() { return arg_list(); } 58 | string name(); 59 | }; 60 | 61 | namespace Expressions { 62 | 63 | void init(); 64 | bool is_atom(PExpr e); 65 | void dump(std::ostream& os, PExpr e); 66 | PExpr clone (PExpr e); 67 | PExpr entry_op(PEntry pe); 68 | PExpr make_op(int op,Type type, PExpr e1, PExpr e2 = NULL); 69 | 70 | PEntry ExprToEntry(PExpr e); 71 | Type type_of(PExpr e); 72 | PFunction lookup_function(char *name); 73 | int call_main(int argc, char **argv); 74 | void stop_main(bool is_error=true); 75 | PExprList expr_list(PExpr e1=NULL, PExpr e2=NULL); 76 | PExpr function_call(const char* name, PExprList pel); 77 | 78 | // functions to build up expression trees 79 | PExpr arith_op(int op, PExpr e1, PExpr e2); 80 | PExpr bin_op(int op, PExpr e1, PExpr e2); 81 | PExpr delete_op(PExpr e1, bool is_arr); 82 | PExpr initialize_op(PEntry pe, PExpr er, PExprList pel, int ctype); 83 | PExpr construct_op(PClass pc, PExprList pel, bool check_abstract = true); 84 | PExpr init_ref_op(PExpr el, PExpr er); 85 | PExpr new_op(Type t, PExpr e, PExprList pel); 86 | PExpr deref_op(PExpr e1, bool do_overload=true); 87 | PExpr addr_op(PExpr e1, bool do_overload=true,bool force_reference=false); 88 | PExpr reference_stub_op(PExpr e); 89 | PExpr unary_op(int op, PExpr e1); 90 | PExpr arith_if_op(PExpr cond, PExpr e1, PExpr e2); 91 | PExpr sizeof_op(int type_size); 92 | PExpr typecast_op(int which, Type t, PExpr e); 93 | PExpr function_cast_op(Type t, PExprList pel); 94 | PExpr cast_to_bool_op(PExpr e1); 95 | PExpr inc_dec_op(int op, PExpr e, bool is_prefix); 96 | PExpr assign_op(PExpr e1, PExpr e2, bool constness = true); 97 | PExpr compound_assign_op(int op, PExpr e1, PExpr e2); 98 | PExpr return_op(Function *fn, Type rt, PExpr e); 99 | PExpr relational_op(int op, PExpr e1, PExpr e2); 100 | PExpr equal_op(PExpr e1, PExpr e2); 101 | PExpr array_op(PExpr e1, PExpr e2); 102 | PExpr function_op(PExpr e1, PExprList e2, bool suppress_error = false); 103 | PExpr method_call(PFunction fn, PExpr obj, PExprList pel); 104 | void set_first_object(PExpr e1); 105 | Type typeof_op(PExpr e); 106 | PExpr selection_op(PExpr e, char *name,bool is_ptr, bool is_member_ptr=false); 107 | PExpr expr_list_op(PExprList pel, bool is_list); 108 | PExpr append_op(PExpr e1, PExpr e2, bool drop_values=false); 109 | PExpr lambda_op(PEntry pe); 110 | 111 | /*template 112 | PExpr constant_op(Type t, T val) 113 | { 114 | PEntry pe; 115 | using Parser::create_const_entry; 116 | T *pi = (T *)create_const_entry(t,pe); 117 | *pi = val; 118 | return entry_op(pe); 119 | } 120 | */ 121 | PExpr constant_op(Type t, unsigned long val); 122 | 123 | 124 | 125 | } // namespace Expressions 126 | 127 | 128 | 129 | #endif 130 | 131 | -------------------------------------------------------------------------------- /src/fblock.h: -------------------------------------------------------------------------------- 1 | // Fblock.h 2 | 3 | #ifndef __FBLOCK_H 4 | #define __FBLOCK_H 5 | #include "export.h" 6 | 7 | // FBlock contains all that the runtime system needs to know about a function 8 | struct EXPORT FBlock { 9 | PInstruction pstart; // actual pcode 10 | int nlocal; // reserved for local variables (dwords) 11 | int nargs; // no. of args explicitly passed (dwords) 12 | int ntotal; // the sum of nlocal and nargs 13 | Table* context; // symbol table context 14 | Class* class_ptr; // class pointer - NULL if not method 15 | Entry* entry; // specific entry in table 16 | Function* function; // actual corresponding function object 17 | void* data; // extra data (will be addr of wrapped native code) 18 | XTrace* trace; // optional trace object 19 | 20 | // more to follow.... 21 | FBlock (PInstruction pc=NULL, int na=0) 22 | { pstart = pc; nargs = na; nlocal = 0; context = NULL; data = NULL; } 23 | 24 | void *native_addr() { return data; } 25 | 26 | static FBlock *create(Entry *pe, Class *pc); 27 | void finalize(int sz); 28 | }; 29 | 30 | typedef FBlock *PFBlock; 31 | typedef FBlock **PPFBlock; 32 | 33 | #endif 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/function_match.h: -------------------------------------------------------------------------------- 1 | /* FUNCTION_MATCH.H 2 | */ 3 | #ifndef __FUNCTION_MATCH_H 4 | #define __FUNCTION_MATCH_H 5 | 6 | #include "types.h" 7 | #include "function.h" 8 | 9 | std::ostream& operator << (std::ostream& os, Signature& sig); 10 | std::ostream& operator <<(std::ostream& os, Function& f); 11 | 12 | const int MAX_OVERLOAD = 35, MAX_ARGUMENTS = 20, MAX_ERR = 512; 13 | 14 | class MatchItem { 15 | protected: 16 | int m_match; 17 | Type m_type; 18 | public: 19 | MatchItem(int match, Type type) : m_match(match),m_type(type) {} 20 | int match() { return m_match; } 21 | Type type() { return m_type; } 22 | }; 23 | 24 | enum MatchResult { AMBIGUOUS, MATCHED, NO_MATCH_POSSIBLE }; 25 | typedef std::list MatchList; 26 | 27 | class FunctionMatch { 28 | private: 29 | typedef TypeDistance MatchMatrix[MAX_OVERLOAD][MAX_ARGUMENTS]; 30 | MatchMatrix mmatch; 31 | int match_idx, other_match_idx,n_sig,n_arg; 32 | Signature *sigs[MAX_OVERLOAD]; 33 | Type args[MAX_ARGUMENTS]; 34 | MatchList m_match_list; 35 | FunctionEntry *m_fe; 36 | Signature *m_sig; 37 | char m_err_buff[MAX_ERR]; 38 | 39 | public: 40 | TypeDistance list_match(TypeList& tl, Type t, bool dir); 41 | MatchResult user_match(); 42 | MatchResult apply_match(MatchFunction fmatch); 43 | bool function_match(const FunctionEntry& fe, Signature& sig); 44 | char *error() { return m_err_buff; } 45 | void dump_match_matrix(); 46 | Function *matched_function(); 47 | MatchList::iterator matches(PExprList el); 48 | }; 49 | 50 | 51 | #endif 52 | 53 | -------------------------------------------------------------------------------- /src/hard_except.cpp: -------------------------------------------------------------------------------- 1 | /* hard_except.cpp 2 | * Mapping between hardware signals/exceptions and C++ exceptions 3 | * UnderC C++ interpreter 4 | * Steve Donovan, 2001 5 | * This is GPL'd software, and the usual disclaimers apply. 6 | * See LICENCE 7 | */ 8 | #include "hard_except.h" 9 | 10 | #ifndef __GNUC__ 11 | // Mapping Win32 SE exceptions onto C++ exceptions 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | void trans_func( unsigned int u, _EXCEPTION_POINTERS* pExp ) 20 | { 21 | //*fix 1.2.4 Reset floating point after exceptions - otherwise we may lose further fp exceptions! 22 | _fpreset(); 23 | if(u == STATUS_ACCESS_VIOLATION) throw AccessViolation(); else 24 | if(u == STATUS_FLOAT_DIVIDE_BY_ZERO) throw FloatDivByZero(); else 25 | if(u == STATUS_FLOAT_OVERFLOW) throw FloatOverflow(); else 26 | if(u == STATUS_INTEGER_DIVIDE_BY_ZERO) throw IntDivByZero(); else 27 | if(u == STATUS_INTEGER_OVERFLOW) throw IntOverflow(); 28 | else throw Exception("Unknown"); 29 | } 30 | 31 | // I found it necessary to use this little low-level fiddle 32 | // from Matt Pietrek (_Under the Hood) article from MSJ, 1997) 33 | void UnmaskFPExceptionBits( void ) 34 | { 35 | unsigned short cw; 36 | 37 | __asm fninit // Initialize the coprocessor 38 | __asm fstcw [cw] 39 | cw &= 0xFFE0; // Turn off the most of the exception bits (except the 40 | // the precision exception) 41 | __asm fldcw [cw] 42 | 43 | } 44 | 45 | int check_mem(); 46 | 47 | void Exception::initialize() 48 | { 49 | // enable FP exceptions 50 | // *unfix 1.2.1 Use _controlfp() rather than half-assed inline assembler 51 | // _controlfp(_EM_ZERODIVIDE, _MCW_EM); 52 | // Trouble is I get 'bad number' exceptions as well, which may well be a Win9x thing. 53 | UnmaskFPExceptionBits(); 54 | _set_se_translator( trans_func ); 55 | } 56 | 57 | #else 58 | #include 59 | #include 60 | 61 | static char* mRangeMsg = NULL; 62 | 63 | void signal_to_exception(int signl) 64 | { 65 | switch(signl) { 66 | case SIGSEGV: throw AccessViolation(); 67 | case SIGILL: throw RangeError(mRangeMsg); 68 | case SIGFPE: throw FloatDivByZero(); 69 | default: throw Exception("unknown"); 70 | } 71 | } 72 | 73 | // *fix 1.2.6 raise() only works _once_. However, there's no reason why we can't 74 | // call the handler directly! 75 | 76 | void handler(int); 77 | 78 | void throw_range_error(char* msg) 79 | { 80 | mRangeMsg = strdup(msg); 81 | handler(SIGILL); 82 | } 83 | 84 | // Win32 and Linux work differently here. In Win32 you can directly 85 | // throw a C++ exception from a signal handler, in Linux you have 86 | // to make a long jump out of the handler to avoid crashing in flames. 87 | // See hard_except.h and CATCH_SIGNALS in engine.cpp to see how the rest works. 88 | #ifndef _WIN32 89 | #include 90 | jmp_buf here_in_execute; 91 | int global_last_signal = 0; 92 | 93 | void handler(int signl) 94 | { 95 | longjmp(here_in_execute,signl); 96 | // global_last_signal = signl; 97 | // signal(signl,SIG_IGN); 98 | } 99 | #else 100 | void handler(int signl) 101 | { 102 | signal_to_exception(signl); 103 | } 104 | #endif 105 | 106 | 107 | void UnmaskFPExceptionBits() 108 | { 109 | //?que? ISSUE: we _do_ need to do this, I think! 110 | } 111 | 112 | void Exception::initialize() 113 | { 114 | UnmaskFPExceptionBits(); 115 | signal(SIGSEGV, handler); 116 | signal(SIGILL, handler); 117 | signal(SIGFPE, handler); 118 | } 119 | 120 | #endif 121 | 122 | class __Init__ { 123 | public: 124 | __Init__() { 125 | Exception::initialize(); 126 | } 127 | }; 128 | 129 | __Init__ this__Init__; 130 | 131 | 132 | -------------------------------------------------------------------------------- /src/hard_except.h: -------------------------------------------------------------------------------- 1 | // hard_except.h 2 | // Maps Win32 structured exceptions (SE) onto C++ exceptions 3 | 4 | #ifndef _hard_except_h 5 | #define _hard_except_h 6 | class Exception { 7 | private: 8 | char *m_what; 9 | int m_type; 10 | public: 11 | enum { UNKNOWN, BAD_PTR, INT_OVERFLOW, FLOAT_OVERFLOW, INT_DIV0, FLOAT_DIV0, ACCESS, RANGE_ERROR}; 12 | Exception(char *msg, int type = UNKNOWN) : m_what(msg), m_type(type) {} 13 | virtual char *what() { return m_what; } 14 | int type() { return m_type; } 15 | static void initialize(); 16 | }; 17 | 18 | class BadPointer: public Exception { 19 | public: 20 | BadPointer(char *msg) : Exception(msg,BAD_PTR) { } 21 | }; 22 | 23 | class HardwareException: public Exception { 24 | public: 25 | HardwareException(char *msg,int type) : Exception(msg,type) { } 26 | }; 27 | 28 | class RangeError: public Exception { 29 | public: 30 | RangeError(char *msg) : Exception(msg,RANGE_ERROR) { } 31 | }; 32 | 33 | class IntOverflow: public HardwareException { 34 | public: 35 | IntOverflow() : HardwareException("integer overflow",INT_OVERFLOW) {} 36 | }; 37 | 38 | class FloatOverflow: public HardwareException { 39 | public: 40 | FloatOverflow() : HardwareException("floating point overflow",FLOAT_OVERFLOW) {} 41 | }; 42 | 43 | class IntDivByZero: public HardwareException { 44 | public: 45 | IntDivByZero() : HardwareException("integer division by zero",INT_DIV0) {} 46 | }; 47 | 48 | class FloatDivByZero: public HardwareException { 49 | public: 50 | FloatDivByZero() : HardwareException("floating point division by zero",FLOAT_DIV0) {} 51 | }; 52 | 53 | class AccessViolation: public HardwareException { 54 | public: 55 | AccessViolation() : HardwareException("access violation",ACCESS) {} 56 | }; 57 | 58 | #ifndef _WIN32 59 | #include 60 | extern jmp_buf here_in_execute; 61 | void signal_to_exception(int signum); 62 | void throw_range_error(char *msg); 63 | #define CATCH_SIGNALS \ 64 | { int sgn; if ((sgn=setjmp(here_in_execute))!=0) signal_to_exception(sgn);} 65 | #else 66 | # define CATCH_SIGNALS 67 | #endif 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /src/imports.h: -------------------------------------------------------------------------------- 1 | 2 | // imports.h 3 | 4 | #ifndef __IMPORTS_H 5 | #define __IMPORTS_H 6 | 7 | class Function; 8 | class Class; 9 | struct FBlock; 10 | typedef FBlock *PFBlock; 11 | typedef PFBlock *VMTArray; 12 | typedef std::list VMTList; 13 | typedef int (*CALLFN) (); 14 | typedef CALLFN *VTable; 15 | typedef VTable *PVTable; 16 | 17 | class ImportScheme { 18 | protected: 19 | VTable m_vtable; 20 | bool m_patched; 21 | bool m_cpp_friendly; 22 | int m_vtable_size; 23 | int m_vmt_ofs; 24 | int m_scheme_type; // *add 1.2.7 25 | VMTList *m_ghost_classes; 26 | virtual int index(int id) { return id; } 27 | 28 | public: 29 | ImportScheme(); 30 | bool patched() { return m_patched; } 31 | void now_patched() { m_patched = true; } 32 | int vmt_offset() { return m_vmt_ofs; } 33 | void vtable_size(int sz) { m_vtable_size = sz; } 34 | int vtable_size() { return m_vtable_size; } 35 | bool cpp_friendly() { return m_cpp_friendly; } 36 | void scheme_type(int st) { m_scheme_type = st; } 37 | int scheme_type() { return m_scheme_type; } 38 | 39 | // overrideables 40 | virtual bool uses_stdmethod() { return false; } 41 | virtual bool pre_construct() { return true; } 42 | virtual bool ret_obj_popped() { return false; } 43 | virtual bool true_pass_by_value(Type) { return false; } 44 | virtual bool true_return_by_value(Type) { return false; } 45 | virtual void set_first_virtual_class(int) { } 46 | virtual int vtable_full_size() { return m_vtable_size; } 47 | virtual VTable clone_vtable(); 48 | virtual void vtable_write_slot(int i, CALLFN pf); 49 | virtual CALLFN vtable_read_slot(int i); 50 | virtual void vtable_write(void *obj); 51 | virtual VTable vtable_read(void *obj); 52 | virtual bool vtable_at_begining() { return true; } 53 | VMTArray hunt_for_matching_VMT(VMTArray vmt, Class *pc); 54 | }; 55 | 56 | namespace Import { 57 | ImportScheme *create_scheme(int scm=-1); 58 | ImportScheme *create_compat_scheme(); 59 | ImportScheme *scheme(); 60 | void reset(bool new_dl); 61 | bool set_scheme(string keyword); 62 | void* load_method_entry(Function *pfn, string& mangled_name); 63 | bool cpp_friendly(); 64 | } 65 | 66 | #endif 67 | 68 | -------------------------------------------------------------------------------- /src/input.h: -------------------------------------------------------------------------------- 1 | // A convenient thin interface to the input stream 2 | #ifndef __INPUT_H 3 | #define __INPUT_H 4 | typedef int (*INTFN) (); 5 | namespace Input { 6 | int lineno() ; 7 | string filename() ; 8 | bool open(const char *fname) ; 9 | void clear() ; 10 | void insert_stream(std::istream *pos, const char *name, int start_line = 0) ; 11 | void insert_string(char* str); 12 | void grab_next_line(char *buff) ; 13 | char *next_token(bool first=true) ; 14 | void set_open_restore(INTFN module_open, INTFN module_close) ; 15 | PEntry lookup_next_symbol() ; 16 | } 17 | #endif 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/keywords.cpp: -------------------------------------------------------------------------------- 1 | /* KEYWORDS.CPP 2 | * Looking up keywords (contains full list) 3 | * UnderC C++ interpreter 4 | * Steve Donovan, 2001 5 | * This is GPL'd software, and the usual disclaimers apply. 6 | * See LICENCE 7 | */ 8 | // get rid of nasty & irrevalent messages about debug map names 9 | #pragma warning(disable:4786) 10 | #include "common.h" 11 | #include "tparser.h" 12 | #include "classlib.h" 13 | #include 14 | 15 | typedef std::map IntMap; 16 | 17 | namespace Keywords { 18 | 19 | IntMap kmap; 20 | IntMap::iterator kmap_end; 21 | 22 | int lookup(const string& name) 23 | { 24 | //kmap[name]; not a good idea - _always_ adds an entry! 25 | IntMap::iterator iim = kmap.find(name); 26 | return (iim != kmap_end) ? iim->second : 0; 27 | } 28 | 29 | string find(int id) 30 | { 31 | // the opposite operation! 32 | IntMap::iterator iim; 33 | for(iim = kmap.begin(); iim != kmap_end; ++iim) 34 | if (iim->second == id) return iim->first; 35 | return ""; 36 | } 37 | 38 | void add(char *name, int val) 39 | { 40 | kmap[name] = val; 41 | } 42 | 43 | void init() 44 | { 45 | add("unsigned",UNSIGNED); 46 | add("char",CHAR); 47 | add("int",INT); 48 | add("short",SHORT); 49 | add("long",LONG); 50 | add("float",FLOAT); 51 | add("double",DOUBLE); 52 | add("bool",BOOL); 53 | add("void",VOID); 54 | add("const",CONST); 55 | add("static",STATIC); 56 | add("virtual",VIRTUAL); 57 | add("typedef",TYPEDEF); 58 | add("class",CLASS); 59 | add("struct",STRUCT); 60 | add("private",PRIVATE); 61 | add("protected",PROTECTED); 62 | add("public",PUBLIC); 63 | add("enum",ENUM); 64 | add("new",NEW); 65 | add("delete",DELETE); 66 | add("sizeof",SIZEOF); 67 | add("if",IF); 68 | add("else",ELSE); 69 | add("while",WHILE); 70 | add("do",DO); 71 | add("for",FOR); 72 | add("switch",SWITCH); 73 | add("case",CASE); 74 | add("default",DEFAULT); 75 | add("return",RETURN); 76 | add("continue",CONTINUE); 77 | add("break",BREAK); 78 | add("operator",OPERATOR); 79 | add("static_cast",STATIC_CAST); 80 | add("const_cast",CONST_CAST); 81 | add("dynamic_cast",DYNAMIC_CAST); 82 | add("reinterpret_cast",REINTERPRET_CAST); 83 | add("namespace",NAMESPACE); 84 | add("using",USING); 85 | add("try",TRY); 86 | add("catch",CATCH); 87 | add("throw",THROW); 88 | add("template",TEMPLATE); 89 | add("extern",EXTERN); 90 | add("explicit",EXPLICIT); 91 | add("friend",FRIEND); 92 | add("decltype",TYPEOF); 93 | add("__stdcall",STDCALL); 94 | add("__API",API); 95 | add("__lambda",LAMBDA); 96 | add("goto",GOTO); // *add 1.2.5 97 | add("union",UNION); // *add 1.2.6 98 | add("__init_block__",FAKE_INIT_LIST); // *add 1.2.7 A syntactical hack; see ParserState::handle_method_body 99 | 100 | 101 | kmap_end = kmap.end(); 102 | } 103 | 104 | 105 | }; 106 | -------------------------------------------------------------------------------- /src/keywords.h: -------------------------------------------------------------------------------- 1 | // keywords.h 2 | #ifndef __KEYWORDS_H 3 | #define __KEYWORDS_H 4 | namespace Keywords { 5 | int lookup(const string& name); 6 | string find(int id); 7 | void init(); 8 | }; 9 | #endif 10 | -------------------------------------------------------------------------------- /src/lakefile: -------------------------------------------------------------------------------- 1 | cpp.program{'ucc',src='*',exclude='dll_entry', 2 | defines='NO_READLINE _CONSOLE', 3 | dynamic=true,odir=true} 4 | -------------------------------------------------------------------------------- /src/linenoise.h: -------------------------------------------------------------------------------- 1 | /* linenoise.h -- guerrilla line editing library against the idea that a 2 | * line editing lib needs to be 20,000 lines of C code. 3 | * 4 | * See linenoise.c for more information. 5 | * 6 | * ------------------------------------------------------------------------ 7 | * 8 | * Copyright (c) 2010, Salvatore Sanfilippo 9 | * Copyright (c) 2010, Pieter Noordhuis 10 | * 11 | * All rights reserved. 12 | * 13 | * Redistribution and use in source and binary forms, with or without 14 | * modification, are permitted provided that the following conditions are 15 | * met: 16 | * 17 | * * Redistributions of source code must retain the above copyright 18 | * notice, this list of conditions and the following disclaimer. 19 | * 20 | * * Redistributions in binary form must reproduce the above copyright 21 | * notice, this list of conditions and the following disclaimer in the 22 | * documentation and/or other materials provided with the distribution. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #ifndef __LINENOISE_H 38 | #define __LINENOISE_H 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | typedef struct linenoiseCompletions { 45 | size_t len; 46 | char **cvec; 47 | } linenoiseCompletions; 48 | 49 | typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *); 50 | void linenoiseSetCompletionCallback(linenoiseCompletionCallback *); 51 | void linenoiseAddCompletion(linenoiseCompletions *, const char *); 52 | 53 | char *linenoise(const char *prompt); 54 | int linenoiseHistoryAdd(const char *line); 55 | int linenoiseHistorySetMaxLen(int len); 56 | int linenoiseHistorySave(const char *filename); 57 | int linenoiseHistoryLoad(const char *filename); 58 | void linenoiseClearScreen(void); 59 | void linenoiseSetMultiLine(int ml); 60 | void linenoisePrintKeyCodes(void); 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | 66 | #endif /* __LINENOISE_H */ 67 | -------------------------------------------------------------------------------- /src/loaded_module_list.h: -------------------------------------------------------------------------------- 1 | #ifndef __LOADED_MODULE_LIST_H 2 | #define __LOADED_MODULE_LIST_H 3 | namespace LoadedModuleList { 4 | void init(); 5 | void init_module(int idx); 6 | void finish_module(Instruction* pi); 7 | void ODL_add(void* ptr, Function* dtor); 8 | void run_program_initialization(); 9 | void run_program_finalization(); 10 | void run_global_finalization(); 11 | }; 12 | #endif 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/main.h: -------------------------------------------------------------------------------- 1 | /* main.h 2 | * Main Program, initialization, and # command implementation 3 | * UnderC C++ interpreter 4 | * Steve Donovan, 2001 5 | * This is GPL'd software, and the usual disclaimers apply. 6 | * See LICENCE 7 | */ 8 | 9 | namespace Main { 10 | void initialize(); 11 | bool process_command_line(int& argc, char**& argv); 12 | void banner(); 13 | void finalize(); 14 | int interactive_loop(); 15 | char *uc_exec_name(); 16 | string uc_lib_dir(); 17 | }; 18 | 19 | -------------------------------------------------------------------------------- /src/makefile: -------------------------------------------------------------------------------- 1 | # Makefile for console-build UnderC C++ interpreter 2 | # vs 1.2.4 Can also build as a shared library, if SO is set 3 | 4 | # variables from configure 5 | UC_VERSION=1.3.1 6 | UC_HOME=/home/azisa/uc/UnderC 7 | 8 | OBJ = tparser.o function_match.o class.o code.o common.o \ 9 | directcall.o dissem.o engine.o expressions.o \ 10 | function.o breakpoints.o tokens.o keywords.o \ 11 | mangle.o operators.o os.o subst.o \ 12 | table.o templates.o hard_except.o mstring.o \ 13 | types.o program.o uc_tokens.o lexer.o main.o \ 14 | errors.o utils.o imports.o ex_vfscanf.o ucri.o 15 | 16 | NAME = ucc 17 | DEFINES = -D_CONSOLE 18 | CFLAGS = -Wno-deprecated -Wno-write-strings -m32 19 | ifdef DEBUG 20 | CFLAGS := -g $(CFLAGS) 21 | else 22 | CFLAGS := -O1 $(CFLAGS) 23 | ifdef DYNAMIC 24 | LFLAGS = -Wl,-E 25 | endif 26 | endif 27 | 28 | ifdef SO 29 | LFLAGS := $(LFLAGS) -shared 30 | OBJ := $(OBJ) dll_entry.o 31 | # DEFINES = $(DEFINES) -D_USRDLL 32 | DEFINES = -D_USRDLL 33 | NAME = ucc131.so 34 | NO_READLINE = 1 35 | endif 36 | 37 | ifndef NO_READLINE 38 | DEFINES := $(DEFINES) -D_USE_READLINE 39 | ifdef REALLY_USE_READLINE 40 | DEFINES := $(DEFINES) -D_REALLY_USE_READLINE 41 | LFLAGS := $(LFLAGS) -lreadline -lncurses 42 | else 43 | OBJ := $(OBJ) linenoise.o 44 | endif 45 | endif 46 | 47 | ifndef BSD 48 | LFLAGS := $(LFLAGS) -ldl 49 | endif 50 | 51 | ifdef STATIC 52 | LFLAGS := $(LFLAGS) -static 53 | endif 54 | 55 | ucc: $(OBJ) 56 | $(CXX) $(CFLAGS) -o $(NAME) $(OBJ) $(LFLAGS) 57 | ifndef SO 58 | ifndef DYNAMIC 59 | nm -g ucc | awk -f xnames.awk > ../lib/self.imp 60 | ifndef DEBUG 61 | strip ucc 62 | endif 63 | endif 64 | endif 65 | 66 | %.o: %.cpp 67 | $(CXX) -c $(CFLAGS) $(DEFINES) $< 68 | 69 | tparser.cpp: parser.y 70 | bison -y -d parser.y; cp y.tab.c tparser.cpp; cp y.tab.h tparser.h 71 | 72 | tparser.o: tparser.cpp 73 | 74 | clean: 75 | rm -f *.o ucc *~ ../lib/string_imp.dll 76 | 77 | lib: 78 | $(CXX) $(CFLAGS) -o ../lib/string_imp.dll -shared -Wl,-export-dynamic ../lib/string_imp.cpp 79 | 80 | function_match.o: function_match.cpp function_match.h \ 81 | common.h templates.h 82 | 83 | class.o: class.cpp class.h common.h \ 84 | directcall.h operators.h opcodes.h tparser.h std_utils.h 85 | 86 | linenoise.o: linenoise.c 87 | 88 | code.o: code.cpp code.h common.h opcodes.h tparser.h 89 | 90 | common.o: common.h function_match.h tparser.h code.h \ 91 | opcodes.h engine.h 92 | 93 | # gcc 4.6 optimization omits frame pointers, which upsets callfn 94 | directcall.o: directcall.cpp directcall.h common.h \ 95 | opcodes.h directcall.h mangle.h hard_except.h os.h 96 | $(CXX) -c $(CFLAGS) -fno-omit-frame-pointer $(DEFINES) directcall.cpp 97 | 98 | dissem.o: dissem.cpp common.h \ 99 | opcodes.h breakpoints.h 100 | 101 | engine.o: engine.cpp engine.h common.h errors.h \ 102 | opcodes.h directcall.h breakpoints.h hard_except.h 103 | 104 | expressions.o: expressions.cpp expressions.h common.h \ 105 | function_match.h tparser.h operators.h directcall.h 106 | 107 | function.o: function.cpp function.h common.h opcodes.h \ 108 | module.h 109 | 110 | breakpoints.o: breakpoints.cpp breakpoints.h common.h \ 111 | module.h opcodes.h tokens.h std_utils.h os.h 112 | 113 | tokens.o: tokens.cpp tokens.h utils.h 114 | 115 | keywords.o: keywords.cpp common.h \ 116 | tparser.h 117 | 118 | mangle.o: mangle.cpp mangle.h common.h 119 | 120 | operators.o: operators.cpp operators.h common.h \ 121 | tparser.h 122 | 123 | os.o: os.cpp os.h 124 | 125 | subst.o: subst.cpp 126 | 127 | table.o: table.cpp table.h 128 | 129 | templates.o: templates.cpp templates.h common.h \ 130 | tparser.h std_utils.h 131 | 132 | hard_except.o: hard_except.cpp hard_except.h 133 | 134 | types.o: types.cpp types.h common.h \ 135 | templates.h 136 | 137 | program.o: program.cpp program.h common.h \ 138 | module.h errors.h utils.h 139 | 140 | uc_tokens.o: uc_tokens.cpp uc_tokens.h common.h \ 141 | module.h version.h errors.h 142 | 143 | lexer.o: lexer.cpp common.h \ 144 | tparser.h keywords.h operators.h input.h uc_tokens.h 145 | 146 | main.o: main.cpp common.h \ 147 | breakpoints.h module.h uc_tokens.h engine.h mangle.h \ 148 | directcall.h keywords.h operators.h program.h utils.h \ 149 | input.h version.h errors.h 150 | 151 | errors.o: errors.cpp errors.h common.h \ 152 | input.h 153 | 154 | imports.o: imports.cpp imports.h common.h \ 155 | mangle.h os.h 156 | 157 | ucri.o: ucri.cpp module.h directcall.h program.h imports.h 158 | 159 | dll_entry.o: dll_entry.cpp module.h engine.h main.h errors.h directcall.h input.h 160 | 161 | ex_vfscanf.o: ex_vfscanf.h 162 | 163 | utils.o: utils.cpp utils.h classlib.h 164 | 165 | mstring.o: mstring.cpp mstring.h 166 | 167 | 168 | -------------------------------------------------------------------------------- /src/makefile.in: -------------------------------------------------------------------------------- 1 | # Makefile for console-build UnderC C++ interpreter 2 | 3 | # variables from configure 4 | UC_VERSION=@@UC_VERSION@@ 5 | UC_HOME=@@UC_HOME@@ 6 | @@BSD@@ 7 | 8 | OBJ = tparser.o function_match.o class.o code.o common.o \ 9 | directcall.o dissem.o engine.o expressions.o \ 10 | function.o breakpoints.o tokens.o keywords.o \ 11 | mangle.o operators.o os.o subst.o \ 12 | table.o templates.o hard_except.o mstring.o \ 13 | types.o program.o uc_tokens.o lexer.o main.o \ 14 | errors.o utils.o imports.o ex_vfscanf.o ucri.o 15 | 16 | NAME = ucc 17 | DEFINES = -D_CONSOLE 18 | CFLAGS = -Wno-deprecated -Wno-write-strings -m32 19 | ifdef DEBUG 20 | CFLAGS := -g $(CFLAGS) 21 | else 22 | CFLAGS := -O1 $(CFLAGS) 23 | ifdef DYNAMIC 24 | LFLAGS = -Wl,-E 25 | endif 26 | endif 27 | 28 | ifdef SO 29 | LFLAGS := $(LFLAGS) -shared 30 | OBJ := $(OBJ) dll_entry.o 31 | # DEFINES = $(DEFINES) -D_USRDLL 32 | DEFINES = -D_USRDLL 33 | NAME = ucc$(UC_VERSION).so 34 | NO_READLINE = 1 35 | endif 36 | 37 | ifndef NO_READLINE 38 | DEFINES := $(DEFINES) -D_USE_READLINE 39 | ifdef REALLY_USE_READLINE 40 | DEFINES := $(DEFINES) -D_REALLY_USE_READLINE 41 | LFLAGS := $(LFLAGS) -lreadline -lncurses 42 | else 43 | OBJ := $(OBJ) linenoise.o 44 | endif 45 | endif 46 | 47 | ifndef BSD 48 | LFLAGS := $(LFLAGS) -ldl 49 | endif 50 | 51 | ifdef STATIC 52 | LFLAGS := $(LFLAGS) -static 53 | endif 54 | 55 | ucc: $(OBJ) 56 | $(CXX) $(CFLAGS) -o $(NAME) $(OBJ) $(LFLAGS) 57 | ifndef SO 58 | ifndef DYNAMIC 59 | nm -g ucc | awk -f xnames.awk > ../lib/self.imp 60 | ifndef DEBUG 61 | strip ucc 62 | endif 63 | endif 64 | endif 65 | 66 | %.o: %.cpp 67 | $(CXX) -c $(CFLAGS) $(DEFINES) $< 68 | 69 | tparser.cpp: parser.y 70 | bison -y -d parser.y; cp y.tab.c tparser.cpp; cp y.tab.h tparser.h 71 | 72 | tparser.o: tparser.cpp 73 | 74 | clean: 75 | rm -f *.o ucc *~ ../lib/string_imp.dll 76 | 77 | lib: 78 | $(CXX) $(CFLAGS) -o ../lib/string_imp.dll -shared -Wl,-export-dynamic ../lib/string_imp.cpp 79 | 80 | function_match.o: function_match.cpp function_match.h \ 81 | common.h templates.h 82 | 83 | class.o: class.cpp class.h common.h \ 84 | directcall.h operators.h opcodes.h tparser.h std_utils.h 85 | 86 | linenoise.o: linenoise.c 87 | 88 | code.o: code.cpp code.h common.h opcodes.h tparser.h 89 | 90 | common.o: common.h function_match.h tparser.h code.h \ 91 | opcodes.h engine.h 92 | 93 | # gcc 4.6 optimization omits frame pointers, which upsets callfn 94 | directcall.o: directcall.cpp directcall.h common.h \ 95 | opcodes.h directcall.h mangle.h hard_except.h os.h 96 | $(CXX) -c $(CFLAGS) -fno-omit-frame-pointer $(DEFINES) directcall.cpp 97 | 98 | dissem.o: dissem.cpp common.h \ 99 | opcodes.h breakpoints.h 100 | 101 | engine.o: engine.cpp engine.h common.h errors.h \ 102 | opcodes.h directcall.h breakpoints.h hard_except.h 103 | 104 | expressions.o: expressions.cpp expressions.h common.h \ 105 | function_match.h tparser.h operators.h directcall.h 106 | 107 | function.o: function.cpp function.h common.h opcodes.h \ 108 | module.h 109 | 110 | breakpoints.o: breakpoints.cpp breakpoints.h common.h \ 111 | module.h opcodes.h tokens.h std_utils.h os.h 112 | 113 | tokens.o: tokens.cpp tokens.h utils.h 114 | 115 | keywords.o: keywords.cpp common.h \ 116 | tparser.h 117 | 118 | mangle.o: mangle.cpp mangle.h common.h 119 | 120 | operators.o: operators.cpp operators.h common.h \ 121 | tparser.h 122 | 123 | os.o: os.cpp os.h 124 | 125 | subst.o: subst.cpp 126 | 127 | table.o: table.cpp table.h 128 | 129 | templates.o: templates.cpp templates.h common.h \ 130 | tparser.h std_utils.h 131 | 132 | hard_except.o: hard_except.cpp hard_except.h 133 | 134 | types.o: types.cpp types.h common.h \ 135 | templates.h 136 | 137 | program.o: program.cpp program.h common.h \ 138 | module.h errors.h utils.h 139 | 140 | uc_tokens.o: uc_tokens.cpp uc_tokens.h common.h \ 141 | module.h version.h errors.h 142 | 143 | lexer.o: lexer.cpp common.h \ 144 | tparser.h keywords.h operators.h input.h uc_tokens.h 145 | 146 | main.o: main.cpp common.h \ 147 | breakpoints.h module.h uc_tokens.h engine.h mangle.h \ 148 | directcall.h keywords.h operators.h program.h utils.h \ 149 | input.h version.h errors.h 150 | 151 | errors.o: errors.cpp errors.h common.h \ 152 | input.h 153 | 154 | imports.o: imports.cpp imports.h common.h \ 155 | mangle.h os.h 156 | 157 | ucri.o: ucri.cpp module.h directcall.h program.h imports.h 158 | 159 | dll_entry.o: dll_entry.cpp module.h engine.h main.h errors.h directcall.h input.h 160 | 161 | ex_vfscanf.o: ex_vfscanf.h 162 | 163 | utils.o: utils.cpp utils.h classlib.h 164 | 165 | mstring.o: mstring.cpp mstring.h 166 | 167 | 168 | -------------------------------------------------------------------------------- /src/mangle.h: -------------------------------------------------------------------------------- 1 | // Mangle.h 2 | // creates C++ 'decorated names' for a few common compilers 3 | #ifndef __MANGLE_H 4 | #define __MANGLE_H 5 | namespace Mangle { 6 | char *microsoft(Function *pf); 7 | char *GCC2(Function *pf); 8 | char *GCC3(Function *pf); 9 | } 10 | 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /src/mingw.mak: -------------------------------------------------------------------------------- 1 | # Makefile for console-build UnderC C++ interpreter 2 | # vs 1.2.4 Can also build as a shared library, if SO is set 3 | 4 | # variables from configure 5 | UC_VERSION=1.2.9 6 | UC_HOME=/home/user/dev/underc 7 | 8 | 9 | OBJ = tparser.o function_match.o class.o code.o common.o \ 10 | directcall.o dissem.o engine.o expressions.o \ 11 | function.o breakpoints.o tokens.o keywords.o \ 12 | mangle.o operators.o os.o subst.o \ 13 | table.o templates.o hard_except.o mstring.o \ 14 | types.o program.o uc_tokens.o lexer.o main.o \ 15 | errors.o utils.o imports.o ex_vfscanf.o ucri.o 16 | 17 | NAME = ucc 18 | DEFINES = -D_CONSOLE 19 | NO_READLINE = 1 20 | 21 | CFLAGS = -Wno-deprecated -Wno-write-strings -m32 22 | ifdef DEBUG 23 | CFLAGS := -g $(CFLAGS) 24 | CFLAGSX := $(CFLAGS) 25 | else 26 | CFLAGS := -O1 $(CFLAGS) 27 | CFLAGSX := $(CFLAGS) -fno-omit-frame-pointer 28 | ifdef DYNAMIC 29 | LFLAGS = -Wl,-E 30 | endif 31 | endif 32 | 33 | ifndef NO_READLINE 34 | DEFINES := $(DEFINES) -D_USE_READLINE 35 | LFLAGS := $(LFLAGS) -lreadline -lncurses 36 | ifndef BSD 37 | LFLAGS := $(LFLAGS) -ldl 38 | endif 39 | endif 40 | 41 | ifdef STATIC 42 | LFLAGS := $(LFLAGS) -static 43 | endif 44 | 45 | ifdef SO 46 | LFLAGS := $(LFLAGS) -shared 47 | OBJ := $(OBJ) dll_entry.o 48 | # DEFINES = $(DEFINES) -D_USRDLL 49 | DEFINES = -D_USRDLL -D_USE_READLINE 50 | NAME = ucc131.so 51 | endif 52 | 53 | ifdef GTK 54 | LFLAGS := $(LFLAGS) `gtk-config --libs` 55 | DEFINES = -D_CONSOLE -D_USE_READLINE -D_LINK_GTK 56 | endif 57 | 58 | ucc: $(OBJ) 59 | $(CXX) $(CFLAGS) -o $(NAME) $(OBJ) $(LFLAGS) 60 | ifndef DEBUG 61 | strip ucc.exe 62 | endif 63 | 64 | %.o: %.cpp 65 | $(CXX) -c $(CFLAGS) $(DEFINES) $< 66 | 67 | tparser.cpp: parser.y 68 | bison -y -d parser.y; cp y.tab.c tparser.cpp; cp y.tab.h tparser.h 69 | 70 | tparser.o: tparser.cpp 71 | 72 | clean: 73 | del *.o 74 | 75 | lib: 76 | $(CXX) $(CFLAGS) -o ../lib/string_imp.dll -shared -Wl,-export-dynamic ../lib/string_imp.cpp 77 | 78 | function_match.o: function_match.cpp function_match.h \ 79 | common.h templates.h 80 | 81 | class.o: class.cpp class.h common.h \ 82 | directcall.h operators.h opcodes.h tparser.h std_utils.h 83 | 84 | code.o: code.cpp code.h common.h opcodes.h tparser.h 85 | 86 | common.o: common.h function_match.h tparser.h code.h \ 87 | opcodes.h engine.h 88 | 89 | directcall.o: directcall.cpp directcall.h common.h \ 90 | opcodes.h directcall.h mangle.h hard_except.h os.h 91 | $(CXX) -c $(CFLAGSX) $(DEFINES) directcall.cpp 92 | 93 | dissem.o: dissem.cpp common.h \ 94 | opcodes.h breakpoints.h 95 | 96 | engine.o: engine.cpp engine.h common.h errors.h \ 97 | opcodes.h directcall.h breakpoints.h hard_except.h 98 | 99 | expressions.o: expressions.cpp expressions.h common.h \ 100 | function_match.h tparser.h operators.h directcall.h 101 | 102 | function.o: function.cpp function.h common.h opcodes.h \ 103 | module.h 104 | 105 | breakpoints.o: breakpoints.cpp breakpoints.h common.h \ 106 | module.h opcodes.h tokens.h std_utils.h os.h 107 | 108 | tokens.o: tokens.cpp tokens.h utils.h 109 | 110 | keywords.o: keywords.cpp common.h \ 111 | tparser.h 112 | 113 | mangle.o: mangle.cpp mangle.h common.h 114 | 115 | operators.o: operators.cpp operators.h common.h \ 116 | tparser.h 117 | 118 | os.o: os.cpp os.h 119 | 120 | subst.o: subst.cpp 121 | 122 | table.o: table.cpp table.h 123 | 124 | templates.o: templates.cpp templates.h common.h \ 125 | tparser.h std_utils.h 126 | 127 | hard_except.o: hard_except.cpp hard_except.h 128 | 129 | types.o: types.cpp types.h common.h \ 130 | templates.h 131 | 132 | program.o: program.cpp program.h common.h \ 133 | module.h errors.h utils.h 134 | 135 | uc_tokens.o: uc_tokens.cpp uc_tokens.h common.h \ 136 | module.h version.h errors.h 137 | 138 | lexer.o: lexer.cpp common.h \ 139 | tparser.h keywords.h operators.h input.h uc_tokens.h 140 | 141 | main.o: main.cpp common.h \ 142 | breakpoints.h module.h uc_tokens.h engine.h mangle.h \ 143 | directcall.h keywords.h operators.h program.h utils.h \ 144 | input.h version.h errors.h 145 | 146 | errors.o: errors.cpp errors.h common.h \ 147 | input.h 148 | 149 | imports.o: imports.cpp imports.h common.h \ 150 | mangle.h os.h 151 | 152 | ucri.o: ucri.cpp module.h directcall.h program.h imports.h 153 | 154 | dll_entry.o: dll_entry.cpp module.h engine.h main.h errors.h directcall.h input.h 155 | 156 | ex_vfscanf.o: ex_vfscanf.h 157 | 158 | utils.o: utils.cpp utils.h classlib.h 159 | 160 | mstring.o: mstring.cpp mstring.h 161 | 162 | 163 | -------------------------------------------------------------------------------- /src/module.h: -------------------------------------------------------------------------------- 1 | // Module.h 2 | #ifndef __MODULE_H 3 | #define __MODULE_H 4 | #include "classlib.h" 5 | #include "common.h" 6 | #include "engine.h" 7 | #include 8 | 9 | class ModuleEntry { 10 | private: 11 | int m_start, m_end; // line number range 12 | int m_type; 13 | void *m_pf; // for a given function, class, etc 14 | 15 | public: 16 | ModuleEntry(void *pf, int l1, int l2, int type); 17 | 18 | bool contains(int l) 19 | { 20 | return l >= m_start && l <= m_end; 21 | } 22 | 23 | void * object() { return m_pf; } 24 | Class * as_class() { return (Class *)m_pf; } 25 | Function * function() { return (Function *)m_pf; } 26 | int type() { return m_type; } 27 | int lstart() { return m_start; } 28 | int lend() { return m_end; } 29 | }; 30 | class Module; 31 | typedef std::list ModuleEntryList; 32 | typedef std::list ModuleList; 33 | 34 | class Module { 35 | private: 36 | string m_name; 37 | int m_id, m_rc; 38 | long m_modified_time; 39 | bool m_modified, m_visited; 40 | ModuleEntryList m_entry_list; 41 | ModuleList m_dependencies; 42 | EntryList m_typenames; 43 | StringList m_macros; 44 | public: 45 | enum { FUNS = 1, DEPEND = 2, ALL = 3 }; 46 | typedef ModuleEntryList::iterator entry_iterator; 47 | Module(const string& name, int id); 48 | Function *function_at(int lineno); 49 | string name() { return m_name; } 50 | int id() { return m_id; } 51 | int inc_refcount() { return m_rc++; } 52 | int refcount() { return m_rc; } 53 | 54 | static Function *function_from_file(const string& file, int lineno); 55 | static int file_from_function(Function *pf, string& file); 56 | static Module *create(const string& file); 57 | static Module *current(); 58 | static void remove(Module *pm); 59 | static Module *from_id(int id); 60 | static Module *from_name(const string& file); 61 | static void add_namespace(Namespace *ns); 62 | static void clean_namespaces(bool do_save = true); 63 | static void restore_namespaces(); 64 | static string anonymous_namespace_name(); 65 | static void set_current(const string& file, bool is_entering); 66 | static void dump_entries(std::ostream& os, int flags); 67 | static void reset_modify_flags(); 68 | static void get_modules(ModuleList& ml); 69 | void get_dependencies(ModuleList& ml); 70 | void reset_flags(); 71 | void dump(std::ostream& os, int flags); 72 | 73 | entry_iterator entry_begin() { return m_entry_list.begin(); } 74 | entry_iterator entry_end() { return m_entry_list.end(); } 75 | entry_iterator find(void *pf); 76 | 77 | void add_entry(ModuleEntry& me); 78 | void add_function(Function *pf, int l1, int l2); 79 | void add_class(Class *pf, int l1, int l2); 80 | void add_typename(PEntry pe); 81 | void add_macro(const string& s) { m_macros.push_back(s); } 82 | int get_function_line(Function* pf); 83 | void clean_macros_and_typedefs(); 84 | bool is_inside(Function *pf, int l); 85 | bool is_modified(); 86 | bool needs_rebuilding(); 87 | }; 88 | #endif 89 | -------------------------------------------------------------------------------- /src/mstring.cpp: -------------------------------------------------------------------------------- 1 | // Mstring.c 2 | // testing string class 3 | /* 4 | Yes, I know it's bad to reinvent this particular wheel but 5 | I don't like the templatized standard string. An extra 30% 6 | (at least) size penalty for using the char traits templatized 7 | iostreams and strings, hassle debugging those long names, 8 | plus longer compile times. A longer version of this rave 9 | is available at 10 | home.mweb.co.za/sd/sdonovan/templates.html 11 | 12 | Masochists and other diehard supporters of the standard 13 | can switch to using and in classlib.h. 14 | 15 | Raves aside, this class could certainly do with improvements. 16 | */ 17 | #include 18 | #include "classlib.h" // includes i/o and mstring headers... 19 | 20 | const int MAX_LINE = 1024; 21 | 22 | int nCreated = 0; 23 | 24 | STR 25 | string::alloc(int size) 26 | { STR ss = new char[size+1]; 27 | return ss; 28 | } 29 | 30 | string::string (const char *ss /*=NULL*/) 31 | //*acts as our default constructor 32 | { 33 | if (!ss) ss = ""; 34 | m_length = strlen((char *)ss); 35 | m_data = alloc (m_length); 36 | strcpy (m_data, (char *)ss); 37 | nCreated++; 38 | } 39 | 40 | string::string (int size) 41 | { 42 | m_length = size; 43 | m_data = alloc (size); 44 | m_data[0] = 0; 45 | nCreated++; 46 | } 47 | 48 | // and (NB) a copy constructor.... 49 | string::string (const string& s) 50 | { 51 | m_length = s.m_length; 52 | m_data = alloc(m_length); 53 | strcpy(m_data,s.m_data); 54 | nCreated++; 55 | } 56 | 57 | string::~string() 58 | { 59 | delete m_data; 60 | m_data = NULL; 61 | nCreated--; 62 | } 63 | 64 | // assignment operators 65 | string& 66 | string::operator = (const string &s) 67 | { 68 | copy(s.c_str(),s.length()); 69 | return *this; 70 | } 71 | 72 | string& 73 | string::operator = (const char *str) 74 | { 75 | if (!str) str = ""; 76 | copy (str, strlen(str)); 77 | return *this; 78 | } 79 | 80 | 81 | int string::compare(const string& s) const 82 | { 83 | if(!m_data || !s.m_data) return -1; else 84 | return strcmp(m_data,s.m_data); 85 | } 86 | 87 | int string::compare(const char *s) const 88 | { return strcmp(m_data,s); } 89 | 90 | string 91 | string::substr (int start, int n) 92 | { 93 | STR in,out; 94 | int i; 95 | 96 | if (!n || start + n > length()) n = length()-start; 97 | 98 | string T(n); 99 | in = c_str() + start; 100 | out = T.c_str(); 101 | //strcpy(out,in); 102 | for (i = 0; i < n; i++) *out++ = *in++; 103 | *out = 0; 104 | return T; 105 | 106 | } 107 | int 108 | string::find(STR ps) 109 | { 110 | STR ss = strstr(c_str(),ps); 111 | return !ss ? -1 :long(ss) - long(c_str()); 112 | } 113 | 114 | int 115 | string::find(string& s) 116 | { 117 | return find(s.c_str()); 118 | } 119 | 120 | int 121 | string::find(char ch) 122 | { 123 | STR ss = strchr(c_str(),ch); 124 | return !ss ? -1 :long(ss) - long(c_str()); 125 | } 126 | 127 | int 128 | string::rfind(char ch) 129 | { 130 | STR ss = strrchr(c_str(),ch); 131 | return !ss ? -1 :long(ss) - long(c_str()); 132 | } 133 | 134 | string & 135 | string::operator += (const string &s) 136 | { 137 | m_length += s.length(); 138 | resize (m_length); 139 | strcat(m_data, s.m_data); 140 | return *this; 141 | } 142 | 143 | string& 144 | string::operator += (const char *str) 145 | { 146 | if (!str) str = ""; 147 | m_length += strlen(str); 148 | resize (m_length); 149 | strcat(m_data, str); 150 | return *this; 151 | } 152 | 153 | string& 154 | string::operator += (char ch) 155 | { 156 | char tmp[] = {ch,'\0'}; // very crude!! 157 | return (*this) += tmp; 158 | } 159 | 160 | 161 | 162 | void string::copy(const char*str, int sz) 163 | { 164 | if (sz > length() || sz == 0) resize(sz); 165 | m_length = sz; 166 | strcpy (m_data,str); 167 | } 168 | 169 | int string::resize (int size) 170 | { 171 | STR new_str = alloc (size); 172 | if (m_data) strncpy(new_str,m_data,size+1); 173 | if (m_length > 0) { delete m_data; m_data = NULL; } 174 | m_data = new_str; 175 | return size; 176 | } 177 | 178 | string operator + (string s1, string s2) 179 | { 180 | string temps(s1); 181 | temps += s2; 182 | return temps; 183 | } 184 | 185 | //#include 186 | char temp_buff[MAX_LINE]; 187 | 188 | std::ostream& operator << (std::ostream& os, string s) 189 | { 190 | return os << s.c_str(); 191 | } 192 | 193 | 194 | //ostream& operator << (ostream& os, const string& s) 195 | //{ 196 | // return os << s.c_str(); 197 | //} 198 | 199 | 200 | std::istream& operator >> (std::istream& is, string& s) 201 | { 202 | is >> temp_buff; 203 | s = temp_buff; 204 | return is; 205 | } 206 | 207 | /* test code 208 | void do_it() 209 | { 210 | string s("hello"), b("and"), c(80), d("and"); 211 | char *ss; 212 | 213 | cout << s.length() << "," << b.length() << endl; 214 | 215 | c = s; 216 | c += b; 217 | c = s + "hm?" + b + "and what else?"; 218 | 219 | cout << " and " << c << endl; 220 | 221 | cout << '*' << s.c_str() << s.substr(1,3) << endl; 222 | 223 | cout << c.find("what") << s.substr(s.find("h"),3) << endl; 224 | 225 | 226 | } 227 | 228 | 229 | int main() 230 | { 231 | string in,key; 232 | char buff[80]; 233 | int test; 234 | 235 | cout.set_outspace('|'); 236 | 237 | do_it(); 238 | 239 | cout << nCreated << endl; 240 | 241 | return 0; 242 | 243 | } 244 | 245 | */ 246 | 247 | 248 | -------------------------------------------------------------------------------- /src/mstring.h: -------------------------------------------------------------------------------- 1 | /* MSTRING.H 2 | * A simple string class which implements a reasonable subset 3 | * of the standard template basic_string class. 4 | * Part of the MLIB library 5 | */ 6 | 7 | #ifndef _MSTRING_H 8 | # define _MSTRING_H 9 | 10 | #include 11 | 12 | typedef char *STR; 13 | 14 | const int S_TEMP = 1, S_LOAN = 2; 15 | 16 | class string { 17 | //------------ 18 | private: 19 | STR m_data; 20 | int m_length; 21 | 22 | public: 23 | string (const char *str=0); 24 | string (int size); 25 | string (const string& s); 26 | string (const string& s,int flags); 27 | ~string (); 28 | 29 | typedef char *iterator; 30 | iterator begin() { return m_data; } 31 | iterator end() { return m_data+m_length; } 32 | 33 | int length () const 34 | { return m_length; } 35 | int size () const 36 | { return m_length; } 37 | 38 | STR c_str () const 39 | { return m_data; } 40 | 41 | string& operator = (const string &s); 42 | string& operator = (const char *str); 43 | char& operator [] (int i) { return m_data[i]; } 44 | 45 | void copy(const char *str, int sz); 46 | int compare(const string& s) const; 47 | int compare(const char *s) const; 48 | 49 | string& operator += (const string &s); 50 | string& operator += (const char *str); 51 | string& operator += (char ch); 52 | 53 | string substr (int start, int n=0); 54 | int find (STR ps); 55 | int find (string& s); 56 | int find (char ch); 57 | int rfind (char ch); 58 | 59 | STR alloc (int size); 60 | int resize(int size); 61 | 62 | }; 63 | 64 | string operator + (string s1, string s2); 65 | 66 | // *change 1.2.8 (string,char*) comparisons no longer involve temporary creation 67 | inline int operator == (const string& s1, const string& s2) { return s1.compare(s2)==0; } 68 | 69 | inline int operator == (const string& s1, char *ps2) { return s1.compare((const char*)ps2)==0; } 70 | inline int operator != (const string& s1, const string& s2) { return s1.compare(s2)!=0; } 71 | inline int operator != (const string& s1, const char*ps2) { return s1.compare(ps2)!=0; } 72 | inline int operator < (const string& s1, const string& s2) { return s1.compare(s2)<0; } 73 | //inline int operator < (string s1, string& s2) { return s1.compare(s2)<0; } 74 | inline int operator > (string& s1, string& s2) { return s1.compare(s2)>0; } 75 | 76 | 77 | //#ifdef __IOSTRM_H 78 | std::ostream& operator << (std::ostream&, string); 79 | // ostream& operator << (ostream&, const string&); 80 | std::istream& operator >> (std::istream&, string&); 81 | //#endif 82 | 83 | 84 | #endif 85 | 86 | -------------------------------------------------------------------------------- /src/msvc.mak: -------------------------------------------------------------------------------- 1 | # Microsoft nmake file for console-build UnderC C++ interpreter 2 | 3 | OBJ = tparser.obj function_match.obj class.obj code.obj common.obj \ 4 | directcall.obj dissem.obj engine.obj expressions.obj \ 5 | function.obj breakpoints.obj tokens.obj keywords.obj \ 6 | mangle.obj operators.obj os.obj subst.obj \ 7 | table.obj templates.obj hard_except.obj mstring.obj \ 8 | types.obj program.obj uc_tokens.obj lexer.obj main.obj \ 9 | errors.obj utils.obj imports.obj ex_vfscanf.obj ucri.obj 10 | 11 | # throw in a /MD here if you want a non-static link against the MS runtime 12 | CXXFLAGS = /nologo /EHsc -c /O1 /WX /DNO_READLINE /D_CONSOLE 13 | 14 | ucc: $(OBJ) 15 | link /nologo $(OBJ) /out:ucc.exe 16 | 17 | .cpp.obj: 18 | cl $(CXXFLAGS) $< 19 | 20 | tparser.obj: tparser.cpp 21 | 22 | clean: 23 | del *.obj 24 | 25 | function_match.obj: function_match.cpp function_match.h \ 26 | common.h templates.h 27 | 28 | class.obj: class.cpp class.h common.h \ 29 | directcall.h operators.h opcodes.h tparser.h std_utils.h 30 | 31 | linenoise.obj: linenoise.c 32 | 33 | code.obj: code.cpp code.h common.h opcodes.h tparser.h 34 | 35 | common.obj: common.h function_match.h tparser.h code.h \ 36 | opcodes.h engine.h 37 | 38 | directcall.obj: directcall.cpp directcall.h common.h \ 39 | opcodes.h directcall.h mangle.h hard_except.h os.h 40 | 41 | dissem.obj: dissem.cpp common.h \ 42 | opcodes.h breakpoints.h 43 | 44 | engine.obj: engine.cpp engine.h common.h errors.h \ 45 | opcodes.h directcall.h breakpoints.h hard_except.h 46 | 47 | expressions.obj: expressions.cpp expressions.h common.h \ 48 | function_match.h tparser.h operators.h directcall.h 49 | 50 | function.obj: function.cpp function.h common.h opcodes.h \ 51 | module.h 52 | 53 | breakpoints.obj: breakpoints.cpp breakpoints.h common.h \ 54 | module.h opcodes.h tokens.h std_utils.h os.h 55 | 56 | tokens.obj: tokens.cpp tokens.h utils.h 57 | 58 | keywords.obj: keywords.cpp common.h \ 59 | tparser.h 60 | 61 | mangle.obj: mangle.cpp mangle.h common.h 62 | 63 | operators.obj: operators.cpp operators.h common.h \ 64 | tparser.h 65 | 66 | os.obj: os.cpp os.h 67 | 68 | subst.obj: subst.cpp 69 | 70 | table.obj: table.cpp table.h 71 | 72 | templates.obj: templates.cpp templates.h common.h \ 73 | tparser.h std_utils.h 74 | 75 | hard_except.obj: hard_except.cpp hard_except.h 76 | 77 | types.obj: types.cpp types.h common.h \ 78 | templates.h 79 | 80 | program.obj: program.cpp program.h common.h \ 81 | module.h errors.h utils.h 82 | 83 | uc_tokens.obj: uc_tokens.cpp uc_tokens.h common.h \ 84 | module.h version.h errors.h 85 | 86 | lexer.obj: lexer.cpp common.h \ 87 | tparser.h keywords.h operators.h input.h uc_tokens.h 88 | 89 | main.obj: main.cpp common.h \ 90 | breakpoints.h module.h uc_tokens.h engine.h mangle.h \ 91 | directcall.h keywords.h operators.h program.h utils.h \ 92 | input.h version.h errors.h 93 | 94 | errors.obj: errors.cpp errors.h common.h \ 95 | input.h 96 | 97 | imports.obj: imports.cpp imports.h common.h \ 98 | mangle.h os.h 99 | 100 | ucri.obj: ucri.cpp module.h directcall.h program.h imports.h 101 | 102 | dll_entry.obj: dll_entry.cpp module.h engine.h main.h errors.h directcall.h input.h 103 | 104 | ex_vfscanf.obj: ex_vfscanf.h 105 | 106 | utils.obj: utils.cpp utils.h classlib.h 107 | 108 | mstring.obj: mstring.cpp mstring.h 109 | 110 | 111 | -------------------------------------------------------------------------------- /src/new-defs.h: -------------------------------------------------------------------------------- 1 | //#define STRING_TESTING 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | #opt v- t- 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/opcodes.h: -------------------------------------------------------------------------------- 1 | // OPCODES.H 2 | 3 | #ifndef __OPCODES_H 4 | #define __OPCODES_H 5 | 6 | #define TOK(t) 7 | #define TNAME(t) 8 | #define OP0(t) t, 9 | #define OP1(t) t, 10 | #define JOP(t) t, 11 | 12 | enum Opcodes { 13 | END_OP, 14 | #include "ops.h" 15 | EOP 16 | }; 17 | 18 | #undef TOK 19 | #undef TNAME 20 | #undef OP0 21 | #undef OP1 22 | #undef JOP 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/operators.cpp: -------------------------------------------------------------------------------- 1 | /* Operators.cpp 2 | * Fast lookup for operators 3 | * UnderC C++ interpreter 4 | * Steve Donovan, 2001 5 | * This is GPL'd software, and the usual disclaimers apply. 6 | * See LICENCE 7 | */ 8 | #include 9 | #include "common.h" 10 | #define NEEDS_LOOKUP 11 | #include "operators.h" 12 | #include "tparser.h" 13 | 14 | #include 15 | 16 | void Operators::init() 17 | { 18 | init_lookup(); 19 | add("<",LESS_THAN,"<<",LSHIFT,"<=",LEQ, 20 | "<<=",SHL_A,0); 21 | add(">",GREATER,">>",RSHIFT,">=",GEQ, 22 | ">>=",SHR_A,0); 23 | add("=",ASSIGN,"==",EQUAL,0); 24 | add("!",LOG_NOT,"!=",NOT_EQUAL,0); 25 | add("*",STAR,"*=",MUL_A,0); 26 | add(",",COMMA,0); 27 | add("+",PLUS,"++",INCR,"+=",ADD_A,0); 28 | add("-",MINUS,"--",DECR,"-=",MINUS_A, 29 | "->",ARROW,"->*",MEMBER_ARROW, 0); 30 | add("%",MODULO,"%=",MOD_A,0); 31 | add("/",DIVIDE,"/=",DIV_A,0); 32 | add("|",BIN_OR,"||",LOG_OR,"|=",BOR_A,0); 33 | add("&",ADDR,"&&",LOG_AND,"&=",BAND_A,0); 34 | add(":",':',"::",BINARY_SCOPE,0); 35 | add("~",BIN_NOT,0); 36 | // bit of a fiddle to get ellipsis recognized... 37 | add(".",DOT,".*",MEMBER_DOT,"..",DOT,"...",THREEDOT,0); 38 | add("?",ARITH_IF,0); 39 | add("^",BIN_XOR,"^=",XOR_A,0); 40 | //*Note shd pass through!! 41 | } 42 | 43 | // private to this module... 44 | #include 45 | typedef std::map NameMap; 46 | 47 | namespace { 48 | struct LookupItem { 49 | char ch; 50 | int op; 51 | }; 52 | 53 | struct LookupStruct { 54 | int op; // op corresp to first char, e.g. ASSIGN 55 | LookupItem *second_char; // list of two-letter ops, e.g. "<<","<=". Term. by nul char! 56 | char ch3; // third char of op name, e.g. '=' in "<<=" 57 | int op3; // op corresponding 58 | }; 59 | 60 | LookupStruct *ch_lookup[256]; 61 | NameMap name_map; 62 | }; 63 | 64 | namespace Operators { 65 | 66 | void init_lookup() 67 | { 68 | memset(ch_lookup,0,sizeof(void *)*256); 69 | } 70 | 71 | void add(char *first, int id,...) 72 | { 73 | char *str; 74 | va_list ap; 75 | va_start(ap,id); 76 | static LookupItem ibuff[6]; 77 | // single char must be first! 78 | LookupStruct *ls = new LookupStruct; 79 | ch_lookup[first[0]] = ls; 80 | ls->op = id; 81 | name_map[id] = first; 82 | // pick up the second chars, if any!! 83 | int i = 0; 84 | while ((str = va_arg(ap,char *)) != NULL) { 85 | id = va_arg(ap,int); 86 | name_map[id] = str; 87 | if (str[2] != '\0') break; // we hit a 3-char op! 88 | ibuff[i].ch = str[1]; 89 | ibuff[i].op = id; 90 | i++; 91 | } 92 | ibuff[i].ch = '\0'; // terminate the 2-char list 93 | 94 | if (str != NULL) { ls->ch3 = str[2]; ls->op3 = id; } else ls->ch3 = -1; // wuz 0 95 | 96 | // always add an extra item, even if no 2-char ops! 97 | ls->second_char = new LookupItem[i+1]; 98 | memcpy(ls->second_char,ibuff,(i+1)*sizeof(LookupItem)); 99 | va_end(ap); 100 | } 101 | 102 | 103 | int lookup(int ch, TokenStream& ts) 104 | { 105 | LookupStruct *ls = ch_lookup[ch]; 106 | if (!ls) return ch; // pass through 107 | LookupItem *li = ls->second_char; 108 | char chr, nextch = ts.look_ahead(); 109 | while ((chr = li->ch) != '\0') { 110 | if (chr == nextch) { 111 | ts.next(); 112 | if (ls->ch3 == ts.look_ahead()) { 113 | ts.next(); 114 | return ls->op3; 115 | } 116 | else return li->op; 117 | } 118 | li++; 119 | } 120 | return ls->op; 121 | } 122 | 123 | string name_from_id(int id) 124 | { 125 | NameMap::iterator nmi = name_map.find(id); 126 | if (nmi != name_map.end()) return nmi->second; // "operator" + string(nmi->second); 127 | // otherwise, is either a 'token' operator or a formal operator 128 | char *s; 129 | switch(id) { 130 | case NEW: s = "new"; break; 131 | case DELETE: s = "delete"; break; 132 | case SIZEOF: s = "sizeof"; break; 133 | case ARRAY: s = "[]"; break; 134 | case FUN_CALL: s = "()"; break; 135 | case UMINUS: s = "-"; break; 136 | case UPLUS: s = "+"; break; 137 | case BIN_AND: s = "&"; break; 138 | case DEREF: s = "*"; break; 139 | case ',': s = ","; break; // often it just _passes through_ depending on comma flag! 140 | default: s = ""; break; 141 | } 142 | return s; //"operator"+string(s); 143 | } 144 | 145 | } // namespace Operators 146 | 147 | -------------------------------------------------------------------------------- /src/operators.h: -------------------------------------------------------------------------------- 1 | // operators.h 2 | 3 | #ifndef __OPERATORS_H 4 | #define __OPERATORS_H 5 | 6 | #include "classlib.h" 7 | #ifdef NEEDS_LOOKUP 8 | #include "tokens.h" 9 | #endif 10 | 11 | namespace Operators { 12 | 13 | void init(); 14 | string name_from_id(int id); 15 | #ifdef NEEDS_LOOKUP 16 | int lookup(int ch, TokenStream& ts); 17 | #endif 18 | void add(char *first, int id,...); 19 | void init_lookup(); 20 | 21 | }; 22 | 23 | #endif 24 | 25 | -------------------------------------------------------------------------------- /src/os.cpp: -------------------------------------------------------------------------------- 1 | /* os.cpp 2 | * All miscelaneous OS-dependent stuff goes here. 3 | * UnderC C++ interpreter 4 | * Steve Donovan, 2001 5 | * This is GPL'd software, and the usual disclaimers apply. 6 | * See LICENCE 7 | */ 8 | 9 | #include "os.h" 10 | 11 | #ifdef _WIN32 12 | #include "directcall.h" 13 | #include 14 | 15 | long get_file_time(const char *file) 16 | // unfortunately, _stat does not work on Win32? 17 | // certainly don't seem to get an accurate fractional time. 18 | { 19 | FILETIME at; // hahmm 20 | OFSTRUCT ofs; 21 | void *hFile = (void *)OpenFile(file, &ofs, OF_READ); 22 | GetFileTime(hFile,NULL,NULL,&at); 23 | CloseHandle(hFile); 24 | __int64 *f = (__int64 *)&at; 25 | (*f) /= 100000; 26 | long val = *f; 27 | return val; 28 | } 29 | 30 | Handle load_library(const char *name) 31 | { 32 | // *add 1.2.0 Support for $caller under Win32 33 | if (name==NULL) return get_process_handle(); 34 | return (Handle) LoadLibrary(name); 35 | } 36 | 37 | void free_library(Handle h) 38 | { 39 | FreeLibrary((HINSTANCE)h); 40 | } 41 | 42 | void *get_proc_address(Handle h, const char *name) 43 | { 44 | // *add 1.2.0 if there's a supplied .imp file, we use that 45 | // *add 1.2.2 (Eric) if it's not in the imp file, try the DLL... 46 | // *add 1.2.5 imp file may contain _absolute_ addresses 47 | if (Builtin::using_ordinal_lookup()) { 48 | int ordn = Builtin::lookup_ordinal(name); 49 | if (ordn!=0) { 50 | if (Builtin::lookup_is_ordinal()) 51 | name = (const char *)ordn; 52 | // and pass through 53 | else return (void *)ordn; 54 | } 55 | } 56 | return (void*)GetProcAddress((HINSTANCE)h,name); 57 | } 58 | 59 | Handle get_process_handle() 60 | { 61 | return (Handle) GetModuleHandle(NULL); 62 | } 63 | 64 | #else 65 | #include 66 | #include 67 | #include 68 | #include 69 | #include "directcall.h" 70 | 71 | char *itoa(int val, char *buff, int) 72 | { 73 | sprintf(buff,"%d",val); 74 | return buff; 75 | } 76 | 77 | long get_file_time(const char *filename) 78 | { 79 | struct stat st; 80 | stat(filename,&st); 81 | return st.st_mtime; 82 | } 83 | 84 | // *ch 1.2.9 patch 85 | #ifdef __BEOS__ 86 | #include 87 | #include 88 | #include 89 | /* XXX:FIXME: make it all native */ 90 | #include 91 | 92 | Handle get_process_handle() 93 | { 94 | image_info ii; 95 | int32 cookie = 0; 96 | while (get_next_image_info(0, &cookie, &ii) >= B_OK) { 97 | if (ii.type == B_APP_IMAGE) 98 | return (Handle) ii.id; 99 | } 100 | return (Handle) 0; 101 | } 102 | 103 | Handle load_library(const char *name) 104 | { 105 | image_info ii; 106 | int32 cookie = 0; 107 | /* XXX: needs a better euristic */ 108 | while (get_next_image_info(0, &cookie, &ii) >= B_OK) { 109 | printf("img: %s\n", ii.name); 110 | if (strstr(ii.name, name)) { 111 | puts("match"); 112 | return (Handle)ii.id; 113 | } 114 | } 115 | printf("dlopen(%s)\n", name); 116 | /* not yet loaded: load it ourselves */ 117 | return dlopen(name, RTLD_LAZY); 118 | } 119 | 120 | void free_library(Handle h) 121 | { 122 | image_info ii; 123 | image_id img = (image_id)h; 124 | printf("free_library(%08lx)\n", h); /* XXX:DBG */ 125 | if (get_image_info(img, &ii) == B_OK) { 126 | if (ii.type == B_ADD_ON_IMAGE) 127 | unload_add_on(img); 128 | } 129 | } 130 | 131 | void *get_proc_address(Handle h, const char *name) 132 | { 133 | void *sym; 134 | image_id img = (image_id)h; 135 | printf("get_proc_address(%08lx, %s)\n", h, name); /* XXX:DBG */ 136 | // *add 1.2.4 In the case of Linux, the .IMP file actually contains 137 | // absolute addresses. 138 | if (Builtin::using_ordinal_lookup()) { 139 | int ordn = Builtin::lookup_ordinal(name); 140 | if (ordn!=0) { 141 | return (void *)ordn; 142 | } 143 | } 144 | if (get_image_symbol(img, name, B_SYMBOL_TYPE_ANY, &sym) < B_OK) 145 | return NULL; 146 | return sym; 147 | } 148 | 149 | #else /* __BEOS__ */ 150 | #include 151 | 152 | Handle get_process_handle() 153 | { 154 | return NULL; 155 | } 156 | 157 | Handle load_library(const char *name) 158 | { 159 | Handle h = dlopen(*name!=0 ? name : NULL,RTLD_LAZY); 160 | if (h == NULL) { 161 | puts(dlerror()); 162 | } 163 | return h; 164 | } 165 | 166 | void free_library(Handle h) 167 | { 168 | dlclose(h); 169 | } 170 | 171 | void *get_proc_address(Handle h, const char *name) 172 | { 173 | // *add 1.2.4 In the case of Linux, the .IMP file actually contains 174 | // absolute addresses. 175 | if (Builtin::using_ordinal_lookup()) { 176 | int ordn = Builtin::lookup_ordinal(name); 177 | if (ordn!=0) { 178 | return (void *)ordn; 179 | } 180 | } 181 | return dlsym(h,name); 182 | } 183 | 184 | #endif /* __BEOS__ */ 185 | 186 | #endif /* _WIN32 */ 187 | 188 | 189 | -------------------------------------------------------------------------------- /src/os.h: -------------------------------------------------------------------------------- 1 | // os.h 2 | // *ch 1.2.9 patch (argues with standard BeOS header) 3 | #ifndef _UNDERC_OS_H 4 | #define _UNDERC_OS_H 5 | 6 | typedef void *Handle; 7 | long get_file_time(const char *file); 8 | Handle load_library(const char *name); 9 | void free_library(Handle h); 10 | void *get_proc_address(Handle h, const char *name); 11 | Handle get_process_handle(); 12 | 13 | #endif 14 | 15 | -------------------------------------------------------------------------------- /src/parser.h: -------------------------------------------------------------------------------- 1 | typedef union { 2 | int val; /* opcodes and types */ 3 | Entry *tptr; /* identifiers and constants */ 4 | } YYSTYPE; 5 | #define LBRACE 258 6 | #define RBRACE 259 7 | #define LPAREN 260 8 | #define RPAREN 261 9 | #define CLASS 262 10 | #define PROC 263 11 | #define VIRTUAL 264 12 | #define STATIC 265 13 | #define ARG 266 14 | #define LOAD 267 15 | #define LLOCAL 268 16 | #define STRING 269 17 | #define INTEGER 270 18 | #define NUMBER 271 19 | #define IDEN 272 20 | #define USERTYPE 273 21 | #define OPCODE 274 22 | #define JUMP 275 23 | #define DOT 276 24 | #define SCOPE 277 25 | #define COLON 278 26 | #define COMMA 279 27 | #define RBOX 280 28 | #define LBOX 281 29 | #define DELIM 282 30 | #define TYPENAME 283 31 | 32 | 33 | extern YYSTYPE yylval; 34 | 35 | -------------------------------------------------------------------------------- /src/program.h: -------------------------------------------------------------------------------- 1 | // program.h 2 | namespace Program { 3 | enum RunType { new_thread, new_window, same_window }; 4 | void stop_main(bool is_error); 5 | int call_main(int argc, char **argv,RunType how=new_thread); 6 | bool run(char *cmdline,bool same_thread=false); 7 | bool in_main_thread(); 8 | int run_int_function(int flags, int& retval); 9 | void compile_function(void *e); 10 | void pause_thread(); 11 | bool thread_is_paused(); 12 | void release_thread(); 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/signature.h: -------------------------------------------------------------------------------- 1 | /* SIGNATURE.H 2 | */ 3 | 4 | #ifndef _SIGNATURE_H 5 | #define _SIGNATURE_H 6 | 7 | // for now, Signature acts as a list of types 8 | // and also has a return type and a (maybe NULL) class ptr. 9 | // *fix 1.2.3 (Eric) Ensure that all fields are properly initialized 10 | #include 11 | typedef std::list ArgList; 12 | 13 | class Signature { 14 | protected: 15 | Type m_ret_type; 16 | Class *m_class_ptr; 17 | TypeArray m_arg_types; 18 | int m_byte_size; 19 | bool m_stdarg; 20 | bool m_is_const, m_is_static; // only for methods 21 | ArgList *m_arg_names; 22 | public: 23 | typedef TypeArray::const_iterator iterator; 24 | 25 | Signature(Type rtype=t_void, Class *cptr=NULL) 26 | : m_ret_type(rtype),m_class_ptr(cptr),m_arg_names(NULL),m_is_const(false), 27 | m_is_static(false),m_byte_size(0),m_stdarg(false) 28 | {} 29 | 30 | Signature(Type rtype, const TypeArray& tl, Class *cptr=NULL) 31 | : m_ret_type(rtype),m_class_ptr(cptr),m_is_const(false), m_is_static(true),m_arg_names(NULL), 32 | m_stdarg(false),m_byte_size(0) 33 | { 34 | m_arg_types.assign(tl.begin(),tl.end()); 35 | } 36 | 37 | void set_arg_names(const ArgList& sl) 38 | { m_arg_names = new ArgList(sl); } 39 | 40 | ArgList *get_arg_names() const { return m_arg_names; } 41 | 42 | static void set_fun_name(const string& name, bool ctor=false, bool dtor=false); 43 | static string get_fun_name(); 44 | static void write_qualified_names(bool yesno); 45 | 46 | Type return_type() const { return m_ret_type; } 47 | void adjust_return_type(Type t) { m_ret_type = t; } 48 | Class *class_ptr() const { return m_class_ptr; } 49 | void set_class_ptr(Class *pc) { m_class_ptr = pc; } 50 | int byte_size() const { return m_byte_size; } 51 | void byte_size(int sz) { m_byte_size = sz; } 52 | void set_const() { m_is_const = true; } 53 | bool is_const() const { return m_is_const; } 54 | void set_not_static() { m_is_static = false; } 55 | bool is_static() const { return m_is_static; } 56 | bool stdarg() const { return m_stdarg; } 57 | void stdarg(bool stdarg) { m_stdarg = stdarg; } 58 | 59 | bool match(const Signature& sig, bool do_strict=false) const; 60 | 61 | // list-like interface! 62 | void push_back(Type t) { m_arg_types.push_back(t); } 63 | int size() const { return m_arg_types.size(); } 64 | iterator begin() const { return m_arg_types.begin(); } 65 | iterator end() const { return m_arg_types.end(); } 66 | 67 | // this naive impl. is poss. because TypeArray _really_ is a TypeList!! 68 | const TypeList& type_list() const { return m_arg_types; } 69 | 70 | }; 71 | 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /src/stack.h: -------------------------------------------------------------------------------- 1 | /* STACK.H 2 | * a simple parametrized stack class 3 | * Note: we roll our own, rather than use the std implementation, because: 4 | * (a) pop() should return a value; _drop()_ doesn't. 5 | * (b) the execution stack needs to operate in quadwords as well as doublewords. 6 | */ 7 | 8 | #ifndef __STACK_H 9 | #define __STACK_H 10 | template 11 | class Stack { 12 | int m_cap; 13 | T m_arr[STACKSIZE]; 14 | int m_p; 15 | public: 16 | Stack(T t) { clear(); push(t); m_cap = STACKSIZE; } 17 | Stack() { clear(); m_cap = STACKSIZE; } 18 | void clear() { m_p = -1; } 19 | 20 | Stack& operator = (const Stack& st) 21 | { 22 | m_p = st.m_p; 23 | for(int i = 0; i <= m_p; i++) m_arr[i] = st.m_arr[i]; 24 | return *this; 25 | } 26 | 27 | bool empty() 28 | { return m_p == -1; } 29 | 30 | int depth() 31 | { return m_p+1; } 32 | 33 | int capacity() 34 | { return m_cap; } 35 | 36 | void push(T v) 37 | { m_arr[++m_p] = v; } 38 | 39 | void drop() 40 | { m_p--; } 41 | 42 | T pop() 43 | { return m_arr[m_p--]; } 44 | 45 | T& TOS() 46 | { return m_arr[m_p]; } 47 | 48 | T *ref_to_TOS(int depth) 49 | { return &m_arr[m_p + depth]; } 50 | 51 | void drop(int i) 52 | { m_p -= i; } 53 | }; 54 | #endif 55 | 56 | 57 | -------------------------------------------------------------------------------- /src/std_utils.h: -------------------------------------------------------------------------------- 1 | // std_utils.h 2 | // some utility templates for working with std::list 3 | #ifndef __STD_UTILS_H 4 | #define __STD_UTILS_H 5 | 6 | namespace utils { 7 | template 8 | bool add_unique(std::list& ls, T t) 9 | { 10 | // useful little routine for keeping lists unique 11 | typename std::list::iterator is; 12 | for(is = ls.begin(); is != ls.end(); ++is) 13 | if (*is == t) return false; // already there 14 | ls.push_back(t); 15 | return true; 16 | } 17 | 18 | template 19 | T list_item(std::list& ls, int i) 20 | { 21 | typename std::list::iterator is; 22 | int ii = 0; 23 | for(is = ls.begin(); is != ls.end(); ++is,++ii) 24 | if (ii == i) return *is; 25 | return 0; 26 | } 27 | 28 | template 29 | bool find(std::list& ls, T t) 30 | { 31 | typename std::list::iterator is; 32 | for(is = ls.begin(); is != ls.end(); ++is) 33 | if (*is == t) return true; 34 | return false; 35 | } 36 | 37 | } 38 | #endif 39 | -------------------------------------------------------------------------------- /src/templates.h: -------------------------------------------------------------------------------- 1 | // TEMPLATES.H 2 | 3 | #ifndef __TEMPLATES_H 4 | #define __TEMPLATES_H 5 | 6 | class TemplateEntry; // forward 7 | class TemplateInstance; 8 | 9 | const int INSTANTIATION_CONTEXT = 805; 10 | 11 | class DummyType: public NamedObject { 12 | private: 13 | Type m_type; 14 | PEntry m_entry; 15 | public: 16 | DummyType(const string& name, Type t=t_null, PEntry pe=NULL) 17 | : NamedObject(name), m_type(t),m_entry(pe) { } 18 | 19 | Type type() { return m_type; } 20 | PEntry entry() { return m_entry; } 21 | void entry(PEntry pe) { m_entry = pe; } 22 | bool bind_to(Type t); 23 | string value_as_string(); 24 | bool unbound() { return m_type == t_null; } 25 | void unbind() { bind_to(t_null); } 26 | }; 27 | 28 | class IContext: public Table { 29 | private: 30 | TypeList m_formal_parms; 31 | public: 32 | IContext(Table *parent); 33 | const TypeList& formal_parms() { return m_formal_parms; } 34 | void set_formal_parms(const TypeList& tl) { m_formal_parms = tl; } 35 | }; 36 | 37 | class Template { 38 | private: 39 | IContext *m_context; 40 | char *m_buffer; 41 | TemplateEntry *m_templ_entry; 42 | TypeList m_formal_args; // do we need this? 43 | string m_file; 44 | StringList m_methods; 45 | int m_lineno; 46 | public: 47 | Template(TemplateEntry *te, const TypeList& tl, IContext *cntxt); 48 | 49 | int match(const TypeList& tl); 50 | void grab(); 51 | void instantiate(TemplateInstance *inst); 52 | bool is_class(); 53 | string name(); 54 | TemplateEntry *get_entry() { return m_templ_entry; } 55 | IContext *context() { return m_context; } 56 | StringList& methods() { return m_methods; } 57 | const TypeList& formal_args(); 58 | TypeList& formal_parms(); 59 | static Type dummy(Type t, string name); 60 | static Type dummy(PEntry pe); 61 | static bool type_contains(Type t1, Type t2); 62 | static Template *as_template(Type t); 63 | static Type get_template_type(PEntry te, TypeList *ptl); 64 | static void do_template_header(TypeList *ptl); 65 | static void do_function_template(); 66 | static void do_class_template(int s_or_c, string name, int deriv, TypeList *ptl); 67 | static void grab_function_body(bool plain_method, char* body); 68 | static char* generate_function_header(string name, Signature* sig, bool plain_method); 69 | static char* generate_function_header(Function* pf, bool plain_method, bool qualified_names); 70 | }; 71 | 72 | class TemplateInstance { 73 | private: 74 | TypeList m_type_parms; 75 | TypeList m_type_args; 76 | Template *m_template; 77 | void *m_data; 78 | PEntry m_entry; 79 | bool m_instantiated; 80 | public: 81 | TemplateInstance(Template *templ, const TypeList& parms); 82 | 83 | TypeList& type_parms() { return m_type_parms; } 84 | Template * get_template() { return m_template; } 85 | const TypeList& type_list() { return m_type_args; } 86 | void *data() { return m_data; } 87 | void data(void *d) { m_data = d; } 88 | PEntry entry() { return m_entry; } 89 | void entry(PEntry pe) { m_entry = pe; } 90 | bool instantiated() { return m_instantiated; } 91 | void instantiated(bool y) { m_instantiated = y; } 92 | string name(); 93 | Type type(); 94 | }; 95 | 96 | typedef std::list