diff --git a/OBXLJ.pro b/OBXLJ.pro index 0db0277..97bcf68 100644 --- a/OBXLJ.pro +++ b/OBXLJ.pro @@ -37,7 +37,8 @@ DEFINES += OBX_BBOX include( ObxParser.pri ) -DEFINES += _LJTOOLS_DONT_CREATE_TAIL_CALLS # crashes otherwise in are-we-fast-yet runall +DEFINES += LUA_ENGINE_USE_DEFAULT_PRINT +#DEFINES += _LJTOOLS_DONT_CREATE_TAIL_CALLS SOURCES += \ ObxLjMain.cpp \ @@ -76,17 +77,25 @@ CONFIG(debug, debug|release) { DEFINES += _DEBUG } -INCLUDEPATH += .. ../LjTools/luajit-2.0 -DEFINES += LUA_ENGINE_USE_DEFAULT_PRINT - -include( ../LuaJIT/src/LuaJit.pri ){ - LIBS += -ldl -} else { - LIBS += -lluajit +win32 { + INCLUDEPATH += .. ../LjTools/luajit-2.0 + LIBS += -L../LuaJIT/src -llua51 } -QMAKE_LFLAGS += -rdynamic -ldl -#rdynamic is required so that the LjLibFfi functions are visible to LuaJIT FFI +linux { + include( ../LuaJIT/src/LuaJit.pri ){ + LIBS += -ldl + } else { + LIBS += -lluajit + } + + QMAKE_LFLAGS += -rdynamic -ldl + #rdynamic is required so that the LjLibFfi functions are visible to LuaJIT FFI +} +macx { + include( ../LuaJIT/src/LuaJit.pri ) + QMAKE_LFLAGS += -rdynamic -ldl -pagezero_size 10000 -image_base 100000000 +} RESOURCES += \ diff --git a/ObxIde.cpp b/ObxIde.cpp index 36072d4..9ab45f1 100644 --- a/ObxIde.cpp +++ b/ObxIde.cpp @@ -115,6 +115,17 @@ class Ide::Editor : public CodeEditor setPaintIndents(false); d_hl = new Highlighter( document() ); updateTabWidth(); + QSettings set; + if( !set.contains("CodeEditor/Font") ) + { + QFont monospace("Monospace",9); + if( !monospace.exactMatch() ) + { + monospace = QFont("DejaVu Sans Mono",9); + monospace.setStyleName("Book"); + } + setFont(monospace); + } } ~Editor() @@ -511,15 +522,15 @@ Ide::Ide(QWidget *parent) enableDbgMenu(); - createTerminal(); - createDumpView(); createMods(); createMod(); createHier(); - createErrs(); createXref(); - createStack(); + createErrs(); + createDumpView(); createLocals(); + createStack(); + createTerminal(); createMenu(); setCentralWidget(d_tab); @@ -598,11 +609,13 @@ void Ide::createTerminal() dock->setWidget(d_term); addDockWidget( Qt::BottomDockWidgetArea, dock ); new Gui::AutoShortcut( tr("CTRL+SHIFT+C"), this, d_term, SLOT(onClear()) ); + connect( d_rt->getLua(), SIGNAL(onNotify(int,QByteArray,int)), dock, SLOT(show()) ); } void Ide::createDumpView() { QDockWidget* dock = new QDockWidget( tr("Bytecode"), this ); + dock->setVisible(false); dock->setObjectName("Bytecode"); dock->setAllowedAreas( Qt::AllDockWidgetAreas ); dock->setFeatures( QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable ); @@ -735,6 +748,7 @@ void Ide::createXref() void Ide::createStack() { QDockWidget* dock = new QDockWidget( tr("Stack"), this ); + dock->setVisible(false); dock->setObjectName("Stack"); dock->setAllowedAreas( Qt::AllDockWidgetAreas ); dock->setFeatures( QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable ); @@ -747,13 +761,14 @@ void Ide::createStack() d_stack->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents); d_stack->header()->setSectionResizeMode(3, QHeaderView::Stretch); dock->setWidget(d_stack); - addDockWidget( Qt::LeftDockWidgetArea, dock ); + addDockWidget( Qt::RightDockWidgetArea, dock ); connect( d_stack, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),this,SLOT(onStackDblClicked(QTreeWidgetItem*,int)) ); } void Ide::createLocals() { QDockWidget* dock = new QDockWidget( tr("Locals"), this ); + dock->setVisible(false); dock->setObjectName("Locals"); dock->setAllowedAreas( Qt::AllDockWidgetAreas ); dock->setFeatures( QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable ); @@ -764,7 +779,7 @@ void Ide::createLocals() d_locals->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); d_locals->header()->setSectionResizeMode(1, QHeaderView::Stretch); dock->setWidget(d_locals); - addDockWidget( Qt::LeftDockWidgetArea, dock ); + addDockWidget( Qt::RightDockWidgetArea, dock ); } void Ide::createMenu() @@ -787,7 +802,7 @@ void Ide::createMenu() pop->addCommand( "Remove Import Path...", this, SLOT(onRemoveDir()) ); pop->addSeparator(); pop->addCommand( "Built-in Oakwood", this, SLOT(onOakwood()) ); - pop->addCommand( "Built-in Oberon System Inner", this, SLOT(onObSysInner()) ); + pop->addCommand( "Built-in Oberon Sys. Inner Mod.", this, SLOT(onObSysInner()) ); pop->addCommand( "Set Working Directory...", this, SLOT( onWorkingDir() ) ); pop->addSeparator(); pop->addCommand( "Compile", this, SLOT(onCompile()), tr("CTRL+T"), false ); @@ -855,7 +870,7 @@ void Ide::createMenuBar() pop->addCommand( "Remove Module...", this, SLOT(onRemoveFile()) ); pop->addSeparator(); pop->addCommand( "Built-in Oakwood", this, SLOT(onOakwood()) ); - pop->addCommand( "Built-in Oberon System Inner", this, SLOT(onObSysInner()) ); + pop->addCommand( "Built-in Oberon System Inner Modules", this, SLOT(onObSysInner()) ); pop->addCommand( "Set Working Directory...", this, SLOT( onWorkingDir() ) ); pop = new Gui::AutoMenu( tr("Build && Run"), this ); @@ -2183,6 +2198,7 @@ void Ide::fillLocals() if( d_rt->getLua()->getMode() == Lua::Engine2::PcMode ) { fillRawLocals(d_locals, d_rt->getLua()); + d_locals->parentWidget()->show(); return; } @@ -2244,6 +2260,7 @@ void Ide::fillLocals() #if 0 // TEST, usually 0 fillRawLocals(d_locals, d_rt->getLua()); #endif + d_locals->parentWidget()->show(); } static inline Type* derefed( Type* type ) @@ -3062,8 +3079,9 @@ int main(int argc, char *argv[]) a.setOrganizationName("me@rochus-keller.ch"); a.setOrganizationDomain("github.com/rochus-keller/Oberon"); a.setApplicationName("Oberon+ IDE"); - a.setApplicationVersion("0.7.25"); - a.setStyle("Fusion"); + a.setApplicationVersion("0.8"); + a.setStyle("Fusion"); + QFontDatabase::addApplicationFont(":/font/DejaVuSansMono.ttf"); // "DejaVu Sans Mono" Ide w; if( a.arguments().size() > 1 ) diff --git a/ObxIde.qrc b/ObxIde.qrc index dc76ad0..4f83990 100644 --- a/ObxIde.qrc +++ b/ObxIde.qrc @@ -43,5 +43,6 @@ images/marker.png images/alias_priv.png images/alias.png + font/DejaVuSansMono.ttf diff --git a/ObxLjMain.cpp b/ObxLjMain.cpp index a201c5a..fcabd45 100644 --- a/ObxLjMain.cpp +++ b/ObxLjMain.cpp @@ -65,7 +65,7 @@ int main(int argc, char *argv[]) a.setOrganizationName("Rochus Keller"); a.setOrganizationDomain("https://github.com/rochus-keller/Oberon"); a.setApplicationName("OBXLJ"); - a.setApplicationVersion("2021-07-12"); + a.setApplicationVersion("2021-07-13"); QTextStream out(stdout); out << "OBXLJ version: " << a.applicationVersion() << diff --git a/README.md b/README.md index 3932b6b..4d5088f 100644 --- a/README.md +++ b/README.md @@ -1,83 +1,65 @@ -## Welcome to the Oberon parser, code model, browser, compiler and IDE +## Welcome to the Oberon+ parser, code model, compiler and IDE -This project started out as an Oberon-07 (see http://www.projectoberon.net/wirth/Oberon/Oberon07.Report.pdf) parser, code model and transpiler written in C++ and Qt, with the goal to build tools to better understand the Lola-2 compiler and to automatically translate it to maintainable C++ with minimal dependencies to other C++ libraries, and with no dependencies to the Oberon System (see https://github.com/rochus-keller/lola and https://github.com/rochus-keller/lolacreator). +This project started out as an [Oberon-07](http://www.projectoberon.net/wirth/Oberon/Oberon07.Report.pdf) parser, code model and transpiler written in C++ and Qt, with the goal to build tools to better understand the [Lola-2](https://www.inf.ethz.ch/personal/wirth/Lola/Lola2.pdf) compiler and to automatically translate it to maintainable C++ with minimal dependencies to other C++ libraries, and with no dependencies to the Oberon System (see the [Lola](https://github.com/rochus-keller/lola) and [LolaCreator](https://github.com/rochus-keller/lolacreator) repositories). -Oberon turned out to be a language very well suited for compiler front and backend experiments because it is decently simple but still powerful enough to build real-world software as it supports pointers, static and stack based data structures and call by reference which are not usually available with scripting languages. In consequence an other goal of this project is to study the feasibility of reusing LuaJIT (see http://luajit.org/) as a backend for statically typed programming languages like Oberon. The current implementation of the compiler is able to map full Oberon to Lua source code or LuaJIT bytecode and run with decent performance on LuaJIT. There is also a compatible version of the Oberon System (see https://github.com/rochus-keller/OberonSystem) and an IDE. +Oberon turned out to be a language very well suited for compiler front and backend experiments because it is decently simple but still powerful enough to build real-world software, as it supports pointers, static and stack based data structures and call by reference, which are not usually available with scripting languages. In consequence, an other goal of this project is to study the feasibility of reusing [LuaJIT](http://luajit.org/) as a backend for statically typed programming languages like Oberon (see [this article](https://medium.com/@rochus.keller/implementing-call-by-reference-and-call-by-name-in-lua-47b9d1003cc2)). The current implementation of the compiler is able to map full Oberon+ to LuaJIT bytecode and run with decent performance (see [this report](https://github.com/rochus-keller/Oberon/blob/master/testcases/Are-we-fast-yet/Are-we-fast-yet_results.pdf)) on LuaJIT. There is also a [compatible version of the Oberon System](https://github.com/rochus-keller/OberonSystem), as well as a powerful IDE with semantic navigation and source-level debugging (see below). -During my work with Oberon and systems implemented in Oberon, I kept asking myself what properties the language would need to have so that I could use it for my own systems too, without giving up the goal of making it as simple as possible. From these considerations a new language emerged, which I call "Oberon+" (i.e. "Oberon with extensions", abbreviated OBX); is a general-purpose, procedural and object-oriented programming language in the tradition of Oberon-07 and Oberon-2, with all the elements of these languages, plus parametric polymorphism, enumerations and simplifications such as optional lower case keywords and semicolons. Oberon+ is actually a superset of Oberon 90, Oberon-2 and Oberon-07, i.e. each valid program written in one of these dialects is also a valid Oberon+ program (subject to different byte sizes of the base types). See [the language report](documentation/The_Programming_Language_Oberon+.adoc) for more information. There will also be an IDE with source level debugger and different backends (LuaJIT, TCC, LLVM, etc.). But note that Oberon+ is currently **work in progress** and subject to change at any time. +During my work with Oberon and systems implemented in Oberon, I kept asking myself what properties the language would need to have so that I could use it for my own systems too, without giving up the goal of making it as simple as possible. From these considerations a new language emerged, which I call **Oberon+** (i.e. "Oberon with extensions", abbreviated OBX); it is a general-purpose, procedural and object-oriented programming language in the tradition of and based on Oberon-07, Oberon-2 and Oberon 90, with all the elements of these languages, plus generic modules, enumerations, and many additional simplifications such as support for lower case keywords, optional semicolons, and flexible declaration sequences. See [the language report](documentation/The_Programming_Language_Oberon+.adoc) for more information. The compiler supports both, Oberon+ as well as most of the syntax and semantics of the previous Oberon versions. -On my way to the Oberon+ compiler I needed a decent code browser compatible with all Oberon dialects in focus. I therefore extended the original Oberon-07 parser, code model and browser so it can now also read old Oberon and Oberon-2 code bases. +For representative examples of Oberon+ see the [Are-we-fast-yet benchmark suite migrated to Oberon+](https://github.com/rochus-keller/Oberon/tree/master/testcases/Are-we-fast-yet). It also demonstrates generic programming with collections and iterators. -More to come. +### What this repository includes -### Parser and code model features +- The old Oberon-07 validating parser with code model, Lua source code transpiler, C++ transpiler and LuaJIT bytecode compiler (file prefix Ob) +- The old OberonViewer, Oberon-07 IDE and OBNLC command line version of the compiler/transpiler +- The Oberon+ programming language specification +- The new Oberon+ validating parser, code model and LuaJIT bytecode compiler (file prefix Obx) +- The new Oberon+ IDE and OBXLJ command line version of the compiler -- Three parser versions; one generates a syntax tree and one a fully validated AST - - The parser/code model (ObLexer, ObParser, ObCodeModel) used by the code browser supports Oberon-07, Oberon 90, Oberon-2, and Component Pascal 1.7.2; - - The parser/validator (ObLexer, ObParser, ObAst, ObAstValidator) used by the Lua bytecode generator and IDE supports Oberon-07 (optionally with lower-case keywords, underscores in idents and line comments); - - The new OBX parser (ObLexer, ObxParser, ObxValidator) supports Oberon-07, Oberon 90, Oberon-2 and Oberon+. -- All parsers support syntax and (some) semantics validation, and error reporting -- ObCodeModel optionally infers and synthesizes missing modules +### Planned or work-in-progress features -### C++ Code generator features +- [x] Oberon+ validating parser +- [x] IDE with semantic navigation & source-level debugger +- [x] LuaJIT compiler backend +- [ ] Complete built-in procedure and Oakwood library implementations +- [ ] Write documentation and focus articles +- [ ] Implement a DotNet CIL compiler backend (started) +- [ ] Use a minimal Mono runtime as an alternative to the LuaJIT VM +- [ ] Implement an LLVM compiler backend +- [ ] Proceed with the programming language development (based on actual need and after careful consideration) -- Generates C++03 compatible code with no other dependencies than the standard libraries -- Generates stub headers for the synthesized (missing) modules to ease implementing the missing parts -- Arrays including strings are implemented by C++ template classes -- Modules are dynamically created to maintain the correct initialization dependencies -- Comments of the original files are also translated -- Oberon idents conflicting with C++ keywords are postfixed by underscore -- The generated code is well readable and maintainable -- Currently **only the subset of Oberon-07 used by the Lola-2 compiler is supported**; see https://github.com/rochus-keller/Lolac for an example of the generated code -- There is no garbage collector code generated yet, but an arena based collector can easily be implemented outside of the generator by customizing the _Root class; future versions will generate a regular mark & sweep collector. +### The Oberon+ IDE -### Lua source and bytecode generator features - -- Generates Lua 5.1 compatible source code only dependend on an included library and the standard libraries -- Generates LuaJIT 2.0 compatible bytecode -- The full Oberon-07 language including the Oakwood libraries are supported (note that the latter are still work in progress) -- The DEFINITION syntax is supported such that imports can have only a DEFINITION but a Lua implementation -- Full support for VAR parameters (call by reference, using thunks or multiple return values) and strings as ARRAY OF CHAR with element access -- Oberon idents conflicting with Lua keywords and standard names are postfixed with underscores -- The generated Lua source code is formatted for readability; Oberon comments are not included -- The bytecode generator is nearly feature complete; the generated code of the adapted Oberon System works quite good (whereas still work in progress) -- SYSTEM module is not supported. - -### Code browser features +This is a lean IDE with the following features: - Syntax highlighting -- Code navigation; jump to the declaration of an ident +- Semantic code navigation; jump to the declaration of an ident (CTRL+click on the ident) - Mark all idents refering to the same declaration -- Cross-referencing: list all uses of a declaration for easy navigation +- Cross-reference view: list all instances of an identifier for easy navigation +- Module view: shows the records declared in the module and their bound procedures together +- Hierarchy view: shows the inheritance relation of a selected record or the overrides of a selected bound procedure - Browsing history, forward and backward navigation - - -![OberonViewer Screenshot](http://software.rochus-keller.ch/oberonviewer_screenshot_1.png) - -### Oberon IDE features - -Same as code browser, in addition - -- Project file format: combine modules to a single project -- Oberon to LuaJIT bytecode compiler, automatic recompile when edited +- Project files combine modules into a single project and associate them with virtual import paths - Built-in LuaJIT engine - Bytecode view (LuaJIT assembler syntax), synchronized to source -- Optional Oakwood or Oberon System backend - Integrated source level debugger with breakpoints, stack trace and locals view -- A stack trace is also shown if TRACE or TRACEIF( exp: BOOLEAN ) evaluating to TRUE is executed - +- Built-in optional Oakwood or Oberon System backend library -![Oberon IDE Screenshot](http://software.rochus-keller.ch/screenshot_oberon_system_in_debugger.png) +![Oberon+ IDE Screenshot](http://software.rochus-keller.ch/obxide_0.7.13.png) -Here is another [screenshot](http://software.rochus-keller.ch/screenshot_oberon_ide_0.5.1.png). +### Oberon+ to LuaJIT bytecode compiler +- Generates LuaJIT 2.0 compatible bytecode +- The full Oberon+ language including the Oakwood libraries are supported +- The SYSTEM module is not supported +- The TRAP() and TRAPIF(condition:BOOLEAN) bult-in procedures let you escape to the debugger ### Binary versions -Here is a binary version of the Oberon IDE for Windows: http://software.rochus-keller.ch/OberonIDE_win32.zip. -Just unpack the ZIP somewhere on your drive and double-click OberonIDE.exe; Qt libraries are included as well as the demo Oberon System (open the project using CTRL+O and then run it using CTRL+R, or right-click to open context menus and select the commands from there). +Here is a binary version of the Oberon+ IDE for Windows: http://software.rochus-keller.ch/OberonIDE_win32.zip. +Just unpack the ZIP somewhere on your drive and double-click ObxIDE.exe; Qt libraries are included, as well as the OBXLJ command line tools, the demo Oberon System and some other example projects (open the project using CTRL+O and then run it using CTRL+R, or right-click to open context menus and select the commands from there). And here is a version of the Oberon IDE for Linux x86: http://software.rochus-keller.ch/OberonIDE_linux_i368.tar.gz. It requires a preinstalled Qt version >= 5.4. @@ -85,33 +67,29 @@ It requires a preinstalled Qt version >= 5.4. Here is a version of the Oberon IDE for macOS x86_64 (>= El Capitan): http://software.rochus-keller.ch/OberonIDE_macOS_x64.dmg. The app can just be moved to the drive or used directly from the mounted DMG; everything required is included, also the Oberon System demo; please note that the CTRL key is mapped to the command key on Mac, but you have to press CTRL+mouse key to trigger the right mouse button; to summarize: just click=left click, command+click=middle click, CTRL+click=right click; note that the shortcuts can differ between platforms. - -Here is a binary version of OberonViewer for Windows: http://software.rochus-keller.ch/OberonViewer_win32.zip +Here is a binary version of the OberonViewer for Windows: http://software.rochus-keller.ch/OberonViewer_win32.zip Just download, unpack and run it; no installer is needed. The ZIP includes the needed Qt libraries. Here is a binary version of OberonViewer for Linux x86: http://software.rochus-keller.ch/OberonViewer_linux_x86.tar.gz It requires a preinstalled Qt version >= 5.4. -Here is a binary version of OBNLC (Lua source code and bytecode generator) for Linux x86: http://software.rochus-keller.ch/OBNLC_linux_x86.tar.gz. -libQt5Core.so is required to run the binary. - - ### Build Steps -Follow these steps if you want to build OberonViewer yourself: +Follow these steps if you want to build e.g. the Oberon+ IDE yourself: 1. Make sure a Qt 5.x (libraries and headers) version compatible with your C++ compiler is installed on your system. -1. Download the Oberon source code from https://github.com/rochus-keller/Oberon/archive/master.zip and unpack it. -1. Goto the unpacked directory and execute `QTDIR/bin/qmake OberonViewer.pro` (see the Qt documentation concerning QTDIR). +1. Create an empty directory, call it e.g. Build. +1. Download https://github.com/rochus-keller/GuiTools/archive/master.zip and unpack to in the Build directory. Rename it to GuiTools. +1. Download https://github.com/rochus-keller/LjTools/archive/master.zip and unpack it to the Build directory. Rename it to LjTools. +1. Download https://github.com/rochus-keller/LuaJIT/archive/LjTools.zip and unpack it to the Build directory. Rename it to LuaJIT. Go to the src subdirectory and run the build script appropriate to your platform (see LuaJIT/doc/install.html for more information). +1. Download https://github.com/rochus-keller/Oberon/archive/master.zip and unpack it to the Build directory. Rename it to Oberon. +1. Goto the Build/Oberon directory and execute e.g. `QTDIR/bin/qmake ObxIde.pro` (see the Qt documentation concerning QTDIR). 1. Run make; after a couple of seconds you will find the executable in the build directory. -Alternatively you can open OberonViewer.pro using QtCreator and build it there. - -The library makes use of a parser generated by Coco/R based on input from EbnfStudio. There is no other dependency than the Qt Core library. -The repository already contains the generated files. In order to regenerate ObParser.cpp/h you have to use this version of Coco/R: https://github.com/rochus-keller/Coco +Alternatively you can open ObxIde.pro using QtCreator and build it there. -Note that this procedure also applies to OberonIde.pro, OBNLC.pro, and ObnLjEditor.pro, but https://github.com/rochus-keller/GuiTools/archive/master.zip and https://github.com/rochus-keller/LjTools/archive/master.zip have to be downloaded and unpacked to the same directory. The LuaJIT 2.0 library is needed as well; please use the LjTools branch of https://github.com/rochus-keller/LuaJIT/tree/LjTools. +Note that this procedure also applies to OBXLJ.pro, OberonIde.pro, OBNLC.pro, and OberonViewer.pro. ## Support If you need support or would like to post issues or feature requests please use the Github issue list at https://github.com/rochus-keller/Oberon/issues or send an email to the author. diff --git a/README_old.md b/README_old.md new file mode 100644 index 0000000..3932b6b --- /dev/null +++ b/README_old.md @@ -0,0 +1,120 @@ +## Welcome to the Oberon parser, code model, browser, compiler and IDE + +This project started out as an Oberon-07 (see http://www.projectoberon.net/wirth/Oberon/Oberon07.Report.pdf) parser, code model and transpiler written in C++ and Qt, with the goal to build tools to better understand the Lola-2 compiler and to automatically translate it to maintainable C++ with minimal dependencies to other C++ libraries, and with no dependencies to the Oberon System (see https://github.com/rochus-keller/lola and https://github.com/rochus-keller/lolacreator). + +Oberon turned out to be a language very well suited for compiler front and backend experiments because it is decently simple but still powerful enough to build real-world software as it supports pointers, static and stack based data structures and call by reference which are not usually available with scripting languages. In consequence an other goal of this project is to study the feasibility of reusing LuaJIT (see http://luajit.org/) as a backend for statically typed programming languages like Oberon. The current implementation of the compiler is able to map full Oberon to Lua source code or LuaJIT bytecode and run with decent performance on LuaJIT. There is also a compatible version of the Oberon System (see https://github.com/rochus-keller/OberonSystem) and an IDE. + +During my work with Oberon and systems implemented in Oberon, I kept asking myself what properties the language would need to have so that I could use it for my own systems too, without giving up the goal of making it as simple as possible. From these considerations a new language emerged, which I call "Oberon+" (i.e. "Oberon with extensions", abbreviated OBX); is a general-purpose, procedural and object-oriented programming language in the tradition of Oberon-07 and Oberon-2, with all the elements of these languages, plus parametric polymorphism, enumerations and simplifications such as optional lower case keywords and semicolons. Oberon+ is actually a superset of Oberon 90, Oberon-2 and Oberon-07, i.e. each valid program written in one of these dialects is also a valid Oberon+ program (subject to different byte sizes of the base types). See [the language report](documentation/The_Programming_Language_Oberon+.adoc) for more information. There will also be an IDE with source level debugger and different backends (LuaJIT, TCC, LLVM, etc.). But note that Oberon+ is currently **work in progress** and subject to change at any time. + +On my way to the Oberon+ compiler I needed a decent code browser compatible with all Oberon dialects in focus. I therefore extended the original Oberon-07 parser, code model and browser so it can now also read old Oberon and Oberon-2 code bases. + +More to come. + +### Parser and code model features + +- Three parser versions; one generates a syntax tree and one a fully validated AST + - The parser/code model (ObLexer, ObParser, ObCodeModel) used by the code browser supports Oberon-07, Oberon 90, Oberon-2, and Component Pascal 1.7.2; + - The parser/validator (ObLexer, ObParser, ObAst, ObAstValidator) used by the Lua bytecode generator and IDE supports Oberon-07 (optionally with lower-case keywords, underscores in idents and line comments); + - The new OBX parser (ObLexer, ObxParser, ObxValidator) supports Oberon-07, Oberon 90, Oberon-2 and Oberon+. +- All parsers support syntax and (some) semantics validation, and error reporting +- ObCodeModel optionally infers and synthesizes missing modules + +### C++ Code generator features + +- Generates C++03 compatible code with no other dependencies than the standard libraries +- Generates stub headers for the synthesized (missing) modules to ease implementing the missing parts +- Arrays including strings are implemented by C++ template classes +- Modules are dynamically created to maintain the correct initialization dependencies +- Comments of the original files are also translated +- Oberon idents conflicting with C++ keywords are postfixed by underscore +- The generated code is well readable and maintainable +- Currently **only the subset of Oberon-07 used by the Lola-2 compiler is supported**; see https://github.com/rochus-keller/Lolac for an example of the generated code +- There is no garbage collector code generated yet, but an arena based collector can easily be implemented outside of the generator by customizing the _Root class; future versions will generate a regular mark & sweep collector. + +### Lua source and bytecode generator features + +- Generates Lua 5.1 compatible source code only dependend on an included library and the standard libraries +- Generates LuaJIT 2.0 compatible bytecode +- The full Oberon-07 language including the Oakwood libraries are supported (note that the latter are still work in progress) +- The DEFINITION syntax is supported such that imports can have only a DEFINITION but a Lua implementation +- Full support for VAR parameters (call by reference, using thunks or multiple return values) and strings as ARRAY OF CHAR with element access +- Oberon idents conflicting with Lua keywords and standard names are postfixed with underscores +- The generated Lua source code is formatted for readability; Oberon comments are not included +- The bytecode generator is nearly feature complete; the generated code of the adapted Oberon System works quite good (whereas still work in progress) +- SYSTEM module is not supported. + +### Code browser features + +- Syntax highlighting +- Code navigation; jump to the declaration of an ident +- Mark all idents refering to the same declaration +- Cross-referencing: list all uses of a declaration for easy navigation +- Browsing history, forward and backward navigation + + +![OberonViewer Screenshot](http://software.rochus-keller.ch/oberonviewer_screenshot_1.png) + +### Oberon IDE features + +Same as code browser, in addition + +- Project file format: combine modules to a single project +- Oberon to LuaJIT bytecode compiler, automatic recompile when edited +- Built-in LuaJIT engine +- Bytecode view (LuaJIT assembler syntax), synchronized to source +- Optional Oakwood or Oberon System backend +- Integrated source level debugger with breakpoints, stack trace and locals view +- A stack trace is also shown if TRACE or TRACEIF( exp: BOOLEAN ) evaluating to TRUE is executed + + +![Oberon IDE Screenshot](http://software.rochus-keller.ch/screenshot_oberon_system_in_debugger.png) + + +Here is another [screenshot](http://software.rochus-keller.ch/screenshot_oberon_ide_0.5.1.png). + + + +### Binary versions + +Here is a binary version of the Oberon IDE for Windows: http://software.rochus-keller.ch/OberonIDE_win32.zip. +Just unpack the ZIP somewhere on your drive and double-click OberonIDE.exe; Qt libraries are included as well as the demo Oberon System (open the project using CTRL+O and then run it using CTRL+R, or right-click to open context menus and select the commands from there). + +And here is a version of the Oberon IDE for Linux x86: http://software.rochus-keller.ch/OberonIDE_linux_i368.tar.gz. +It requires a preinstalled Qt version >= 5.4. + +Here is a version of the Oberon IDE for macOS x86_64 (>= El Capitan): http://software.rochus-keller.ch/OberonIDE_macOS_x64.dmg. +The app can just be moved to the drive or used directly from the mounted DMG; everything required is included, also the Oberon System demo; please note that the CTRL key is mapped to the command key on Mac, but you have to press CTRL+mouse key to trigger the right mouse button; to summarize: just click=left click, command+click=middle click, CTRL+click=right click; note that the shortcuts can differ between platforms. + + +Here is a binary version of OberonViewer for Windows: http://software.rochus-keller.ch/OberonViewer_win32.zip +Just download, unpack and run it; no installer is needed. The ZIP includes the needed Qt libraries. + +Here is a binary version of OberonViewer for Linux x86: http://software.rochus-keller.ch/OberonViewer_linux_x86.tar.gz +It requires a preinstalled Qt version >= 5.4. + + +Here is a binary version of OBNLC (Lua source code and bytecode generator) for Linux x86: http://software.rochus-keller.ch/OBNLC_linux_x86.tar.gz. +libQt5Core.so is required to run the binary. + + +### Build Steps + +Follow these steps if you want to build OberonViewer yourself: + +1. Make sure a Qt 5.x (libraries and headers) version compatible with your C++ compiler is installed on your system. +1. Download the Oberon source code from https://github.com/rochus-keller/Oberon/archive/master.zip and unpack it. +1. Goto the unpacked directory and execute `QTDIR/bin/qmake OberonViewer.pro` (see the Qt documentation concerning QTDIR). +1. Run make; after a couple of seconds you will find the executable in the build directory. + +Alternatively you can open OberonViewer.pro using QtCreator and build it there. + +The library makes use of a parser generated by Coco/R based on input from EbnfStudio. There is no other dependency than the Qt Core library. +The repository already contains the generated files. In order to regenerate ObParser.cpp/h you have to use this version of Coco/R: https://github.com/rochus-keller/Coco + +Note that this procedure also applies to OberonIde.pro, OBNLC.pro, and ObnLjEditor.pro, but https://github.com/rochus-keller/GuiTools/archive/master.zip and https://github.com/rochus-keller/LjTools/archive/master.zip have to be downloaded and unpacked to the same directory. The LuaJIT 2.0 library is needed as well; please use the LjTools branch of https://github.com/rochus-keller/LuaJIT/tree/LjTools. + +## Support +If you need support or would like to post issues or feature requests please use the Github issue list at https://github.com/rochus-keller/Oberon/issues or send an email to the author. + + + diff --git a/documentation/The_Programming_Language_Oberon+.html b/documentation/The_Programming_Language_Oberon+.html index c7363f6..edff557 100644 --- a/documentation/The_Programming_Language_Oberon+.html +++ b/documentation/The_Programming_Language_Oberon+.html @@ -17,7 +17,7 @@

The Programming Language Oberon+

Rochus Keller
me@rochus-keller.ch
- 2021-06-22 + 2021-07-09
work in progress
@@ -2791,7 +2791,7 @@

10.3.1. Predeclared function procedure

INTEGER

-

length of string (up to but without the first 0X)

+

length of string (including the terminating 0X)

@@ -3165,7 +3165,7 @@

10.3.1. Predeclared function procedure

INTEGER

-

dynamic length of the string up to and not including the first +

dynamic length of the string up to and not including the terminating 0X

@@ -3175,9 +3175,7 @@

10.3.1. Predeclared function procedure

s: string

- -

same as LEN(s)

- + @@ -3526,7 +3524,9 @@

11. Modules

prefixed with an import path. There is no requirement that the import path actually exists in the file system, or that the source files corresponding to an import path are in the same file system directory. It is up to - the compiler how source files are mapped to import paths.

+ the compiler how source files are mapped to import paths. An imported + module with no import path is first looked up in the import path of the + importing module.

A module must not import itself.

diff --git a/examples/See_also b/examples/See_also new file mode 100644 index 0000000..9f49285 --- /dev/null +++ b/examples/See_also @@ -0,0 +1,5 @@ +testcases + Are-we-fast-yet + Hennessy + +https://github.com/rochus-keller/BlackboxFramework/tree/master/Minimal diff --git a/font/DejaVu.license b/font/DejaVu.license new file mode 100644 index 0000000..cdf662f --- /dev/null +++ b/font/DejaVu.license @@ -0,0 +1,99 @@ +DejaVu Fonts License + +Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. +Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below) + +Bitstream Vera Fonts Copyright +——————————————— + +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is +a trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of the fonts accompanying this license (“Fonts”) and associated +documentation files (the “Font Software”), to reproduce and distribute the +Font Software, including without limitation the rights to use, copy, merge, +publish, distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to the +following conditions: + +The above copyright and trademark notices and this permission notice shall +be included in all copies of one or more of the Font Software typefaces. + +The Font Software may be modified, altered, or added to, and in particular +the designs of glyphs or characters in the Fonts may be modified and +additional glyphs or characters may be added to the Fonts, only if the fonts +are renamed to names not containing either the words “Bitstream” or the word +“Vera”. + +This License becomes null and void to the extent applicable to Fonts or Font +Software that has been modified and is distributed under the “Bitstream +Vera” names. + +The Font Software may be sold as part of a larger software package but no +copy of one or more of the Font Software typefaces may be sold by itself. + +THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, +TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME +FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING +ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE +FONT SOFTWARE. + +Except as contained in this notice, the names of Gnome, the Gnome +Foundation, and Bitstream Inc., shall not be used in advertising or +otherwise to promote the sale, use or other dealings in this Font Software +without prior written authorization from the Gnome Foundation or Bitstream +Inc., respectively. For further information, contact: fonts at gnome dot +org. + +Arev Fonts Copyright +——————————————— + +Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the fonts accompanying this license (“Fonts”) and +associated documentation files (the “Font Software”), to reproduce +and distribute the modifications to the Bitstream Vera Font Software, +including without limitation the rights to use, copy, merge, publish, +distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to +the following conditions: + +The above copyright and trademark notices and this permission notice +shall be included in all copies of one or more of the Font Software +typefaces. + +The Font Software may be modified, altered, or added to, and in +particular the designs of glyphs or characters in the Fonts may be +modified and additional glyphs or characters may be added to the +Fonts, only if the fonts are renamed to names not containing either +the words “Tavmjong Bah” or the word “Arev”. + +This License becomes null and void to the extent applicable to Fonts +or Font Software that has been modified and is distributed under the +“Tavmjong Bah Arev” names. + +The Font Software may be sold as part of a larger software package but +no copy of one or more of the Font Software typefaces may be sold by +itself. + +THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL +TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +Except as contained in this notice, the name of Tavmjong Bah shall not +be used in advertising or otherwise to promote the sale, use or other +dealings in this Font Software without prior written authorization +from Tavmjong Bah. For further information, contact: tavmjong @ free +. fr. diff --git a/font/DejaVuSansMono.ttf b/font/DejaVuSansMono.ttf new file mode 100644 index 0000000..1376228 Binary files /dev/null and b/font/DejaVuSansMono.ttf differ diff --git a/testcases/are-we-fast-yet/AUTORS.md b/testcases/Are-we-fast-yet/AUTORS.md similarity index 100% rename from testcases/are-we-fast-yet/AUTORS.md rename to testcases/Are-we-fast-yet/AUTORS.md diff --git a/testcases/Are-we-fast-yet/Are-we-fast-yet_results.ods b/testcases/Are-we-fast-yet/Are-we-fast-yet_results.ods new file mode 100644 index 0000000..f846e77 Binary files /dev/null and b/testcases/Are-we-fast-yet/Are-we-fast-yet_results.ods differ diff --git a/testcases/Are-we-fast-yet/Are-we-fast-yet_results.pdf b/testcases/Are-we-fast-yet/Are-we-fast-yet_results.pdf new file mode 100644 index 0000000..531695d Binary files /dev/null and b/testcases/Are-we-fast-yet/Are-we-fast-yet_results.pdf differ diff --git a/testcases/are-we-fast-yet/Benchmark.obx b/testcases/Are-we-fast-yet/Benchmark.obx similarity index 100% rename from testcases/are-we-fast-yet/Benchmark.obx rename to testcases/Are-we-fast-yet/Benchmark.obx diff --git a/testcases/are-we-fast-yet/Bounce.obx b/testcases/Are-we-fast-yet/Bounce.obx similarity index 100% rename from testcases/are-we-fast-yet/Bounce.obx rename to testcases/Are-we-fast-yet/Bounce.obx diff --git a/testcases/are-we-fast-yet/CD.obx b/testcases/Are-we-fast-yet/CD.obx similarity index 100% rename from testcases/are-we-fast-yet/CD.obx rename to testcases/Are-we-fast-yet/CD.obx diff --git a/testcases/are-we-fast-yet/CD2.obx b/testcases/Are-we-fast-yet/CD2.obx similarity index 100% rename from testcases/are-we-fast-yet/CD2.obx rename to testcases/Are-we-fast-yet/CD2.obx diff --git a/testcases/are-we-fast-yet/DeltaBlue.obx b/testcases/Are-we-fast-yet/DeltaBlue.obx similarity index 100% rename from testcases/are-we-fast-yet/DeltaBlue.obx rename to testcases/Are-we-fast-yet/DeltaBlue.obx diff --git a/testcases/are-we-fast-yet/Harness.obx b/testcases/Are-we-fast-yet/Harness.obx similarity index 100% rename from testcases/are-we-fast-yet/Harness.obx rename to testcases/Are-we-fast-yet/Harness.obx diff --git a/testcases/are-we-fast-yet/Havlak.obx b/testcases/Are-we-fast-yet/Havlak.obx similarity index 98% rename from testcases/are-we-fast-yet/Havlak.obx rename to testcases/Are-we-fast-yet/Havlak.obx index 3c5365e..28373f4 100644 --- a/testcases/are-we-fast-yet/Havlak.obx +++ b/testcases/Are-we-fast-yet/Havlak.obx @@ -586,10 +586,7 @@ module Havlak if v # UNVISITED then if this.this.isAncestor(this.w, v) then this.this.backPreds.at(this.w).append(v) - else // TODO - // fix to avoid misterious crash in JIT (2021-07-11) - //tmp := this.this.nonBackPreds.at(this.w) - //tmp.add(v) + else this.this.nonBackPreds.at(this.w).add(v) end end @@ -743,9 +740,6 @@ module Havlak if ~this.this.isAncestor(this.w, ydash.dfsNumber) then this.this.type_[this.w] := BB_IRREDUCIBLE - // fix to avoid misterious crash in JIT (2021-07-11) TODO - //tmp := this.this.nonBackPreds.at(this.w) - //tmp.add(ydash.dfsNumber) this.this.nonBackPreds.at(this.w).add(ydash.dfsNumber) else if ydash.dfsNumber # this.w then diff --git a/testcases/are-we-fast-yet/Json.obx b/testcases/Are-we-fast-yet/Json.obx similarity index 100% rename from testcases/are-we-fast-yet/Json.obx rename to testcases/Are-we-fast-yet/Json.obx diff --git a/testcases/are-we-fast-yet/LICENSE.md b/testcases/Are-we-fast-yet/LICENSE.md similarity index 100% rename from testcases/are-we-fast-yet/LICENSE.md rename to testcases/Are-we-fast-yet/LICENSE.md diff --git a/testcases/are-we-fast-yet/List.obx b/testcases/Are-we-fast-yet/List.obx similarity index 100% rename from testcases/are-we-fast-yet/List.obx rename to testcases/Are-we-fast-yet/List.obx diff --git a/testcases/are-we-fast-yet/Mandelbrot.obx b/testcases/Are-we-fast-yet/Mandelbrot.obx similarity index 100% rename from testcases/are-we-fast-yet/Mandelbrot.obx rename to testcases/Are-we-fast-yet/Mandelbrot.obx diff --git a/testcases/are-we-fast-yet/NBody.obx b/testcases/Are-we-fast-yet/NBody.obx similarity index 100% rename from testcases/are-we-fast-yet/NBody.obx rename to testcases/Are-we-fast-yet/NBody.obx diff --git a/testcases/are-we-fast-yet/ORIGINAL_README.md b/testcases/Are-we-fast-yet/ORIGINAL_README.md similarity index 100% rename from testcases/are-we-fast-yet/ORIGINAL_README.md rename to testcases/Are-we-fast-yet/ORIGINAL_README.md diff --git a/testcases/are-we-fast-yet/Permute.obx b/testcases/Are-we-fast-yet/Permute.obx similarity index 100% rename from testcases/are-we-fast-yet/Permute.obx rename to testcases/Are-we-fast-yet/Permute.obx diff --git a/testcases/are-we-fast-yet/Queens.obx b/testcases/Are-we-fast-yet/Queens.obx similarity index 100% rename from testcases/are-we-fast-yet/Queens.obx rename to testcases/Are-we-fast-yet/Queens.obx diff --git a/testcases/are-we-fast-yet/Readme.md b/testcases/Are-we-fast-yet/Readme.md similarity index 100% rename from testcases/are-we-fast-yet/Readme.md rename to testcases/Are-we-fast-yet/Readme.md diff --git a/testcases/are-we-fast-yet/Richards.obx b/testcases/Are-we-fast-yet/Richards.obx similarity index 100% rename from testcases/are-we-fast-yet/Richards.obx rename to testcases/Are-we-fast-yet/Richards.obx diff --git a/testcases/are-we-fast-yet/Run.obx b/testcases/Are-we-fast-yet/Run.obx similarity index 100% rename from testcases/are-we-fast-yet/Run.obx rename to testcases/Are-we-fast-yet/Run.obx diff --git a/testcases/are-we-fast-yet/Sieve.obx b/testcases/Are-we-fast-yet/Sieve.obx similarity index 100% rename from testcases/are-we-fast-yet/Sieve.obx rename to testcases/Are-we-fast-yet/Sieve.obx diff --git a/testcases/are-we-fast-yet/Storage.obx b/testcases/Are-we-fast-yet/Storage.obx similarity index 100% rename from testcases/are-we-fast-yet/Storage.obx rename to testcases/Are-we-fast-yet/Storage.obx diff --git a/testcases/are-we-fast-yet/Tester.obx b/testcases/Are-we-fast-yet/Tester.obx similarity index 86% rename from testcases/are-we-fast-yet/Tester.obx rename to testcases/Are-we-fast-yet/Tester.obx index 7122c87..ecdefd4 100644 --- a/testcases/are-we-fast-yet/Tester.obx +++ b/testcases/Are-we-fast-yet/Tester.obx @@ -270,28 +270,11 @@ begin // Test4() // Test5() // Test6() + RunAll() //RunEachOnce() - + //H.run("CD", 250, 2) - // CD2 250,1000 works - // CD/CD2 10,1000/ 50,100/ 50,10/ 100,10 works - // CD tends to crash with numIterations > 90 - // with DBGTRACE there is no crash in both CD as CD2! - // with ObxFfi_DBGTRACE both CD and CD2 crash in the first second - // with JIT off there is no crash in CD 250,100 - // fixed in 0.7.24, runs without crash, even before upgrade to latest LJ v2.0 commits - - // but the following crash since 0.7.24, even after upgrade to latest LJ v2.0 - // crashes in JIT, no crash if JIT off (it runs sometimes in OBXLJ with JIT on): - //H.run("Havlak", 1, 1 ) - //H.run("Towers", 1, 1) - // all others run, even with large numIterations, no crashes observed so far - // DeltaBlue, CD2, Bounce and Storage - // run but assert in rec_check_slots itype2irt(tv) == tref_type(tr), - // Bounce crashes in rec_check_slots gco2func(frame_gc(tv)) - // DeltaBlue and Storage run each other run - // Fixed in IDE 0.7.25; reason was changed order of res=buySlots in LjbcGen emitCall and visit( IdentSel*) println("End Tester") end Tester diff --git a/testcases/are-we-fast-yet/Towers.obx b/testcases/Are-we-fast-yet/Towers.obx similarity index 96% rename from testcases/are-we-fast-yet/Towers.obx rename to testcases/Are-we-fast-yet/Towers.obx index c3e4bc0..6605d6a 100644 --- a/testcases/are-we-fast-yet/Towers.obx +++ b/testcases/Are-we-fast-yet/Towers.obx @@ -78,9 +78,6 @@ module Towers proc (this: Towers) moveTopDisk(fromPile, toPile: integer) var t: TowersDisk begin - // modified to avoid unexplicable JIT crash (2021-07-11) - //t := this.popDiskFrom(fromPile) - //this.pushDisk( t, toPile) // TODO this.pushDisk( this.popDiskFrom(fromPile), toPile) inc(this.movesDone) end moveTopDisk diff --git a/testcases/are-we-fast-yet/are-we-fast-yet.obxpro b/testcases/Are-we-fast-yet/are-we-fast-yet.obxpro similarity index 100% rename from testcases/are-we-fast-yet/are-we-fast-yet.obxpro rename to testcases/Are-we-fast-yet/are-we-fast-yet.obxpro diff --git a/testcases/are-we-fast-yet/som/Dictionary.obx b/testcases/Are-we-fast-yet/som/Dictionary.obx similarity index 100% rename from testcases/are-we-fast-yet/som/Dictionary.obx rename to testcases/Are-we-fast-yet/som/Dictionary.obx diff --git a/testcases/are-we-fast-yet/som/IdentityDictionary.obx b/testcases/Are-we-fast-yet/som/IdentityDictionary.obx similarity index 100% rename from testcases/are-we-fast-yet/som/IdentityDictionary.obx rename to testcases/Are-we-fast-yet/som/IdentityDictionary.obx diff --git a/testcases/are-we-fast-yet/som/IdentitySet.obx b/testcases/Are-we-fast-yet/som/IdentitySet.obx similarity index 100% rename from testcases/are-we-fast-yet/som/IdentitySet.obx rename to testcases/Are-we-fast-yet/som/IdentitySet.obx diff --git a/testcases/are-we-fast-yet/som/Interfaces.obx b/testcases/Are-we-fast-yet/som/Interfaces.obx similarity index 100% rename from testcases/are-we-fast-yet/som/Interfaces.obx rename to testcases/Are-we-fast-yet/som/Interfaces.obx diff --git a/testcases/are-we-fast-yet/som/Pair.obx b/testcases/Are-we-fast-yet/som/Pair.obx similarity index 100% rename from testcases/are-we-fast-yet/som/Pair.obx rename to testcases/Are-we-fast-yet/som/Pair.obx diff --git a/testcases/are-we-fast-yet/som/Random.obx b/testcases/Are-we-fast-yet/som/Random.obx similarity index 100% rename from testcases/are-we-fast-yet/som/Random.obx rename to testcases/Are-we-fast-yet/som/Random.obx diff --git a/testcases/are-we-fast-yet/som/RedBlackTree.obx b/testcases/Are-we-fast-yet/som/RedBlackTree.obx similarity index 100% rename from testcases/are-we-fast-yet/som/RedBlackTree.obx rename to testcases/Are-we-fast-yet/som/RedBlackTree.obx diff --git a/testcases/are-we-fast-yet/som/Set.obx b/testcases/Are-we-fast-yet/som/Set.obx similarity index 100% rename from testcases/are-we-fast-yet/som/Set.obx rename to testcases/Are-we-fast-yet/som/Set.obx diff --git a/testcases/are-we-fast-yet/som/Vector.obx b/testcases/Are-we-fast-yet/som/Vector.obx similarity index 100% rename from testcases/are-we-fast-yet/som/Vector.obx rename to testcases/Are-we-fast-yet/som/Vector.obx diff --git a/testcases/HennessyV4.Mod b/testcases/HennessyV4.Mod deleted file mode 100644 index 737e7f6..0000000 --- a/testcases/HennessyV4.Mod +++ /dev/null @@ -1,1000 +0,0 @@ -MODULE HennessyV4; -(* This is a suite of benchmarks that are relatively short, both in program - size and execution time. It requires no input, and prints the execution - time for each program, using the system- dependent routine Getclock, - below, to find out the current CPU time. It does a rudimentary check to - make sure each program gets the right output. These programs were - gathered by John Hennessy and modified by Peter Nye. - Oberon: J.Templ 26.2.90 - - Source: https://github.com/jtempl/ofront, V4_ofront/share, commit 46f758c on 2 Jan 2020 - 2021-02-22 Rochus Keller: renamed to HennessyV4; added BEGIN main; - - *) - -IMPORT - Oberon, Out; - -CONST - bubblebase = 1.61; - dnfbase = 3.5; - permbase = 1.75; - queensbase = 1.83; - towersbase = 2.39; - quickbase = 1.92; - intmmbase = 1.46; - treebase = 2.5; - mmbase = 0.0 (* 0.73 *); - fpmmbase = 2.92; - puzzlebase = 0.5; - fftbase = 0.0 (* 1.11 *); - fpfftbase = 4.44; - - (* Towers *) - maxcells = 18; - stackrange = (*0..*) 3; - - (* Intmm, Mm *) - rowsize = 40; - - (* Puzzle *) - size = 511; - classmax = 3; - typemax = 12; - d = 8; - - (* Bubble, Quick *) - sortelements = 5000; - srtelements = 500; - - (* fft *) - fftsize = 256; - fftsize2 = 129; - - (* Perm *) - permrange = (*0 ..*)10; - (* Towers *) - -TYPE - (* tree *) - node = POINTER TO nodeDesc; - nodeDesc = RECORD - left, right: node; - val: LONGINT; - END; - - (* Towers - discsizrange = 1..maxcells; - cellcursor = 0..maxcells; *) - element = RECORD - discsize: LONGINT; - next: LONGINT; - END ; - -(* emsgtype = packed array[1..15] of char; -*) - (* Intmm, Mm *) (* - index = 1 .. rowsize; *) - intmatrix = ARRAY rowsize+1,rowsize+1 OF LONGINT; - realmatrix = ARRAY rowsize+1,rowsize+1 OF REAL; - - (* Puzzle *) (* - piececlass = 0..classmax; - piecetype = 0..typemax; - position = 0..size; -*) - (* Bubble, Quick *) (* - listsize = 0..sortelements; - sortarray = array [listsize] of integer; -*) - (* FFT *) - complex = RECORD - rp, ip: REAL - END; - carray = ARRAY fftsize+1 OF complex ; - c2array = ARRAY fftsize2+1 OF complex ; - - Proc = PROCEDURE; - -VAR - fixed,floated: REAL; - - (* global *) - seed: LONGINT; - - (* Perm *) - permarray: ARRAY permrange+1 OF LONGINT; - pctr: LONGINT; - - (* tree *) - tree: node; - - (* Towers *) - stack: ARRAY stackrange+1 OF LONGINT; - cellspace: ARRAY maxcells+1 OF element; - freelist: LONGINT; - movesdone: LONGINT; - - (* Intmm, Mm *) - ima, imb, imr: intmatrix; - rma, rmb, rmr: realmatrix; - - (* Puzzle *) - piececount: ARRAY classmax+1 OF LONGINT; - class, piecemax: ARRAY typemax+1 OF LONGINT; - puzzl: ARRAY size+1 OF BOOLEAN; - p: ARRAY typemax+1, size+1 OF BOOLEAN; - n, - kount: LONGINT; - - (* Bubble, Quick *) - sortlist: ARRAY sortelements+1 OF LONGINT; - biggest, littlest, - top: LONGINT; - - (* FFT *) - z, w: carray; - e: c2array; - zr, zi: REAL; - -(* global procedures *) - - PROCEDURE Getclock (): LONGINT; - BEGIN RETURN Oberon.Time() - END Getclock; - - PROCEDURE Initrand (); - BEGIN seed := 74755 - END Initrand; - - PROCEDURE Rand (): LONGINT; - BEGIN - seed := (seed * 1309 + 13849) MOD 65535; - RETURN (seed); - END Rand; - - - (* Permutation program, heavily recursive, written by Denny Brown. *) - - PROCEDURE Swap (VAR a,b: LONGINT); - VAR t: LONGINT; - BEGIN t := a; a := b; b := t; - END Swap; - - PROCEDURE Initialize (); - VAR i: LONGINT; - BEGIN i := 1; - WHILE i <= 7 DO - permarray[i] := i-1; - INC(i) - END - END Initialize; - - PROCEDURE Permute (n: LONGINT); - VAR k: LONGINT; - BEGIN - pctr := pctr + 1; - IF ( n#1 ) THEN - Permute(n-1); - k := n-1; - WHILE k >= 1 DO - Swap(permarray[n], permarray[k]); - Permute(n-1); - Swap(permarray[n], permarray[k]); - DEC(k) - END - END - END Permute; - - PROCEDURE *Perm (); - VAR i: LONGINT; - BEGIN - pctr := 0; i := 1; - WHILE i <= 5 DO - Initialize(); - Permute(7); - INC(i) - END ; - IF ( pctr # 43300 ) THEN Out.String(" Error in Perm."); Out.Ln END - END Perm; - - - (* Program to Solve the Towers of Hanoi *) - - PROCEDURE Makenull (s: LONGINT); - BEGIN stack[s] := 0 - END Makenull; - - PROCEDURE Getelement (): LONGINT; - VAR temp: LONGINT; - BEGIN - IF ( freelist>0 ) THEN - temp := freelist; - freelist := cellspace[freelist].next; - ELSE - Out.String("out of space "); Out.Ln - END ; - RETURN (temp); - END Getelement; - - PROCEDURE Push(i,s: LONGINT); - VAR localel: LONGINT; errorfound: BOOLEAN; - BEGIN - errorfound := FALSE; - IF ( stack[s] > 0 ) THEN - IF ( cellspace[stack[s]].discsize<=i ) THEN - errorfound := TRUE; - Out.String("disc size error"); Out.Ln - END - END ; - IF ( ~ errorfound ) THEN - localel := Getelement(); - cellspace[localel].next := stack[s]; - stack[s] := localel; - cellspace[localel].discsize := i - END - END Push; - - PROCEDURE Init (s,n: LONGINT); - VAR discctr: LONGINT; - BEGIN - Makenull(s); discctr := n; - WHILE discctr >= 1 DO - Push(discctr,s); - DEC(discctr) - END - END Init; - - PROCEDURE Pop (s: LONGINT): LONGINT; - VAR temp, temp1: LONGINT; - BEGIN - IF ( stack[s] > 0 ) THEN - temp1 := cellspace[stack[s]].discsize; - temp := cellspace[stack[s]].next; - cellspace[stack[s]].next := freelist; - freelist := stack[s]; - stack[s] := temp; - RETURN (temp1) - ELSE - Out.String("nothing to pop "); Out.Ln - END - END Pop; - - PROCEDURE Move (s1,s2: LONGINT); - BEGIN - Push(Pop(s1),s2); - movesdone := movesdone+1; - END Move; - - PROCEDURE tower(i,j,k: LONGINT); - VAR other: LONGINT; - BEGIN - IF ( k=1 ) THEN - Move(i,j); - ELSE - other := 6-i-j; - tower(i,other,k-1); - Move(i,j); - tower(other,j,k-1) - END - END tower; - - PROCEDURE *Towers (); - VAR i: LONGINT; - BEGIN i := 1; - WHILE i <= maxcells DO cellspace[i].next := i-1; INC(i) END ; - freelist := maxcells; - Init(1,14); - Makenull(2); - Makenull(3); - movesdone := 0; - tower(1,2,14); - IF ( movesdone # 16383 ) THEN Out.String(" Error in Towers."); Out.Ln END - END Towers; - - - (* The eight queens problem, solved 50 times. *) -(* - type - doubleboard = 2..16; - doublenorm = -7..7; - boardrange = 1..8; - aarray = array [boardrange] of boolean; - barray = array [doubleboard] of boolean; - carray = array [doublenorm] of boolean; - xarray = array [boardrange] of boardrange; -*) - - PROCEDURE Try(i: LONGINT; VAR q: BOOLEAN; VAR a, b, c: ARRAY OF BOOLEAN; VAR x: ARRAY OF LONGINT); - VAR j: LONGINT; - BEGIN - j := 0; - q := FALSE; - WHILE (~q) & (j # 8) DO - j := j + 1; - q := FALSE; - IF b[j] & a[i+j] & c[i-j+7] THEN - x[i] := j; - b[j] := FALSE; - a[i+j] := FALSE; - c[i-j+7] := FALSE; - IF i < 8 THEN - Try(i+1,q,a,b,c,x); - IF ~q THEN - b[j] := TRUE; - a[i+j] := TRUE; - c[i-j+7] := TRUE - END - ELSE q := TRUE - END - END - END - END Try; - - PROCEDURE Doit (); - VAR i: LONGINT; q: BOOLEAN; - a: ARRAY 9 OF BOOLEAN; - b: ARRAY 17 OF BOOLEAN; - c: ARRAY 15 OF BOOLEAN; - x: ARRAY 9 OF LONGINT; - BEGIN - i := 0 - 7; - WHILE i <= 16 DO - IF (i >= 1) & (i <= 8) THEN a[i] := TRUE END ; - IF i >= 2 THEN b[i] := TRUE END ; - IF i <= 7 THEN c[i+7] := TRUE END ; - i := i + 1; - END ; - Try(1, q, b, a, c, x); - IF ( ~ q ) THEN Out.String(" Error in Queens."); Out.Ln END - END Doit; - - PROCEDURE *Queens (); - VAR i: LONGINT; - BEGIN i := 1; - WHILE i <= 50 DO Doit(); INC(i) END - END Queens; - - - (* Multiplies two integer matrices. *) - - PROCEDURE Initmatrix (VAR m: intmatrix); - VAR temp, i, j: LONGINT; - BEGIN i := 1; - WHILE i <= rowsize DO - j := 1; - WHILE j <= rowsize DO - temp := Rand(); - m[i][j] := temp - (temp DIV 120)*120 - 60; - INC(j) - END ; - INC(i) - END - END Initmatrix; - - PROCEDURE Innerproduct(VAR result: LONGINT; VAR a,b: intmatrix; row,column: LONGINT); - VAR i: LONGINT; - (* computes the inner product of A[row,*] and B[*,column] *) - BEGIN - result := 0; i := 1; - WHILE i <= rowsize DO result := result+a[row][i]*b[i][column]; INC(i) END - END Innerproduct; - - PROCEDURE *Intmm (); - VAR i, j: LONGINT; - BEGIN - Initrand(); - Initmatrix (ima); - Initmatrix (imb); - i := 1; - WHILE i <= rowsize DO j := 1; - WHILE j <= rowsize DO Innerproduct(imr[i][j],ima,imb,i,j); INC(j) END ; - INC(i) - END - END Intmm; - - - (* Multiplies two real matrices. *) - - PROCEDURE rInitmatrix (VAR m: realmatrix); - VAR temp, i, j: LONGINT; - BEGIN i := 1; - WHILE i <= rowsize DO j := 1; - WHILE j <= rowsize DO - temp := Rand(); - m[i][j] := (temp - (temp DIV 120)*120 - 60) DIV 3; - INC(j) - END ; - INC(i) - END - END rInitmatrix; - - PROCEDURE rInnerproduct(VAR result: REAL; VAR a,b: realmatrix; row,column: LONGINT); - (* computes the inner product of A[row,*] and B[*,column] *) - VAR i: LONGINT; - BEGIN - result := 0.0; i := 1; - WHILE i<=rowsize DO result := result+a[row][i]*b[i][column]; INC(i) END - END rInnerproduct; - - PROCEDURE *Mm (); - VAR i, j: LONGINT; - BEGIN - Initrand(); - rInitmatrix (rma); - rInitmatrix (rmb); - i := 1; - WHILE i <= rowsize DO j := 1; - WHILE j <= rowsize DO rInnerproduct(rmr[i][j],rma,rmb,i,j); INC(j) END ; - INC(i) - END - END Mm; - - - (* A compute-bound program from Forest Baskett. *) - - PROCEDURE Fit (i, j: LONGINT): BOOLEAN; - VAR k: LONGINT; - BEGIN k := 0; - WHILE k <= piecemax[i] DO - IF ( p[i][k] ) THEN IF ( puzzl[j+k] ) THEN RETURN FALSE END END; - INC(k) - END; - RETURN TRUE - END Fit; - - PROCEDURE Place (i, j: LONGINT): LONGINT; - VAR k: LONGINT; - BEGIN k := 0; - WHILE k <= piecemax[i] DO - IF ( p[i][k] ) THEN puzzl[j+k] := TRUE END; - INC(k) - END; - piececount[class[i]] := piececount[class[i]] - 1; - k := j; - WHILE k <= size DO - IF ( ~ puzzl[k] ) THEN RETURN (k) END; - INC(k) - END ; - RETURN (0); - END Place; - - PROCEDURE Remove (i, j: LONGINT); - VAR k: LONGINT; - BEGIN k := 0; - WHILE k <= piecemax[i] DO - IF ( p[i][k] ) THEN puzzl[j+k] := FALSE END; - INC(k) - END; - piececount[class[i]] := piececount[class[i]] + 1 - END Remove; - - PROCEDURE Trial (j: LONGINT): BOOLEAN; - VAR i, k: LONGINT; - BEGIN i := 0; - kount := kount + 1; - WHILE i <= typemax DO - IF ( piececount[class[i]] # 0 ) THEN - IF ( Fit (i, j) ) THEN - k := Place (i, j); - IF Trial(k) OR (k = 0) THEN RETURN (TRUE) - ELSE Remove (i, j) - END; - END - END; - INC(i) - END; - RETURN (FALSE) - END Trial; - - PROCEDURE* Puzzle (); - VAR i, j, k, m: LONGINT; - BEGIN - m := 0; WHILE m <= size DO puzzl[m] := TRUE; INC(m) END ; - i := 1; - WHILE i <= 5 DO j := 1; - WHILE j <= 5 DO k := 1; - WHILE k <= 5 DO - puzzl[i+d*(j+d*k)] := FALSE; INC(k) - END; - INC(j) - END; - INC(i) - END; - - i := 0; - WHILE i <= typemax DO m := 0; - WHILE m<= size DO - p[i][m] := FALSE; INC(m) - END; - INC(i) - END; - - i := 0; - WHILE i <= 3 DO j := 0; - WHILE j <= 1 DO k := 0; - WHILE k <= 0 DO - p[0][i+d*(j+d*k)] := TRUE; INC(k) - END; - INC(j) - END; - INC(i) - END; - class[0] := 0; - piecemax[0] := 3+d*1+d*d*0; - - i := 0; - WHILE i <= 1 DO j := 0; - WHILE j <= 0 DO k := 0; - WHILE k <= 3 DO - p[1][i+d*(j+d*k)] := TRUE; INC(k) - END; - INC(j) - END; - INC(i) - END; - class[1] := 0; - piecemax[1] := 1+d*0+d*d*3; - - i := 0; - WHILE i <= 0 DO j := 0; - WHILE j <= 3 DO k := 0; - WHILE k <= 1 DO - p[2][i+d*(j+d*k)] := TRUE; INC(k) - END; - INC(j) - END; - INC(i) - END; - class[2] := 0; - piecemax[2] := 0+d*3+d*d*1; - - i := 0; - WHILE i <= 1 DO j := 0; - WHILE j <= 3 DO k := 0; - WHILE k <= 0 DO - p[3][i+d*(j+d*k)] := TRUE; INC(k) - END; - INC(j) - END; - INC(i) - END; - class[3] := 0; - piecemax[3] := 1+d*3+d*d*0; - - i := 0; - WHILE i <= 3 DO j := 0; - WHILE j <= 0 DO k := 0; - WHILE k <= 1 DO - p[4][i+d*(j+d*k)] := TRUE; INC(k) - END; - INC(j) - END; - INC(i) - END; - class[4] := 0; - piecemax[4] := 3+d*0+d*d*1; - - i := 0; - WHILE i <= 0 DO j := 0; - WHILE j <= 1 DO k := 0; - WHILE k <= 3 DO - p[5][i+d*(j+d*k)] := TRUE; INC(k) - END; - INC(j) - END; - INC(i) - END; - class[5] := 0; - piecemax[5] := 0+d*1+d*d*3; - - i := 0; - WHILE i <= 2 DO j := 0; - WHILE j <= 0 DO k := 0; - WHILE k <= 0 DO - p[6][i+d*(j+d*k)] := TRUE; INC(k) - END; - INC(j) - END; - INC(i) - END; - class[6] := 1; - piecemax[6] := 2+d*0+d*d*0; - - i := 0; - WHILE i <= 0 DO j := 0; - WHILE j <= 2 DO k := 0; - WHILE k <= 0 DO - p[7][i+d*(j+d*k)] := TRUE; INC(k) - END; - INC(j) - END; - INC(i) - END; - class[7] := 1; - piecemax[7] := 0+d*2+d*d*0; - - i := 0; - WHILE i <= 0 DO j := 0; - WHILE j <= 0 DO k := 0; - WHILE k <= 2 DO - p[8][i+d*(j+d*k)] := TRUE; INC(k) - END; - INC(j) - END; - INC(i) - END; - class[8] := 1; - piecemax[8] := 0+d*0+d*d*2; - - i := 0; - WHILE i <= 1 DO j := 0; - WHILE j <= 1 DO k := 0; - WHILE k <= 0 DO - p[9][i+d*(j+d*k)] := TRUE; INC(k) - END; - INC(j) - END; - INC(i) - END; - class[9] := 2; - piecemax[9] := 1+d*1+d*d*0; - - i := 0; - WHILE i <= 1 DO j := 0; - WHILE j <= 0 DO k := 0; - WHILE k <= 1 DO - p[10][i+d*(j+d*k)] := TRUE; INC(k) - END; - INC(j) - END; - INC(i) - END; - class[10] := 2; - piecemax[10] := 1+d*0+d*d*1; - - i := 0; - WHILE i <= 0 DO j := 0; - WHILE j <= 1 DO k := 0; - WHILE k <= 1 DO - p[11][i+d*(j+d*k)] := TRUE; INC(k) - END; - INC(j) - END; - INC(i) - END; - class[11] := 2; - piecemax[11] := 0+d*1+d*d*1; - - i := 0; - WHILE i <= 1 DO j := 0; - WHILE j <= 1 DO k := 0; - WHILE k <= 1 DO - p[12][i+d*(j+d*k)] := TRUE; INC(k) - END; - INC(j) - END; - INC(i) - END; - class[12] := 3; - piecemax[12] := 1+d*1+d*d*1; - - piececount[0] := 13; - piececount[1] := 3; - piececount[2] := 1; - piececount[3] := 1; - m := 1+d*(1+d*1); - kount := 0; - IF Fit(0, m) THEN n := Place(0, m) - ELSE Out.String("Error1 in Puzzle"); Out.Ln - END; - IF ~ Trial(n) THEN Out.String("Error2 in Puzzle."); Out.Ln - ELSIF kount # 2005 THEN Out.String("Error3 in Puzzle."); Out.Ln - END - END Puzzle; - - - (* Sorts an array using quicksort *) - - PROCEDURE Initarr(); - VAR i, temp: LONGINT; - BEGIN - Initrand(); - biggest := 0; littlest := 0; i := 1; - WHILE i <= sortelements DO - temp := Rand(); - sortlist[i] := temp - (temp DIV 100000)*100000 - 50000; - IF sortlist[i] > biggest THEN biggest := sortlist[i] - ELSIF sortlist[i] < littlest THEN littlest := sortlist[i] - END ; - INC(i) - END - END Initarr; - - PROCEDURE Quicksort(VAR a: ARRAY OF LONGINT; l,r: LONGINT); - (* quicksort the array A from start to finish *) - VAR i,j,x,w: LONGINT; - BEGIN - i:=l; j:=r; - x:=a[(l+r) DIV 2]; - REPEAT - WHILE a[i] j; - IF l biggest THEN biggest := sortlist[i] - ELSIF sortlist[i] < littlest THEN littlest := sortlist[i] - END ; - INC(i) - END - END bInitarr; - - PROCEDURE* Bubble(); - VAR i, j: LONGINT; - BEGIN - bInitarr(); - top:=srtelements; - WHILE top>1 DO - i:=1; - WHILE i sortlist[i+1] THEN - j := sortlist[i]; - sortlist[i] := sortlist[i+1]; - sortlist[i+1] := j; - END ; - i:=i+1; - END; - top:=top-1; - END; - IF (sortlist[1] # littlest) OR (sortlist[srtelements] # biggest) THEN Out.String("Error3 in Bubble."); Out.Ln END ; - END Bubble; - - - (* Sorts an array using treesort *) - - PROCEDURE tInitarr(); - VAR i, temp: LONGINT; - BEGIN - Initrand(); - biggest := 0; littlest := 0; i := 1; - WHILE i <= sortelements DO - temp := Rand(); - sortlist[i] := temp - (temp DIV 100000)*100000 - 50000; - IF sortlist[i] > biggest THEN biggest := sortlist[i] - ELSIF sortlist[i] < littlest THEN littlest := sortlist[i] - END ; - INC(i) - END - END tInitarr; - - PROCEDURE CreateNode (VAR t: node; n: LONGINT); - BEGIN - NEW(t); - t.left := NIL; t.right := NIL; - t.val := n - END CreateNode; - - - PROCEDURE Insert(n: LONGINT; t: node); - (* insert n into tree *) - BEGIN - IF n > t.val THEN - IF t.left = NIL THEN CreateNode(t.left,n) - ELSE Insert(n,t.left) - END - ELSIF n < t.val THEN - IF t.right = NIL THEN CreateNode(t.right,n) - ELSE Insert(n,t.right) - END - END - END Insert; - - PROCEDURE Checktree(p: node): BOOLEAN; - (* check by inorder traversal *) - VAR result: BOOLEAN; - BEGIN - result := TRUE; - IF p.left # NIL THEN - IF p.left.val <= p.val THEN result := FALSE; - ELSE result := Checktree(p.left) & result - END - END ; - IF p.right # NIL THEN - IF p.right.val >= p.val THEN result := FALSE; - ELSE result := Checktree(p.right) & result - END - END; - RETURN result - END Checktree; - - PROCEDURE* Trees(); - VAR i: LONGINT; - BEGIN - tInitarr(); - NEW(tree); - tree.left := NIL; tree.right:=NIL; tree.val:=sortlist[1]; - i := 2; - WHILE i <= sortelements DO - Insert(sortlist[i],tree); - INC(i) - END; - IF ~ Checktree(tree) THEN Out.String(" Error in Tree."); Out.Ln END; - END Trees; - - PROCEDURE Cos (x: REAL): REAL; - (* computes cos of x (x in radians) by an expansion *) - VAR i, factor: LONGINT; - result,power: REAL; - BEGIN - result := 1.0; factor := 1; power := x; i := 2; - WHILE i <= 10 DO - factor := factor * i; power := power*x; - IF i MOD 2 = 0 THEN - IF i MOD 4 = 0 THEN result := result + power/factor - ELSE result := result - power/factor - END - END; - INC(i) - END ; - RETURN result - END Cos; - - PROCEDURE Min0( arg1, arg2: LONGINT): LONGINT; - BEGIN - IF arg1 < arg2 THEN RETURN arg1 - ELSE RETURN arg2 - END - END Min0; - - PROCEDURE Uniform11(iy: LONGINT; yfl: REAL); - BEGIN - iy := (4855*iy + 1731) MOD 8192; - yfl := iy/8192.0; - END Uniform11; - - PROCEDURE Exptab(n: LONGINT; VAR e: c2array); - VAR theta, divisor: REAL; h: ARRAY 26 OF REAL; - i, j, k, l, m: LONGINT; - BEGIN - theta := 3.1415926536; - divisor := 4.0; i:=1; - WHILE i <= 25 DO - h[i] := 1/(2*Cos( theta/divisor )); - divisor := divisor + divisor; - INC(i) - END; - m := n DIV 2 ; - l := m DIV 2 ; - j := 1 ; - e[1].rp := 1.0 ; - e[1].ip := 0.0; - e[l+1].rp := 0.0; - e[l+1].ip := 1.0 ; - e[m+1].rp := -1.0 ; - e[m+1].ip := 0.0 ; - REPEAT - i := l DIV 2 ; - k := i ; - REPEAT - e[k+1].rp := h[j]*(e[k+i+1].rp+e[k-i+1].rp) ; - e[k+1].ip := h[j]*(e[k+i+1].ip+e[k-i+1].ip) ; - k := k+l ; - UNTIL ( k > m ); - j := Min0( j+1, 25); - l := i ; - UNTIL ( l <= 1 ); - END Exptab; - - PROCEDURE Fft( n: LONGINT; VAR z, w: carray; VAR e: c2array; sqrinv: REAL); - VAR i, j, k, l, m, index: LONGINT; h: REAL; - BEGIN - m := n DIV 2 ; - l := 1 ; - REPEAT - k := 0 ; - j := l ; - i := 1 ; - REPEAT - REPEAT - w[i+k].rp := z[i].rp+z[m+i].rp ; - w[i+k].ip := z[i].ip+z[m+i].ip ; - h := e[k+1].rp*(z[i].rp-z[i+m].rp); - w[i+j].rp := h-e[k+1].ip*(z[i].ip-z[i+m].ip) ; - h := e[k+1].rp*(z[i].ip-z[i+m].ip); - w[i+j].ip := h+e[k+1].ip*(z[i].rp-z[i+m].rp) ; - i := i+1 ; - UNTIL ( i > j ); - k := j ; - j := k+l ; - UNTIL ( j > m ); - (*z := w ;*) index := 1; - REPEAT - z[index] := w[index]; - index := index+1; - UNTIL ( index > n ); - l := l+l ; - UNTIL ( l > m ); - i := 1; - WHILE i <= n DO - z[i].rp := sqrinv*z[i].rp ; - z[i].ip := -sqrinv*z[i].ip; - INC(i) - END - END Fft; - - PROCEDURE* Oscar (); - VAR i: LONGINT; - BEGIN - Exptab(fftsize,e) ; - seed := 5767 ; i := 1; - WHILE i <= fftsize DO - Uniform11( seed, zr ); - Uniform11( seed, zi ); - z[i].rp := 20.0*zr - 10.0; - z[i].ip := 20.0*zi - 10.0; - INC(i) - END ; - i := 1; - WHILE i <= 20 DO Fft(fftsize,z,w,e,0.0625); INC(i) END - END Oscar; - - PROCEDURE Time(s: ARRAY OF CHAR; p: Proc; base, fbase: REAL); - VAR timer, iter: LONGINT; - BEGIN - Out.String(s); - timer := Getclock(); - iter := 10; WHILE iter > 0 DO p; DEC(iter) END ; - timer := (Getclock()-timer+5) DIV 10; - Out.Int(timer, 8); Out.Ln; - fixed := fixed + timer*base; - floated := floated + timer*fbase - END Time; - - PROCEDURE main*; - BEGIN - fixed := 0.0; floated := 0.0; - Time("Perm ", Perm, permbase, permbase); - Time("Towers ", Towers, towersbase, towersbase); - Time("Queens ", Queens, queensbase, queensbase); - Time("Intmm ", Intmm, intmmbase, intmmbase); - Time("Mm ", Mm, mmbase, fpmmbase); - Time("Puzzle ", Puzzle, puzzlebase, puzzlebase); - Time("Quick ", Quick, quickbase, quickbase); - Time("Bubble ", Bubble, bubblebase, bubblebase); - Time("Tree ", Trees, treebase, treebase); - Time("FFT ", Oscar, fftbase, fpfftbase); - Out.String("Nonfloating point composite is "); Out.Int(ENTIER(fixed/10+0.5), 10); Out.Ln; - Out.String("Floating point composite is "); Out.Int(ENTIER(floated/10+0.5), 10); Out.Ln; - - END main; -BEGIN - main; -END HennessyV4. - diff --git a/testcases/HennessyV4.obxpro b/testcases/HennessyV4.obxpro deleted file mode 100644 index d508b30..0000000 --- a/testcases/HennessyV4.obxpro +++ /dev/null @@ -1,10 +0,0 @@ -[General] -BuiltInOakwood=true -MainModule=@ByteArray() -MainProc=@ByteArray() -Suffixes=.Mod, .obn, .obx - -[Modules] -1\AbsPath=/home/me/Entwicklung/Modules/Oberon/testcases/HennessyV4.Mod -1\RelPath=HennessyV4.Mod -size=1 diff --git a/testcases/OBX/All.obxpro b/testcases/ObxTests/All.obxpro similarity index 100% rename from testcases/OBX/All.obxpro rename to testcases/ObxTests/All.obxpro diff --git a/testcases/OBX/Arrays.obx b/testcases/ObxTests/Arrays.obx similarity index 100% rename from testcases/OBX/Arrays.obx rename to testcases/ObxTests/Arrays.obx diff --git a/testcases/OBX/Arrays2.obx b/testcases/ObxTests/Arrays2.obx similarity index 100% rename from testcases/OBX/Arrays2.obx rename to testcases/ObxTests/Arrays2.obx diff --git a/testcases/OBX/Arrays3.obx b/testcases/ObxTests/Arrays3.obx similarity index 100% rename from testcases/OBX/Arrays3.obx rename to testcases/ObxTests/Arrays3.obx diff --git a/testcases/OBX/Arrays4.obx b/testcases/ObxTests/Arrays4.obx similarity index 100% rename from testcases/OBX/Arrays4.obx rename to testcases/ObxTests/Arrays4.obx diff --git a/testcases/OBX/Enum1.obx b/testcases/ObxTests/Enum1.obx similarity index 100% rename from testcases/OBX/Enum1.obx rename to testcases/ObxTests/Enum1.obx diff --git a/testcases/OBX/Fibonacci.obx b/testcases/ObxTests/Fibonacci.obx similarity index 100% rename from testcases/OBX/Fibonacci.obx rename to testcases/ObxTests/Fibonacci.obx diff --git a/testcases/OBX/Flow.obx b/testcases/ObxTests/Flow.obx similarity index 100% rename from testcases/OBX/Flow.obx rename to testcases/ObxTests/Flow.obx diff --git a/testcases/OBX/Generic1.obx b/testcases/ObxTests/Generic1.obx similarity index 100% rename from testcases/OBX/Generic1.obx rename to testcases/ObxTests/Generic1.obx diff --git a/testcases/OBX/Generic2.obx b/testcases/ObxTests/Generic2.obx similarity index 100% rename from testcases/OBX/Generic2.obx rename to testcases/ObxTests/Generic2.obx diff --git a/testcases/OBX/Generic3.obx b/testcases/ObxTests/Generic3.obx similarity index 100% rename from testcases/OBX/Generic3.obx rename to testcases/ObxTests/Generic3.obx diff --git a/testcases/OBX/Generic4.obx b/testcases/ObxTests/Generic4.obx similarity index 100% rename from testcases/OBX/Generic4.obx rename to testcases/ObxTests/Generic4.obx diff --git a/testcases/OBX/GenericTest1.obx b/testcases/ObxTests/GenericTest1.obx similarity index 100% rename from testcases/OBX/GenericTest1.obx rename to testcases/ObxTests/GenericTest1.obx diff --git a/testcases/OBX/GenericTest2.obx b/testcases/ObxTests/GenericTest2.obx similarity index 100% rename from testcases/OBX/GenericTest2.obx rename to testcases/ObxTests/GenericTest2.obx diff --git a/testcases/OBX/GenericTest3.obx b/testcases/ObxTests/GenericTest3.obx similarity index 100% rename from testcases/OBX/GenericTest3.obx rename to testcases/ObxTests/GenericTest3.obx diff --git a/testcases/OBX/GenericTest4.obx b/testcases/ObxTests/GenericTest4.obx similarity index 100% rename from testcases/OBX/GenericTest4.obx rename to testcases/ObxTests/GenericTest4.obx diff --git a/testcases/OBX/GenericTest5.obx b/testcases/ObxTests/GenericTest5.obx similarity index 100% rename from testcases/OBX/GenericTest5.obx rename to testcases/ObxTests/GenericTest5.obx diff --git a/testcases/OBX/Havlak.obx b/testcases/ObxTests/Havlak.obx similarity index 100% rename from testcases/OBX/Havlak.obx rename to testcases/ObxTests/Havlak.obx diff --git a/testcases/OBX/Hello.obx b/testcases/ObxTests/Hello.obx similarity index 100% rename from testcases/OBX/Hello.obx rename to testcases/ObxTests/Hello.obx diff --git a/testcases/OBX/Import1.obx b/testcases/ObxTests/Import1.obx similarity index 100% rename from testcases/OBX/Import1.obx rename to testcases/ObxTests/Import1.obx diff --git a/testcases/OBX/Import2.obx b/testcases/ObxTests/Import2.obx similarity index 100% rename from testcases/OBX/Import2.obx rename to testcases/ObxTests/Import2.obx diff --git a/testcases/OBX/Imported1a.obx b/testcases/ObxTests/Imported1a.obx similarity index 100% rename from testcases/OBX/Imported1a.obx rename to testcases/ObxTests/Imported1a.obx diff --git a/testcases/OBX/Imported1b.obx b/testcases/ObxTests/Imported1b.obx similarity index 100% rename from testcases/OBX/Imported1b.obx rename to testcases/ObxTests/Imported1b.obx diff --git a/testcases/OBX/Imported2a.obx b/testcases/ObxTests/Imported2a.obx similarity index 100% rename from testcases/OBX/Imported2a.obx rename to testcases/ObxTests/Imported2a.obx diff --git a/testcases/OBX/Imported2b.obx b/testcases/ObxTests/Imported2b.obx similarity index 100% rename from testcases/OBX/Imported2b.obx rename to testcases/ObxTests/Imported2b.obx diff --git a/testcases/OBX/Loops.obx b/testcases/ObxTests/Loops.obx similarity index 100% rename from testcases/OBX/Loops.obx rename to testcases/ObxTests/Loops.obx diff --git a/testcases/OBX/Loops2.obx b/testcases/ObxTests/Loops2.obx similarity index 100% rename from testcases/OBX/Loops2.obx rename to testcases/ObxTests/Loops2.obx diff --git a/testcases/OBX/Minimal.obx b/testcases/ObxTests/Minimal.obx similarity index 100% rename from testcases/OBX/Minimal.obx rename to testcases/ObxTests/Minimal.obx diff --git a/testcases/OBX/Proc10.obx b/testcases/ObxTests/Proc10.obx similarity index 100% rename from testcases/OBX/Proc10.obx rename to testcases/ObxTests/Proc10.obx diff --git a/testcases/OBX/ProcType1.obx b/testcases/ObxTests/ProcType1.obx similarity index 100% rename from testcases/OBX/ProcType1.obx rename to testcases/ObxTests/ProcType1.obx diff --git a/testcases/OBX/Procs1.obx b/testcases/ObxTests/Procs1.obx similarity index 100% rename from testcases/OBX/Procs1.obx rename to testcases/ObxTests/Procs1.obx diff --git a/testcases/OBX/Procs2.obx b/testcases/ObxTests/Procs2.obx similarity index 100% rename from testcases/OBX/Procs2.obx rename to testcases/ObxTests/Procs2.obx diff --git a/testcases/OBX/Procs3.obx b/testcases/ObxTests/Procs3.obx similarity index 100% rename from testcases/OBX/Procs3.obx rename to testcases/ObxTests/Procs3.obx diff --git a/testcases/OBX/Procs4.obx b/testcases/ObxTests/Procs4.obx similarity index 100% rename from testcases/OBX/Procs4.obx rename to testcases/ObxTests/Procs4.obx diff --git a/testcases/OBX/Procs5.obx b/testcases/ObxTests/Procs5.obx similarity index 100% rename from testcases/OBX/Procs5.obx rename to testcases/ObxTests/Procs5.obx diff --git a/testcases/OBX/Procs6.obx b/testcases/ObxTests/Procs6.obx similarity index 100% rename from testcases/OBX/Procs6.obx rename to testcases/ObxTests/Procs6.obx diff --git a/testcases/OBX/Procs7.obx b/testcases/ObxTests/Procs7.obx similarity index 100% rename from testcases/OBX/Procs7.obx rename to testcases/ObxTests/Procs7.obx diff --git a/testcases/OBX/Procs8.obx b/testcases/ObxTests/Procs8.obx similarity index 100% rename from testcases/OBX/Procs8.obx rename to testcases/ObxTests/Procs8.obx diff --git a/testcases/OBX/Procs9.obx b/testcases/ObxTests/Procs9.obx similarity index 100% rename from testcases/OBX/Procs9.obx rename to testcases/ObxTests/Procs9.obx diff --git a/testcases/OBX/Tests.obxpro b/testcases/ObxTests/Tests.obxpro similarity index 100% rename from testcases/OBX/Tests.obxpro rename to testcases/ObxTests/Tests.obxpro diff --git a/testcases/OBX/Towers.obx b/testcases/ObxTests/Towers.obx similarity index 100% rename from testcases/OBX/Towers.obx rename to testcases/ObxTests/Towers.obx diff --git a/testcases/OBX/TryToAssertJit.obx b/testcases/ObxTests/TryToAssertJit.obx similarity index 100% rename from testcases/OBX/TryToAssertJit.obx rename to testcases/ObxTests/TryToAssertJit.obx diff --git a/testcases/T1ConstantDeclarations.obn b/testcases/T1ConstantDeclarations.obn deleted file mode 100644 index 1f60938..0000000 --- a/testcases/T1ConstantDeclarations.obn +++ /dev/null @@ -1,67 +0,0 @@ -(*Copyright (C) 2017, 2018, 2019 Karl Landstrom - modifications by me@rochus-keller.ch, Oct. 2019 - -This file is part of OBNC. - -OBNC is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -OBNC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with OBNC. If not, see .*) - -MODULE T1ConstantDeclarations; - - CONST - (* null = NIL; rochus *) - valid = FALSE; - singleCharStr = "x"; - lineFeed = 0AX; - quotes = 22X; - backslash = "\"; - nonAscii = 80X; - (* letterA = CHR(ORD("A")); rochus *) - sevenDigits = "1234567"; - count = 37; - pi = 3.14; - (*inf = 1.0E+1000;*) - (*nan = 0.0 / 0.0;*) - lastDigits = {0, 2 .. 3, 5}; - - VAR - p: PROCEDURE; - b: BOOLEAN; - ch: CHAR; - s: ARRAY 8 OF CHAR; - i: INTEGER; - x: REAL; - j: BYTE; - A: SET; - -BEGIN - (* p := null; rochus *) - b := valid; - ch := singleCharStr; - ch := lineFeed; - ch := quotes; - ch := backslash; - ch := nonAscii; - (* ch := letterA; rochus *) - s := singleCharStr; - s := lineFeed; - s := quotes; - s := backslash; - s := sevenDigits; - i := count; - j := count; - x := pi; - (*x := inf;*) - (*x := nan;*) - A := lastDigits -END T1ConstantDeclarations. diff --git a/testcases/T2TypeDeclarations.obn b/testcases/T2TypeDeclarations.obn deleted file mode 100644 index 1b36259..0000000 --- a/testcases/T2TypeDeclarations.obn +++ /dev/null @@ -1,142 +0,0 @@ -(*Copyright (C) 2017, 2018, 2019 Karl Landstrom - modifications by me@rochus-keller.ch, Oct. 2019 - -This file is part of OBNC. - -OBNC is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -OBNC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with OBNC. If not, see .*) - -MODULE T2TypeDeclarations; - - CONST left = 0; - - TYPE - String = ARRAY 32 OF CHAR; - StringAlias = String; - - ProcTable = ARRAY 1 OF PROCEDURE; - - ElementDesc = RECORD END; - Element = POINTER TO ElementDesc; (* rochus modified, original Element *) - - Tree = POINTER TO RECORD - content: Element; - proc: PROCEDURE (t: Tree; VAR t1: Tree): Tree; - n: POINTER TO Node; - left, right: Tree - END; - - IntegerNode = POINTER TO RECORD (ElementDesc) (* rochus modified, original Element *) - value: INTEGER - END; - - List = POINTER TO Node; - List1 = POINTER TO Node; - Node = RECORD - elem: INTEGER; - next: List; - next1: POINTER TO Node; - next2: List1; - p: PROCEDURE (n: Node; VAR n1: Node) - END; - - ArrayRecPtr = POINTER TO RECORD - f: ARRAY 10 OF ArrayRecPtr; - g: RECORD - f: ArrayRecPtr - END - END; - - ProcRecArray = ARRAY 10 OF RECORD - f: PROCEDURE (x: ArrayRecPtr): INTEGER - END; - - T = RECORD i: INTEGER END; - - VAR - s: String; - s1: StringAlias; - table: ProcTable; - t: Tree; - e: Element; - i: IntegerNode; - n: Node; - p: ArrayRecPtr; - a: ProcRecArray; - - PROCEDURE TestMemoryAllocation; - TYPE - Ta0 = RECORD - ptr: POINTER TO RECORD END - END; - Tb0 = RECORD - proc: PROCEDURE - END; - Ta1 = RECORD (Ta0) END; - Tb1 = RECORD (Tb0) END; - - VAR - x: POINTER TO Ta1; - y: POINTER TO Tb1; - z: POINTER TO RECORD - ptr: POINTER TO RECORD END; - proc: PROCEDURE - END; - BEGIN - NEW(x); - ASSERT(x.ptr = NIL); - NEW(y); - ASSERT(y.proc = NIL); - NEW(z); - ASSERT(z.ptr = NIL); - ASSERT(z.proc = NIL) - END TestMemoryAllocation; - - - PROCEDURE TreeProc(t: Tree; VAR t1: Tree): Tree; - RETURN NIL - END TreeProc; - - - PROCEDURE NodeProc(n: Node; VAR n1: Node); - END NodeProc; - - - PROCEDURE TestScope; - TYPE P = POINTER TO T; - T = RECORD f: INTEGER END; - VAR x: P; - y: T; - BEGIN - NEW(x); - x.f := 1; (* modified by rochus *) - y.f := 1 - END TestScope; - -BEGIN - TestMemoryAllocation; - s1 := s; - table[0] := NIL; - NEW(t); - NEW(i); - t.content := i; - t.content(IntegerNode).value := 1; - t.proc := TreeProc; - NEW(e); - n.elem := left; - n.next := NIL; - n.p := NodeProc; - NEW(p); - a[0].f := NIL; - TestScope -END T2TypeDeclarations. diff --git a/testcases/T3VariableDeclarations.obn b/testcases/T3VariableDeclarations.obn deleted file mode 100644 index 7522b7c..0000000 --- a/testcases/T3VariableDeclarations.obn +++ /dev/null @@ -1,60 +0,0 @@ -(*Copyright (C) 2017, 2018, 2019 Karl Landstrom - -This file is part of OBNC. - -OBNC is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -OBNC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with OBNC. If not, see .*) - -MODULE T3VariableDeclarations; - - TYPE - Vector = RECORD - x, y: REAL - END; - - ShapeDesc = RECORD - pos: Vector - END; - - Rectangle = POINTER TO RectangleDesc; - RectangleDesc = RECORD (ShapeDesc) - size: Vector - END; - - PROCEDURE TestInitialization; - VAR s: ShapeDesc; - r: RectangleDesc; - rs: ARRAY 10 OF RectangleDesc; - rp: Rectangle; - - PROCEDURE AssertVector(VAR v: Vector); - BEGIN - ASSERT(v IS Vector) - END AssertVector; - - BEGIN - AssertVector(s.pos); - AssertVector(r.pos); - AssertVector(r.size); - AssertVector(rs[0].pos); - AssertVector(rs[0].size); - - NEW(rp); - ASSERT(rp IS Rectangle); - AssertVector(rp.pos); - AssertVector(rp.size); - END TestInitialization; - -BEGIN - TestInitialization -END T3VariableDeclarations. diff --git a/testcases/T4Expressions.obn b/testcases/T4Expressions.obn deleted file mode 100644 index 2a371e0..0000000 --- a/testcases/T4Expressions.obn +++ /dev/null @@ -1,493 +0,0 @@ -(*Copyright (C) 2017, 2018, 2019 Karl Landstrom - modifications by me@rochus-keller.ch, Oct. 2019 - -This file is part of OBNC. - -OBNC is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -OBNC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with OBNC. If not, see .*) - -MODULE T4Expressions; - - PROCEDURE IncReturnZero(VAR x: INTEGER): INTEGER; - BEGIN - INC(x) - RETURN 0 - END IncReturnZero; - - - PROCEDURE IncReturnEmpty(VAR x: INTEGER): SET; - BEGIN - INC(x) - RETURN {} - END IncReturnEmpty; - - - PROCEDURE TestDesignators; - VAR s: ARRAY 32 OF CHAR; - A: ARRAY 3, 4 OF INTEGER; - i, j: INTEGER; - a: ARRAY 10 OF POINTER TO RECORD - a: ARRAY 10 OF INTEGER; - f: PROCEDURE (): INTEGER - END; - - PROCEDURE F(): INTEGER; - RETURN 1 - END F; - - BEGIN - s := "hello"; - ASSERT(s[1] = "e"); - - A[1, 2] := 1; - ASSERT(A[1, 2] = A[1][2]); - i := 0; - j := 0; - A[0,0] := 0; (* rochus *) - A[0, 0] := ABS(A[IncReturnZero(i), IncReturnZero(j)]); - ASSERT(i = 1); - ASSERT(j = 1); - - NEW(a[0]); - a[0].a[0] := 1; - ASSERT(a[0].a[0] = 1); - a[0]^.f := F; - ASSERT(a[0].f() = 1); - END TestDesignators; - - - PROCEDURE TestSetConstructors; - VAR - a, b, i, j: INTEGER; - A: SET; - BEGIN - a := 4; - b := 6; - ASSERT({1, 2, a, 5, b, 8} = {1, 2, a..b, 8}); - i := 0; - j := 0; - A := {IncReturnZero(i)..IncReturnZero(j)}; - ASSERT(A = {0}); - ASSERT(i = 1); - ASSERT(j = 1) - END TestSetConstructors; - - - PROCEDURE TestRelationalOperations; - TYPE - TDesc = RECORD END; - T = POINTER TO TDesc; - T1 = POINTER TO RECORD (TDesc) END; (* modified by rochus, orig T, no TDesc *) - - VAR b, b1: BOOLEAN; - ch, ch1: CHAR; - i, j, n: INTEGER; - x: REAL; - y: BYTE; - A, B: SET; - str: ARRAY 24 OF CHAR; - strs: ARRAY 2, 32 OF CHAR; - t: T; - t1: T1; - BEGIN - (*booleans*) - ASSERT(TRUE = TRUE); - ASSERT(TRUE # FALSE); - b := TRUE; - b1 := FALSE; - ASSERT(b = TRUE); - ASSERT(b1 # TRUE); - - (*characters / single-character strings*) - ch := 0X; - ch1 := "a"; - ASSERT(ch = 0X); - ASSERT(ch # "a"); - ASSERT(ch < ch1); - ASSERT(ch <= 0X); - ASSERT(ch <= "a"); - ASSERT(ch1 > ch); - (*ASSERT(ch >= 0X);*) - ASSERT("a" >= ch); - ch := 7FX; - ch1 := 80X; - ASSERT(ch < ch1); - - (*integers*) - ASSERT(0 = 0); - ASSERT(0 # 1); - ASSERT(0 < 1); - ASSERT(0 <= 0); - ASSERT(0 <= 1); - ASSERT(1 > 0); - ASSERT(0 >= 0); - ASSERT(1 >= 0); - ASSERT(0 IN {0}); - ASSERT(~(1 IN {0})); - n := 0; - ASSERT(n = 0); - ASSERT(n # 1); - ASSERT(n < 1); - ASSERT(n <= 0); - ASSERT(n <= 1); - ASSERT(n < 1); - ASSERT(n >= 0); - ASSERT(n >= -1); - ASSERT(n IN {0}); - ASSERT(~(1 IN {n})); - i := 0; - j := 0; - b := IncReturnZero(i) IN IncReturnEmpty(j); - ASSERT(i = 1); - ASSERT(j = 1); - - (*real numbers*) - ASSERT(0.0 = 0.0); - ASSERT(0.0 # 1.0); - ASSERT(0.0 < 1.0); - ASSERT(0.0 <= 0.0); - ASSERT(0.0 <= 1.0); - ASSERT(1.0 > 0.0); - ASSERT(0.0 >= 0.0); - ASSERT(1.0 >= 0.0); - x := 0.0; - ASSERT(x = 0.0); - ASSERT(x # 1.0); - ASSERT(x < 1.0); - ASSERT(x <= 0.0); - ASSERT(x <= 1.0); - ASSERT(1.0 > x); - ASSERT(x >= 0.0); - ASSERT(x >= -1.0); - - (*bytes*) - y := 0; - ASSERT(y = 0); - ASSERT(y < 1); - ASSERT(y <= 0); - ASSERT(y <= 1); - ASSERT(1 > y); - (*ASSERT(y >= 0);*) - ASSERT(y IN {0}); - ASSERT(~(1 IN {y})); - - (*sets*) - ASSERT({0, 1} = {1, 0}); - ASSERT({0} # {0, 1}); - ASSERT({1 .. 0} = {}); - n := 1; - ASSERT({n .. 0} = {}); - A := {0}; - B := {0, 1}; - ASSERT(A = {0}); - ASSERT(B # {0}); - ASSERT(A # B); - - (*strings / characters / character arrays*) - ASSERT("foo" = "foo"); - ASSERT("foo" # "bar"); - ASSERT("bar" < "foo"); - ASSERT("foo" <= "foo"); - ASSERT("bar" <= "foo"); - ASSERT("foo" > "bar"); - ASSERT("foo" >= "foo"); - ASSERT("foo" >= "bar"); - ch := "b"; - ASSERT("b" = ch); - ASSERT("f" # ch); - ASSERT(ch < "c"); - ASSERT("b" <= ch); - ASSERT("a" <= ch); - ASSERT("c" > ch); - ASSERT("b" >= ch); - ASSERT("c" >= ch); - str := "foo"; - ASSERT(str="foo"); - ASSERT("fool" # str); - ASSERT("fo" # str); - ASSERT("bar" # str); - ASSERT("bar" < str); - ASSERT("fo" < str); - ASSERT("foo" <= str); - ASSERT("bar" <= str); - ASSERT("qux" > str); - ASSERT("foo" >= str); - ASSERT("qux" >= str); - strs[0] := ""; - strs[1] := "bar"; - ASSERT(~(str = strs[1])); - ASSERT(str # strs[1]); - ASSERT(~(str < strs[1])); - ASSERT(~(str <= strs[1])); - ASSERT(str > strs[1]); - ASSERT(str >= strs[1]); - str[0] := 7FX; str[1] := 0X; - strs[1][0] := 80X; strs[1][1] := 0X; - ASSERT(str < strs[1]); - - (*pointers*) - NEW(t1); - t := t1; - ASSERT(t = t1); - ASSERT(t1 = t); - t := NIL; - ASSERT((t IS T) OR ~(t IS T)) (*The value of NIL IS T is undefined.*) - END TestRelationalOperations; - - - PROCEDURE TestAdditiveOperations; - CONST eps = 0.01; - VAR b: BOOLEAN; - n: INTEGER; - x: REAL; - y: BYTE; - A: SET; - BEGIN - (*booleans*) - ASSERT(TRUE OR TRUE); - ASSERT(TRUE OR FALSE); - ASSERT(FALSE OR TRUE); - b := TRUE; - ASSERT(b OR TRUE); - ASSERT(b OR FALSE); - ASSERT(FALSE OR b); - - (*integers*) - ASSERT(1 + 1 = 2); - ASSERT(1 - 1 = 0); - n := 1; - ASSERT(+n = +1); - ASSERT(-n = -1); - ASSERT(n + 1 = 2); - ASSERT(n - 1 = 0); - ASSERT(-n + 1 = 0); - ASSERT(-n - 1 = -2); - - (*reals*) - ASSERT(1.0 + 1.0 >= 2.0 - eps); - ASSERT(1.0 + 1.0 <= 2.0 + eps); - ASSERT(1.0 - 1.0 >= -eps); - ASSERT(1.0 - 1.0 <= eps); - x := 1.0; - ASSERT(+x = +1.0); - ASSERT(-x = -1.0); - ASSERT(x + 1.0 >= 2.0 - eps); - ASSERT(x + 1.0 <= 2.0 + eps); - ASSERT(x - 1.0 >= -eps); - ASSERT(x - 1.0 <= eps); - ASSERT(-x + 1.0 >= - eps); - ASSERT(-x + 1.0 <= eps); - ASSERT(-x - 1.0 >= -2.0 - eps); - ASSERT(-x - 1.0 <= -2.0 + eps); - - (*bytes*) - y := 1; - ASSERT(+y = +1); - ASSERT(-y = -1); - ASSERT(y + 1= 2); - ASSERT(1 - y = 0); - - (*sets*) - ASSERT({0, 1} + (-{0, 1}) = -{}); - ASSERT({0, 1} + {0, 2} = {0 .. 2}); - ASSERT({0, 1} - {0, 2} = {1}); - A := {0, 1}; - ASSERT(A + (-{0, 1}) = -{}); - ASSERT(A + {0, 2} = {0 .. 2}); - ASSERT(A - {0, 2} = {1}) - END TestAdditiveOperations; - - - PROCEDURE TestMultiplicativeOperations; - CONST eps = 0.01; - VAR b: BOOLEAN; - i, j, n: INTEGER; - x: REAL; - y: BYTE; - A: SET; - BEGIN - (*booleans*) - ASSERT(TRUE & TRUE); - b := TRUE; - ASSERT(b & TRUE); - - (*integers*) - ASSERT(9 * 2 = 18); - ASSERT(9 DIV 4 = 2); - ASSERT((-9) DIV 4 = -3); - ASSERT(9 MOD 4 = 1); - ASSERT((-9) MOD 4 = 3); - n := -9; - y := 4; - ASSERT(n * y = -36); - ASSERT(n DIV y = -3); - ASSERT(n MOD y = 3); - i := 1; - j := 1; - n := (IncReturnZero(i) + 3) DIV (IncReturnZero(j) + 2); - ASSERT(n = 1); - ASSERT(i = 2); - ASSERT(j = 2); - n := IncReturnZero(i) MOD (IncReturnZero(j) + 1); - ASSERT(i = 3); - ASSERT(j = 3); - - (*reals*) - ASSERT(9.0 * 2.0 >= 18.0 - eps); - ASSERT(9.0 * 2.0 <= 18.0 + eps); - ASSERT(9.0 / 2.0 >= 4.5 - eps); - ASSERT(9.0 / 2.0 <= 4.5 + eps); - x := 9.0; - ASSERT(x * 2.0 >= 18.0 - eps); - ASSERT(x * 2.0 <= 18.0 + eps); - ASSERT(x / 2.0 >= 4.5 - eps); - ASSERT(x / 2.0 <= 4.5 + eps); - - (*bytes*) - y := 9; - ASSERT(y * 2 = 18); - (*ASSERT(y DIV 4 = 2); - ASSERT(y MOD 4 = 1);*) - - (*sets*) - ASSERT({0, 1} * {1, 2} = {1}); - ASSERT({0, 1} / {1, 2} = {0, 2}); - A := {0, 1}; - ASSERT(A * {1, 2} = {1}); - ASSERT(A / {1, 2} = {0, 2}) - END TestMultiplicativeOperations; - - - PROCEDURE TestPredeclaredFunctionProcedures; - CONST eps = 0.01; - (*make sure function procedures with constant parameters are constant expressions*) - absConst = 0; (* rochus ABS(0); *) - oddConst = 0; (* rochus ODD(0); *) - lslConst = 0; (* rochus LSL(0, 0); *) - asrConst = 0; (* rochus ASR(0, 0); *) - rorConst = 0; (* rochus ROR(0, 1); *) - floorConst = 0; (* rochus FLOOR(eps); *) - fltConst = 0; (* rochus FLT(0); *) - ordConst = 1; (* rochus ORD(TRUE); *) - chrConst = 0; (* rochus CHR(0); *) - - VAR a: ARRAY 10 OF CHAR; - b: BOOLEAN; - ch: CHAR; - i, j, k: INTEGER; - r: REAL; - x: BYTE; - s: SET; - BEGIN - ASSERT(ABS(-1) = 1); - ASSERT(ABS(0) = 0); - ASSERT(ABS(1) = 1); - ASSERT(ABS(-1.0) = 1.0); - ASSERT(ABS(0.0) = 0.0); - ASSERT(ABS(1.0) = 1.0); - i := 0; - j := ABS(IncReturnZero(i) - 1); - ASSERT(j = 1); - ASSERT(i = 1); - - ASSERT(~ODD(-2)); - ASSERT(ODD(-1)); - ASSERT(~ODD(0)); - ASSERT(ODD(1)); - ASSERT(~ODD(2)); - - a := ""; - ASSERT(LEN(a) = 10); - - ASSERT(LSL(0, 0) = 0); - ASSERT(LSL(0, 1) = 0); - ASSERT(LSL(1, 0) = 1); - ASSERT(LSL(1, 1) = 2); - - ASSERT(ASR(0, 0) = 0); - ASSERT(ASR(0, 1) = 0); - ASSERT(ASR(1, 0) = 1); - ASSERT(ASR(1, 1) = 0); - - ASSERT(ROR(0, 1) = 0); - ASSERT(ROR(2, 1) = 1); - i := 0; - j := 0; - k := ROR(IncReturnZero(i) + 2, IncReturnZero(j) + 1); - ASSERT(k = 1); - ASSERT(i = 1); - ASSERT(j = 1); - - ASSERT(FLOOR(-1.5) = -2); - ASSERT(FLOOR(0.0) = 0); - ASSERT(FLOOR(1.5) = 1); - i := 0; - j := FLOOR(FLT(IncReturnZero(i)) + 1.5); - ASSERT(j = 1); - ASSERT(i = 1); - - ASSERT(FLT(-1) = -1.0); - ASSERT(FLT(0) = 0.0); - ASSERT(FLT(1) = 1.0); - - ASSERT(ORD(0X) = 0); - ch := 0X; - ASSERT(ORD(ch) = 0); - ASSERT(ORD("A") = 41H); - ch := "A"; - ASSERT(ORD(ch) = 41H); - ASSERT(ORD(0FFX) = 0FFH); - ch := 0FFX; - ASSERT(ORD(ch) = 0FFH); - - ASSERT(ORD(FALSE) = 0); - b := FALSE; - ASSERT(ORD(b) = 0); - ASSERT(ORD(TRUE) = 1); - b := TRUE; - ASSERT(ORD(b) = 1); - - ASSERT(ORD({}) = 0); - s := {}; - ASSERT(ORD(s) = 0); - ASSERT(ORD({8}) = 256); - s := {8}; - ASSERT(ORD(s) = 256); - - ASSERT(CHR(0) = 0X); - ASSERT(CHR(1) = 1X); - ASSERT(CHR(7FH) = 7FX); - ch := 7FX; - ASSERT(CHR(7FH) = ch); - x := 1; - ASSERT(CHR(x) = 1X); - - i := absConst; - b := oddConst; - i := lslConst; - i := asrConst; - i := rorConst; - i := floorConst; - r := fltConst; - i := ordConst; - ch := chrConst - END TestPredeclaredFunctionProcedures; - -BEGIN - TestDesignators; - TestSetConstructors; - TestRelationalOperations; - TestAdditiveOperations; - TestMultiplicativeOperations; - TestPredeclaredFunctionProcedures; -END T4Expressions. diff --git a/testcases/T5Statements.obn b/testcases/T5Statements.obn deleted file mode 100644 index 37aa856..0000000 --- a/testcases/T5Statements.obn +++ /dev/null @@ -1,552 +0,0 @@ -(*Copyright (C) 2017, 2018, 2019 Karl Landstrom - modifications by me@rochus-keller.ch, Oct. 2019 - -This file is part of OBNC. - -OBNC is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -OBNC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with OBNC. If not, see .*) - -MODULE T5Statements; - - TYPE - T0 = RECORD END; - T1 = RECORD (T0) END; - - Shape = POINTER TO ShapeDesc; - ShapeDesc = RECORD - x, y: REAL - END; - - Rectangle = POINTER TO RectangleDesc; - RectangleDesc = RECORD (ShapeDesc) - w, h: REAL - END; - - Circle = POINTER TO CircleDesc; - CircleDesc = RECORD (ShapeDesc) - r: REAL - END; - - String = ARRAY 256 OF CHAR; - - VAR - globalInteger: INTEGER; - - PROCEDURE TestBasicAssignments; - VAR b, b1: BOOLEAN; - ch, ch1: CHAR; - n, n1: INTEGER; - x, x1: REAL; - y, y1: BYTE; - A, A1: SET; - BEGIN - b := TRUE; - b1 := FALSE; - b := b1; - ASSERT(b = b1); - ch := "a"; - ch1 := 22X; - ch := ch1; - ASSERT(ch = ch1); - n := 0; - n1 := -1; - n := n1; - ASSERT(n = n1); - x := 0.0; - x1 := -1.0; - x := x1; - ASSERT(x = x1); - y := 0; - y1 := 255; - y := y1; - ASSERT(y = y1); - n := 0; - y := n; - ASSERT(y = n); - A := {}; - A1 := {0, 1}; - A := A1; - ASSERT(A = A1); - END TestBasicAssignments; - - - PROCEDURE TestArrayAssignments; - VAR str, str1: ARRAY 60 OF CHAR; - strs, strs1: ARRAY 2 OF String; - strs2: ARRAY 1, 2 OF String; - - PROCEDURE AssignString(VAR s: ARRAY OF CHAR); - BEGIN - s := "hello" - END AssignString; - - PROCEDURE AssignOpenArray(s: ARRAY OF CHAR); - VAR t: ARRAY 128 OF CHAR; - BEGIN - t := s; - ASSERT(t = s) - END AssignOpenArray; - - PROCEDURE AssignMultiDimOpenArray(s: ARRAY OF ARRAY OF String); - VAR t: ARRAY 2 OF String; - BEGIN - t := s[0]; - ASSERT(t[0] = s[0, 0]); - ASSERT(t[1] = s[0, 1]) - END AssignMultiDimOpenArray; - - BEGIN - str := "testing, testing..."; - str1 := "more testing..."; - str := str1; - ASSERT(str = str1); - AssignString(str); - ASSERT(str = "hello"); - AssignOpenArray("hello"); - - strs[0] := "foo"; - ASSERT(strs[0] = "foo"); - strs[1] := "bar"; - ASSERT(strs[1] = "bar"); - strs[1] := strs[0]; - ASSERT(strs[1] = "foo"); - - strs[0] := "foo"; - strs[1] := "bar"; - strs1 := strs; - ASSERT(strs1[0] = "foo"); - ASSERT(strs1[1] = "bar"); - - AssignMultiDimOpenArray(strs2) - END TestArrayAssignments; - - - PROCEDURE TestRecordAssignments; - CONST eps = 0.01; - VAR foo, bar: RECORD ch: CHAR; i: INTEGER END; - s: ShapeDesc; - r: RectangleDesc; - c: CircleDesc; - a: ARRAY 10 OF CircleDesc; - - PROCEDURE P(VAR s: ShapeDesc); - BEGIN - ASSERT(s IS CircleDesc); - s(CircleDesc) := s(CircleDesc); - s(CircleDesc).r := 1.0 - END P; - - PROCEDURE Copy(VAR source, target: ShapeDesc); - BEGIN - target := source - END Copy; - - BEGIN - foo.i := 37; - bar := foo; - ASSERT(bar.i = 37); - - s.x := 0.0; - s.y := 0.0; - r.x := 0.0; - P(c); - ASSERT(ABS(c.r - 1.0) < eps); - - r.x := 1.0; - s := r; - ASSERT(s.x = r.x); - - P(a[9]); - - Copy(r, r) - END TestRecordAssignments; - - - PROCEDURE TestPointerAssignments; - VAR x: Rectangle; - y: Shape; - s: POINTER TO ShapeDesc; - r: POINTER TO RectangleDesc; - r1: POINTER TO RectangleDesc; - BEGIN - NEW(x); - y := x; - ASSERT(y IS Rectangle); - NEW(r); - s := r; - ASSERT(s IS RectangleDesc); - r1 := r; - ASSERT(r1 IS RectangleDesc) - END TestPointerAssignments; - - - PROCEDURE P; - END P; - - PROCEDURE P1(n: INTEGER); - END P1; - - PROCEDURE P2(n: INTEGER; x: REAL); - END P2; - - PROCEDURE F(): INTEGER; - RETURN 0 - END F; - - PROCEDURE F1(n: INTEGER): INTEGER; - RETURN 0 - END F1; - - PROCEDURE F2(VAR n: INTEGER; x: REAL; s: ARRAY OF CHAR): INTEGER; - RETURN 0 - END F2; - - PROCEDURE TestProcedureAssignments; - TYPE - PT = PROCEDURE; - PT1 = PROCEDURE (n: INTEGER); - PT2 = PROCEDURE (n: INTEGER; x: REAL); - FT = PROCEDURE (): INTEGER; - FT1 = PROCEDURE (n: INTEGER): INTEGER; - FT2 = PROCEDURE (VAR n: INTEGER; x: REAL; s: ARRAY OF CHAR): INTEGER; - VAR p: PT; p1: PT1; p2: PT2; - f: FT; f1: FT1; f2, g2: FT2; - n: INTEGER; - - PROCEDURE Local; - END Local; - - BEGIN - p := NIL; - p := P; - p := Local; - p1 := P1; - p2 := P2; - f := F; - n := f(); - f1 := F1; - f2 := F2; - g2 := f2 - END TestProcedureAssignments; - - - PROCEDURE TestAssignments; - BEGIN - TestBasicAssignments; - TestArrayAssignments; - TestRecordAssignments; - TestPointerAssignments; - TestProcedureAssignments - END TestAssignments; - - - PROCEDURE TestProcedureCalls; - VAR s: ARRAY 16 OF CHAR; - p0: POINTER TO T0; - p1: POINTER TO T1; - - PROCEDURE P1; - END P1; - - PROCEDURE P2(n: INTEGER); - END P2; - - PROCEDURE P3(a, b: INTEGER); - END P3; - - PROCEDURE P4(a: INTEGER; b: INTEGER); - END P4; - - PROCEDURE P5(ch: CHAR); - END P5; - - PROCEDURE P6(s: ARRAY OF CHAR); - END P6; - - PROCEDURE P7(VAR t: T0); - BEGIN - ASSERT(t IS T1) - END P7; - - BEGIN - P1; - P2(0); - P3(0, 0); - P4(0, 0); - P5("x"); - P5(0X); - P6("test"); - s := "test"; - P6(s); - NEW(p1); - p0 := p1; - P7(p0^) - END TestProcedureCalls; - - - PROCEDURE TestPredeclaredProperProcedures; - CONST eps = 0.01; - VAR n, i, j: INTEGER; - A: SET; - x: REAL; - a: ARRAY 1 OF REAL; - b: ARRAY 1 OF INTEGER; - v: POINTER TO RECORD f: INTEGER END; - - PROCEDURE IncReturnZero(VAR x: INTEGER): INTEGER; - BEGIN - INC(x) - RETURN 0 - END IncReturnZero; - - BEGIN - n := 0; - INC(n); - ASSERT(n = 1); - - n := 0; - INC(n, 10); - ASSERT(n = 10); - - n := 0; - DEC(n); - ASSERT(n = -1); - - n := 0; - DEC(n, 10); - ASSERT(n = -10); - - A := {}; - INCL(A, 0); - ASSERT(A = {0}); - - A := {0}; - EXCL(A, 0); - ASSERT(A = {}); - - NEW(v); - ASSERT(v # NIL); - v.f := 1; - ASSERT(v.f = 1); - - x := 1.0; - PACK(x, 2); - ASSERT(x >= 4.0 - eps); - ASSERT(x <= 4.0 + eps); - a[0] := 1.0; - i := 0; - j := 0; - PACK(a[IncReturnZero(i)], IncReturnZero(j) + 2); - ASSERT(a[0] >= 4.0 - eps); - ASSERT(a[0] <= 4.0 + eps); - ASSERT(i = 1); - ASSERT(j = 1); - - x := 4.0; - UNPK(x, n); - ASSERT(x >= 1.0); - ASSERT(x < 2.0); - ASSERT(n = 2); - a[0] := 4.0; - i := 0; - j := 0; - UNPK(a[IncReturnZero(i)], b[IncReturnZero(j)]); - ASSERT(a[0] >= 1.0); - ASSERT(a[0] < 2.0); - ASSERT(b[0] = 2); - ASSERT(i = 1); - ASSERT(j = 1) - END TestPredeclaredProperProcedures; - - - PROCEDURE TestIfStatements; - VAR n: INTEGER; - BEGIN - n := 0; - IF n = 0 THEN - n := 1 - END; - ASSERT(n = 1); - n := 1; - IF n = 0 THEN - n := 1 - ELSE - n := 2 - END; - ASSERT(n = 2); - n := 2; - IF n = 0 THEN - n := 1 - ELSIF n = 1 THEN - n := 2 - ELSE - n := 3 - END; - ASSERT(n = 3) - END TestIfStatements; - - - PROCEDURE TestCaseStatements; - CONST - C = 0; - - VAR - n: INTEGER; - ch: CHAR; - sp: Shape; - rp: Rectangle; - c: CircleDesc; - - PROCEDURE P(VAR s: ShapeDesc); - BEGIN - CASE s OF - (*ShapeDesc: - s.x := 0.0; s.y := 0.0 - | *)RectangleDesc: - s.w := 1.0; s.h := 0.0 - | CircleDesc: - s.r := 1.0 - END; - END P; - - BEGIN - n := 15; - CASE n OF - C: - CASE 1 OF - 1: - END - | 1, 2: - CASE sp OF END - | 4, 5, 7: - | 8 .. 9: - | 10, 12 .. 20: - n := 0 - END; - ASSERT(n = 0); - ch := "u"; - CASE ch OF - | 0X: - | "a", "b": - | "d", "e", "f": - | "h" .. "k": - | "l", "m" .. "z": - ch := 0X - END; - ASSERT(ch = 0X); - NEW(rp); - sp := rp; - CASE sp OF - (*Shape: - sp.x := 0.0; sp.y := 0.0 - | *)Rectangle: - sp.w := 1.0; sp.h := 2.0; - sp := sp - | Circle: - sp.r := 1.0 - END; - ASSERT(sp(Rectangle).w = 1.0); - ASSERT(sp(Rectangle).h = 2.0); - P(c); - ASSERT(c.r = 1.0); - END TestCaseStatements; - - - PROCEDURE TestWhileStatements; - VAR n, n1, i: INTEGER; - BEGIN - n := 0; - i := 1; - WHILE i <= 10 DO - n := n + 1; - i := i + 1 - END; - ASSERT(n = 10); - n := 4; - n1 := 6; - WHILE n > n1 DO - n := n - n1 - ELSIF n1 > n DO - n1 := n1 - n - END; - ASSERT(n = 2); - ASSERT(n1 = 2); - n := 5; - n1 := 6; - WHILE n > n1 DO - n := n - n1 - ELSIF n1 > n DO - n1 := n1 - n - END; - ASSERT(n = 1); - ASSERT(n1 = 1); - END TestWhileStatements; - - - PROCEDURE TestRepeatStatements; - VAR n, i: INTEGER; - BEGIN - n:= 0; - i := 1; - REPEAT - INC(n); - INC(i) - UNTIL i = 11; - ASSERT(n = 10); - END TestRepeatStatements; - - - PROCEDURE IncGlobalIntegerReturnOne(): INTEGER; - BEGIN - INC(globalInteger) - RETURN 1 - END IncGlobalIntegerReturnOne; - - - PROCEDURE TestForStatements; - VAR n, i: INTEGER; - x: REAL; - BEGIN - x := 0.0; (* added by rochus *) - n := 0; - FOR i := 1 TO 10 DO - n := n + 1 - END; - ASSERT(n = 10); - n := 0; - FOR i := 1 TO 20 BY 2 DO - n := n + 1 - END; - ASSERT(n = 10); - n := 0; - FOR i := 20 TO 1 BY -2 DO - n := n + 1 - END; - ASSERT(n = 10); - globalInteger := 0; - FOR i := 0 TO IncGlobalIntegerReturnOne() DO (*make sure the limit function is called three times*) - x := x + 1.0 - END; - ASSERT(globalInteger = 3) - END TestForStatements; - -BEGIN - TestAssignments; - TestProcedureCalls; - TestPredeclaredProperProcedures; - TestIfStatements; - TestCaseStatements; - TestWhileStatements; - TestRepeatStatements; - TestForStatements -END T5Statements. diff --git a/testcases/T6ProcedureDeclarations.obn b/testcases/T6ProcedureDeclarations.obn deleted file mode 100644 index 713a7fd..0000000 --- a/testcases/T6ProcedureDeclarations.obn +++ /dev/null @@ -1,261 +0,0 @@ -(*Copyright (C) 2017, 2018, 2019 Karl Landstrom - modifications by me@rochus-keller.ch, Oct. 2019 - -This file is part of OBNC. - -OBNC is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -OBNC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with OBNC. If not, see .*) - -MODULE T6ProcedureDeclarations; - - TYPE - Row = ARRAY 20 OF INTEGER; - Matrix = ARRAY 10, 20 OF INTEGER; - PtrDesc = RECORD f: INTEGER END; (* rochus *) - Ptr = POINTER TO PtrDesc; - Proc = PROCEDURE; - T0 = RECORD END; - T1 = RECORD (T0) END; - T2 = RECORD (T1) - f: INTEGER - END; - - PROCEDURE TestValueParameters; - VAR ptr: Ptr; - proc: Proc; - A: Matrix; - B: ARRAY 10 OF Row; - - PROCEDURE P(x: INTEGER); - BEGIN - x := 0 - END P; - - PROCEDURE P1(x: Ptr); - BEGIN - x := NIL - END P1; - - PROCEDURE P2(x: Proc); - BEGIN - x := NIL - END P2; - - PROCEDURE P3(A: Matrix); - BEGIN - ASSERT(LEN(A) = 10); - ASSERT(LEN(A[0]) = 20) - END P3; - - PROCEDURE P4(A: ARRAY OF Row); - END P4; - - BEGIN - P(0); - NEW(ptr); - P1(ptr); - P2(proc); - P3(A); - P4(B) - END TestValueParameters; - - - PROCEDURE TestVarParameters; - VAR x: Ptr; - A: Matrix; - y: T2; - - PROCEDURE Alloc(VAR p: Ptr); - BEGIN - NEW(p); - p.f := 1 - END Alloc; - - PROCEDURE P(VAR A: Matrix); - BEGIN - ASSERT(LEN(A) = 10); - ASSERT(LEN(A[0]) = 20) - END P; - - PROCEDURE Q(VAR x: T0); - PROCEDURE R(VAR x: T1); - BEGIN - x(T2).f := 1 - END R; - BEGIN - R(x(T1)) - END Q; - - BEGIN - Alloc(x); - ASSERT(x.f = 1); - P(A); - y.f := 0; - Q(y) - END TestVarParameters; - - - PROCEDURE TestOpenArrayParameters; - VAR - a: ARRAY 2 OF INTEGER; - M: ARRAY 2, 3 OF INTEGER; - T: ARRAY 2, 3, 4 OF INTEGER; - c, i, j, k: INTEGER; - - PROCEDURE P(a: ARRAY OF INTEGER); - VAR i: INTEGER; - BEGIN - FOR i := 0 TO LEN(a) - 1 DO - ASSERT(a[i] = i + 1) - END - END P; - - PROCEDURE Q(M: ARRAY OF ARRAY OF INTEGER); - VAR a: ARRAY 3 OF INTEGER; - - PROCEDURE Inner(M: ARRAY OF ARRAY OF INTEGER); - VAR c, i, j: INTEGER; - BEGIN - c := 0; - FOR i := 0 TO LEN(M) - 1 DO - FOR j := 0 TO LEN(M[0]) - 1 DO - ASSERT(M[i, j] = c); - INC(c) - END - END; - END Inner; - - PROCEDURE Inner1(row: ARRAY OF INTEGER); - VAR c, j: INTEGER; - BEGIN - c := LEN(row); - FOR j := 0 TO LEN(row) - 1 DO - ASSERT(row[j] = c); - INC(c) - END - END Inner1; - - BEGIN - Inner(M); - Inner1(M[1]); - a := M[1] - END Q; - - PROCEDURE R(VAR T: ARRAY OF ARRAY OF ARRAY OF INTEGER); - VAR c, i, j, k: INTEGER; - BEGIN - c := 0; - FOR i := 0 TO LEN(T) - 1 DO - FOR j := 0 TO LEN(T[0]) - 1 DO - FOR k := 0 TO LEN(T[0, 0]) - 1 DO - ASSERT(T[i, j, k] = c); - INC(c) - END - END - END; - T[0, 0, 0] := 0 - END R; - - BEGIN - FOR i := 0 TO LEN(a) - 1 DO - a[i] := i + 1 - END; - P(a); - - c := 0; - FOR i := 0 TO LEN(M) - 1 DO - FOR j := 0 TO LEN(M[0]) - 1 DO - M[i, j] := c; - INC(c) - END - END; - Q(M); - - c := 0; - FOR i := 0 TO LEN(T) - 1 DO - FOR j := 0 TO LEN(T[0]) - 1 DO - FOR k := 0 TO LEN(T[0, 0]) - 1 DO - T[i, j, k] := c; - INC(c) - END - END - END; - R(T) - END TestOpenArrayParameters; - - - PROCEDURE TestResultExpressions; - VAR x: Ptr; - - PROCEDURE P(): Ptr; - TYPE PtrExt = POINTER TO RECORD (PtrDesc) END; (* rochus *) - VAR y: PtrExt; - BEGIN - NEW(y) - RETURN y - END P; - - BEGIN - x := P() - END TestResultExpressions; - - - PROCEDURE TestLocalProcedures; - VAR s: INTEGER; - - PROCEDURE Sum(n: INTEGER): INTEGER; - - PROCEDURE Inner(i, acc: INTEGER): INTEGER; - VAR result: INTEGER; - BEGIN - IF i >= 1 THEN - result := Inner(i - 1, acc + i) - ELSE - result := acc - END - RETURN result - END Inner; - - RETURN Inner(n, 0) - END Sum; - - BEGIN - s := Sum(10); - ASSERT(s = 55) - END TestLocalProcedures; - - - PROCEDURE TestScope; - TYPE - List = POINTER TO Node; - Node = RECORD - item: INTEGER; - next: List - END; - Proc = PROCEDURE (x: List): List; - VAR - TestScope: PROCEDURE; - p: Proc; - BEGIN - TestScope := NIL; - p := NIL - END TestScope; - -BEGIN - TestValueParameters; - TestVarParameters; - TestOpenArrayParameters; - TestResultExpressions; - TestLocalProcedures; - TestScope -END T6ProcedureDeclarations. diff --git a/testcases/T7Modules/A.obn b/testcases/T7Modules/A.obn deleted file mode 100644 index 49bf267..0000000 --- a/testcases/T7Modules/A.obn +++ /dev/null @@ -1,105 +0,0 @@ -(*Copyright (C) 2017, 2018, 2019 Karl Landstrom - -This file is part of OBNC. - -OBNC is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -OBNC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with OBNC. If not, see .*) - -MODULE A; - - IMPORT B; - - CONST - boolConst* = TRUE; - charConst* = 22X; (* CHR(22H); *) - intConst* = 1; - realConst* = 2.3; - strConst* = "hello there"; - nul* = 0X; - lf* = 0AX; - charMax* = 0FFX; - setConst* = {0, 2, 3, 5}; - - TYPE - Integer = INTEGER; - String = ARRAY 256 OF CHAR; - EmptyRecord* = RECORD END; - EmptyExtendedRecord* = RECORD (EmptyRecord) END; - EmptyPointer* = POINTER TO EmptyRecord; - EmptyExtendedPointer* = POINTER TO RECORD (EmptyRecord) END; - List* = POINTER TO Node; - Node = RECORD - key: String; - next: List - END; - Nested* = RECORD - f*: B.U - END; - Proc* = PROCEDURE; - Proc1* = PROCEDURE (n: Node); - Proc2* = PROCEDURE (): List; - Proc3* = PROCEDURE (n: Node): List; - Proc4* = PROCEDURE (n, n1: Node): List; - Proc5* = PROCEDURE (n: Node; i: INTEGER); - Proc6* = PROCEDURE (n, n1: Node; i: INTEGER); - T* = B.T; - P1* = B.P1; - - VAR - boolVar*: BOOLEAN; - charVar*: CHAR; - intVar*: Integer; - realVar* : REAL; - byteVar*: BYTE; - setVar*: SET; - strVar*: String; - recVar*, recVar1: RECORD - f*: INTEGER - END; - ptrVar*: POINTER TO Node; - procVar*: PROCEDURE (s: String); - alias: B.CTAlias; - - PROCEDURE P*(s: String); - END P; - - - PROCEDURE Q*(x: B.T); - END Q; - - - PROCEDURE R*(A: ARRAY OF ARRAY OF INTEGER); - END R; - - - PROCEDURE S*(x: T); - END S; - - - PROCEDURE S1*(VAR x: P1); - END S1; - -BEGIN - boolVar := boolConst; - charVar := charConst; - intVar := intConst; - realVar := realConst; - byteVar := intConst; - setVar := setConst; - strVar := strConst; - recVar.f := 1; - recVar1.f := 0; - ptrVar := NIL; - procVar := P; - B.P(alias) -END A. diff --git a/testcases/T7Modules/B.obn b/testcases/T7Modules/B.obn deleted file mode 100644 index f3e9607..0000000 --- a/testcases/T7Modules/B.obn +++ /dev/null @@ -1,32 +0,0 @@ -(*Copyright (C) 2017, 2018, 2019 Karl Landstrom - -This file is part of OBNC. - -OBNC is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -OBNC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with OBNC. If not, see .*) - -MODULE B; - - IMPORT C1 := C; - - TYPE - T* = RECORD (C1.T) END; - P1* = POINTER TO RECORD (C1.T0) END; - U* = POINTER TO UDesc; - UDesc* = RECORD f*: INTEGER END; - CTAlias* = C1.T; - - PROCEDURE P*(VAR x: CTAlias); - END P; - -END B. diff --git a/testcases/T7Modules/C.obn b/testcases/T7Modules/C.obn deleted file mode 100644 index 6e4253f..0000000 --- a/testcases/T7Modules/C.obn +++ /dev/null @@ -1,25 +0,0 @@ -(*Copyright (C) 2017, 2018, 2019 Karl Landstrom - -This file is part of OBNC. - -OBNC is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -OBNC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with OBNC. If not, see .*) - -MODULE C; - - TYPE - T* = RECORD END; - T0* = RECORD END; - P0* = POINTER TO T0; - -END C. diff --git a/testcases/T7Modules/D.obn b/testcases/T7Modules/D.obn deleted file mode 100644 index 50b9f17..0000000 --- a/testcases/T7Modules/D.obn +++ /dev/null @@ -1,22 +0,0 @@ -(*Copyright (C) 2017, 2018, 2019 Karl Landstrom - -This file is part of OBNC. - -OBNC is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -OBNC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with OBNC. If not, see .*) - -MODULE D; - - CONST b* = TRUE; - -END D. diff --git a/testcases/T7Modules/E.Mod b/testcases/T7Modules/E.Mod deleted file mode 100644 index fb5f6a7..0000000 --- a/testcases/T7Modules/E.Mod +++ /dev/null @@ -1,22 +0,0 @@ -(*Copyright (C) 2017, 2018, 2019 Karl Landstrom - -This file is part of OBNC. - -OBNC is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -OBNC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with OBNC. If not, see .*) - -MODULE E; - - CONST b* = TRUE; - -END E. diff --git a/testcases/T7Modules/LocalE.obn b/testcases/T7Modules/LocalE.obn deleted file mode 100644 index 4f2b0a8..0000000 --- a/testcases/T7Modules/LocalE.obn +++ /dev/null @@ -1,29 +0,0 @@ -(*Copyright (C) 2017, 2018, 2019 Karl Landstrom - -This file is part of OBNC. - -OBNC is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -OBNC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with OBNC. If not, see .*) - -MODULE LocalE; - - TYPE - T* = RECORD f*: INTEGER END; - - VAR - x*: INTEGER; - - PROCEDURE P*; - END P; - -END LocalE. diff --git a/testcases/T7Modules/LocalM.obn b/testcases/T7Modules/LocalM.obn deleted file mode 100644 index 391d8b2..0000000 --- a/testcases/T7Modules/LocalM.obn +++ /dev/null @@ -1,29 +0,0 @@ -(*Copyright (C) 2017, 2018, 2019 Karl Landstrom - -This file is part of OBNC. - -OBNC is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -OBNC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with OBNC. If not, see .*) - -MODULE LocalM; - - TYPE - T* = RECORD f*: INTEGER END; - - VAR - x*: INTEGER; - - PROCEDURE P*; - END P; - -END LocalM. diff --git a/testcases/T7Modules/OBNC.obn b/testcases/T7Modules/OBNC.obn deleted file mode 100644 index 8240354..0000000 --- a/testcases/T7Modules/OBNC.obn +++ /dev/null @@ -1,37 +0,0 @@ -(*Copyright (C) 2017, 2018, 2019 Karl Landstrom - -This file is part of OBNC. - -OBNC is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -OBNC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with OBNC. If not, see .*) - -MODULE OBNC; (*should not cause a conflict with system C module OBNC*) - - (*generated identifiers with suffixes should not conflict with identifiers declared in system module OBNC*) - - CONST b* = TRUE; - - TYPE - OBNC = RECORD f: INTEGER END; - - VAR - a: ARRAY 1 OF INTEGER; - x: OBNC; - - PROCEDURE Q(OBNC: ARRAY OF INTEGER); - END Q; - -BEGIN - Q(a); - x.f := 0 -END OBNC. diff --git a/testcases/T7Modules/Readme.md b/testcases/T7Modules/Readme.md deleted file mode 100644 index 761ab57..0000000 --- a/testcases/T7Modules/Readme.md +++ /dev/null @@ -1,3 +0,0 @@ -modified by rochus -no pointers as base records -no duplicate module names diff --git a/testcases/T7Modules/T7Modules.obn b/testcases/T7Modules/T7Modules.obn deleted file mode 100644 index b6efb58..0000000 --- a/testcases/T7Modules/T7Modules.obn +++ /dev/null @@ -1,86 +0,0 @@ -(*Copyright (C) 2017, 2018, 2019 Karl Landstrom - modifications by me@rochus-keller.ch, Oct. 2019 - -This file is part of OBNC. - -OBNC is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -OBNC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with OBNC. If not, see .*) - -MODULE T7Modules; - - IMPORT - A, - B1 := B, - B := C, - D := D, - E, - T7Modules := libE, - lib1M, - OBNC; - - TYPE - ListExt = POINTER TO RECORD (A.Node) END; - - VAR - intVar: INTEGER; - w: B.T; - x: B1.T; - y: A.Nested; - list: A.List; - matrix: ARRAY 2, 3 OF INTEGER; - x0: B.P0; - x1: B1.P1; - t: B1.T; - p: B1.P1; - p1: ListExt; - -BEGIN - ASSERT(A.boolConst); - ASSERT(A.charConst = CHR(22H)); - ASSERT(A.intConst = 1); - ASSERT(A.realConst = 2.3); - ASSERT(A.strConst = "hello there"); - ASSERT(A.nul = 0X); - ASSERT(A.lf = 0AX); - ASSERT(A.charMax = 0FFX); - ASSERT(A.setConst = {0, 2, 3, 5}); - - ASSERT(A.boolVar = A.boolConst); - ASSERT(A.charVar = A.charConst); - ASSERT(A.intVar = A.intConst); - ASSERT(ABS(A.realVar - A.realConst) < 1.0E-6); - ASSERT(A.strVar = A.strConst); - ASSERT(A.setVar = A.setConst); - ASSERT(A.recVar.f = 1); - - intVar := A.intVar; - A.procVar(A.strVar); - NEW(y.f); - y.f.f := 1; - w := x; - A.Q(x); - NEW(list); - A.R(matrix); - x0 := x1; - A.S(t); - A.S1(p); - - ASSERT(D.b); - ASSERT(E.b); - ASSERT(T7Modules.b); - ASSERT(lib1M.b); - ASSERT(OBNC.b); - p1 := NIL -END T7Modules. - -(* rochus disabled: All text after a module should be ignored *) diff --git a/testcases/T7Modules/lib1M.obn b/testcases/T7Modules/lib1M.obn deleted file mode 100644 index 56f96c5..0000000 --- a/testcases/T7Modules/lib1M.obn +++ /dev/null @@ -1,29 +0,0 @@ -(*Copyright (C) 2017, 2018, 2019 Karl Landstrom - -This file is part of OBNC. - -OBNC is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -OBNC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with OBNC. If not, see .*) - -MODULE lib1M; - - IMPORT LocalM; - - CONST b* = TRUE; - - VAR - x: LocalM.T; - -BEGIN - x.f := 0 -END lib1M. diff --git a/testcases/T7Modules/libE.obn b/testcases/T7Modules/libE.obn deleted file mode 100644 index d3513c8..0000000 --- a/testcases/T7Modules/libE.obn +++ /dev/null @@ -1,29 +0,0 @@ -(*Copyright (C) 2017, 2018, 2019 Karl Landstrom - -This file is part of OBNC. - -OBNC is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -OBNC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with OBNC. If not, see .*) - -MODULE libE; - - IMPORT LocalE; - - CONST b* = TRUE; - - VAR - x: LocalE.T; - -BEGIN - x.f := 0 -END libE. diff --git a/testcases/are-we-fast-yet/are-we-fast-yet_results.ods b/testcases/are-we-fast-yet/are-we-fast-yet_results.ods deleted file mode 100644 index 101cdac..0000000 Binary files a/testcases/are-we-fast-yet/are-we-fast-yet_results.ods and /dev/null differ diff --git a/testcases/run_HennessyV4_voc b/testcases/run_HennessyV4_voc deleted file mode 100755 index b4602c3..0000000 --- a/testcases/run_HennessyV4_voc +++ /dev/null @@ -1,5 +0,0 @@ -export PATH="/opt/voc/bin:$PATH" -voc -OC HennessyV4.Mod -m -rm HennessyV4.c -./HennessyV4 -rm HennessyV4