Coder Social home page Coder Social logo

oberon's People

Contributors

rochus-keller avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

oberon's Issues

Mono hangs when creating a new thread in an external library module

Even the most trivial test case hangs:

      module Test4
          import C := NAppCore
          proc worker(data: *void): integer begin println("hello from worker") return 0 end worker
      var t: *C.Thread
      begin
          println("start Test4")
          C.core_start()
          t := C.bthread_create_imp(worker, nil)
          println("thread created")
          C.bthread_wait(t)
          C.core_finish()
          println("end Test4")
      end Test4

This just prints

      start Test4
      thread created

to the console and then waits forever; I found an old Mono bug report which seems to describe this behaviour: https://bugzilla.xamarin.com/15/15695/bug.html; same behaviour in both the Boehm and Sgen version of Mono; still researching.
Apparently the worker function is not run (we don't get output from it); no wonder we wait on bthread_wait.

The generated IL code doesn't look suspicious from my point of view:

    call void [NAppCore]NAppCore::core_start()
    ldsflda valuetype [NAppCore]NAppCore/Thread* Test4::t
    ldnull
    ldftn int32 Test4::worker(native int data)
    newobj instance void class [NAppCore]NAppCore/@597c1d38e252b47b26d76277cefb2b8b::.ctor(object, native int)
    dup
    call void [OBX.Runtime]OBX.Runtime::addRef(object)
    call native int [mscorlib]System.Runtime.InteropServices.Marshal::GetFunctionPointerForDelegate(class [mscorlib]System.Delegate)
    ldnull
    call valuetype [NAppCore]NAppCore/Thread* [NAppCore]NAppCore::bthread_create_imp(native int thmain, native int data)
    stind.i
    ldstr "thread started\0"
    callvirt instance char[] [mscorlib]System.String::ToCharArray()
    call string [OBX.Runtime]OBX.Runtime::toString(char[])
    call void [mscorlib]System.Console::WriteLine(string)
    ldsfld valuetype [NAppCore]NAppCore/Thread* Test4::t
    call int32 [NAppCore]NAppCore::bthread_wait(valuetype [NAppCore]NAppCore/Thread* thread)
    pop
    call void [NAppCore]NAppCore::core_finish()

When the same code is exported to C and run everything works as expected.

Miss *.SO

user@user:~/coding/OberonIDE_linux_i386$ ./ObxIDE
./ObxIDE: error while loading shared libraries: libicui18n.so.52: cannot open shared object file: No such file or directory

Sorry. Nor work %-\

Where to put C# dlls ?

For my project I have created some modules in C#. Where do I put the generated .dlls so that my oberon projects can resolve them?

Niklaus Wirth (1934-2024)

There is an excellent video in youtube that is worth to watch:

https://youtu.be/EXY78gPMvl0?si=Zt6gWa4FhBQytREy

In the time 33:12 he wrote what he learned in his years

  • Writing a program is difficult
  • Writing a correct program is even more so
  • Writing a publishable program is exacting
  • Program is not written. They grow!
  • Controlling the grow needs much discipline
  • Reducing size and complexity is the triumph
  • Programs must not be regarded as code for computers, but as literature for humans

write a text file

I am using as example the oakwood3.obx to write a simple set of number in a file, but without success. Maybe i am making a stupid mistake. The code i used to test is

module filewritetest

import F := Files

var
f : F.File
r : F.Rider
a : int32
b : real
c : int64
d : longreal

begin
a:= 2
b:=3.1415
c:=100
d:=0.002

f := F.New("teste.txt")

F.Set(r,f,0)
F.WriteInt(r,a)
F.WriteLInt(r,c)
F.WriteReal(r,b)
F.WriteLReal(r,d)
F.Register(f)
F.Close(f)

end filewritetest

Problems with projects in INT16 mode

I have various problems with INT16 mode projects particularly when using Oakwood Out and Files. Often complaining about missing methods with Int16 parameters, e.g.

System.MissingMethodException: Method not found: void .Files.Set(Files/Rider,Files/Handle,int16)
at TestInt16Problems.Run () [0x00005] in /home/slw/Develop/OberonCombined/ObxIDE/ASDLSupport/TestInt16Problems.Mod:29
at OBX.Runtime.pcall (OBX.Command cmd, System.Boolean report) [0x00000] in <886ef6ed1e5e447891bce617b8a05575>:0

with the attached test program
TestInt16Problems.txt

(will not allow me to attach .Mod files!)
which is fairly baffling as with the commented out bits as shown has no int16 variables in use!

There also seems to be some problems with the typing of CONSTs. I have had CONST ch = 'a'; treated as a String type rather than a CHAR

Invalid IL code exception

The follow code generates an error:

module TestDate

type
	TDateTime* = longint
    
(* Convert # of Rata Die Days to proleptic Gregorian calendar Year, Month & Day. *)
proc InverseRataDie(days : integer; var year, month, day : integer)
var
    a, b, c, h, z : integer
begin
    z := days + 306 h := 100*z - 25 a := h div 3652425 b := a - a div 4
    year := (100*b + h) div 36525
    c := b + z - 365*year - year div 4
    month := (5*c + 456) div 153
    day := c - (153*month - 457) div 5
    if month > 12 then
        inc(year)
        dec(month, 12)
    end
end InverseRataDie

(* Decode DateTime to Year, Month & Day *)
proc DecodeDate* (datetime: TDateTime; var year, month, day: integer)
begin
    InverseRataDie(datetime div 86400000, year, month, day)
end DecodeDate

var
  year,month,day : integer
begin
  DecodeDate(86400000, year, month, day)
end TestDate

The code compiles fine and have been tested on other Oberon version.
At runtime it fails with the following message:

System.TypeInitializationException: The type initializer for 'TestDate' threw an exception. ---> System.InvalidProgramException: Invalid IL code in TestDate:DecodeDate (long,int&,int&,int&): IL_000f: call      0x06000001


  at TestDate..cctor () [0x00012] in <76014164cb8c4a7daaa157469381efdb>:0 
   --- End of inner exception stack trace ---
  at OBX.Runtime.pcall (OBX.Command cmd, System.Boolean report) [0x00000] in <846778f9d7b048ae8cfecf933b9fa525>:0 

The application finished with code 0

LSL same as ASH

With the following test program:

module Test
import Out
var
    a : integer
begin 
    a := 1;
    Out.Int(a,5) Out.Ln()
    a := lsl(a,1)
    Out.Int(a,5) Out.Ln()
    a := lsl(a,-1)
    Out.Int(a,5) Out.Ln()
    a := 1;
    a := lsl(a,-1)
    Out.Int(a,5) Out.Ln()
    a := -1;
    Out.Int(a,5) Out.Ln()
    a := lsl(a,1)
    Out.Int(a,5) Out.Ln()
    a := lsl(a,-1)
    Out.Int(a,5) Out.Ln()
end Test

We get the output (Mono):

    1
    2
    0
-2147483648
   -1
   -2
    0

I believe LSL should not preserve the sign bit (leftmost bit) when shifting.
Also negative argument are allowed, but set result to zero.
In c this is also undefined behavior.

Perhaps ASH with negative argument can replace ASR?
Same for LSL, with negative argument gives LSR and rename function to LSH?
Otherwise probably negative arguments should be handled to avoid undefined behavior.

Oberon+ Concurrence and others

I am very happy that you continue to work in the oberon+ language. In your paper about possibilities to introduce concurrence in the language you don't cite the Vector Pascal implementation

https://sourceforge.net/projects/vectorpascalcom/

In another topic I saw your implementation of active oberon, I am using for some time the new version (2019)

https://gitlab.inf.ethz.ch/felixf/oberon

The introduction of math arrays is fantastic (they have a library called Matrix very good). The main problem is that the project is like a Frankenstein construct with outdated documentation and half implementation of modules. I saw good ideas there for a solid language, but they need to create a standalone compiler to compile to others operation systems.
One think good is that , like in your oberon implementation, you don't need to write in uppercase the key words. If you begin write in normal letters the compiler will interpreted all the key words correctly.
For modula-2 you saw the modula-2 R10

https://github.com/m2sf

there is a discussion about a better implementation of coroutines. Sadly they don't have a compiler implemented (they are waiting for the creator of the new gnu modula-2 to implement also the R10 specification).
Congratulation for your work.

Building for aarch64 error

Hi.

I don't know if this is even supposed to work on aarch64 but I tried it anyway.
I had a problem to compile the LuaJIT compiler as well. It said it doe not support the architecture. Then I tried to just compile Oberon without it and see.

System: Pinebook Pro (aarch64); Majaro ARM Linux

In Oberon folder:

qmake ObxIde2.pro
make

gives this error after a while.

../PeLib/Resource.h:107:31: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::deque<DotNetPELib::Resource*>::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
  107 |             for( int i = 0; i < s_all.size(); i++ )
      |                             ~~^~~~~~~~~~~~~~
../PeLib/Instruction.cpp: At global scope:
../PeLib/Instruction.cpp:276:1: error: narrowing conversion of ‘-1’ from ‘int’ to ‘char’ [-Wnarrowing]
  276 | };
      | ^
../PeLib/Instruction.cpp:276:1: error: narrowing conversion of ‘-1’ from ‘int’ to ‘char’ [-Wnarrowing]
../PeLib/Instruction.cpp:276:1: error: narrowing conversion of ‘-1’ from ‘int’ to ‘char’ [-Wnarrowing]
../PeLib/Instruction.cpp:276:1: error: narrowing conversion of ‘-1’ from ‘int’ to ‘char’ [-Wnarrowing]
../PeLib/Instruction.cpp:276:1: error: narrowing conversion of ‘-2’ from ‘int’ to ‘char’ [-Wnarrowing]
../PeLib/Instruction.cpp:276:1: error: narrowing conversion of ‘-2’ from ‘int’ to ‘char’ [-Wnarrowing]
../PeLib/Instruction.cpp:276:1: error: narrowing conversion of ‘-2’ from ‘int’ to ‘char’ [-Wnarrowing]

Is there maybe a solution or is it actually not supposed to work on aarch 64 ?

VSCode Integration

I was looking into supporting Oberon+ in VSCode.
Turns out there was a Pascal language file which would be reused and this is now working nicely
for syntax highlighting.

I was thinking it could be possible to support the more advanced language integration present
in VSCode, similar to what is available for Python, C# etc.

I believe this functionality is already present in the Qt IDE you have created.

If the compiler outputs JSON data on syntax check, dot completion, symbol definition, symbol type etc
the integration with VSCode is down to modifying the code examples (TypeScript) existing online to
call out the ObxMC binary in order to feed information into the language server.

Also probably other editors / IDE could be supported in a similar way.

Could you be willing to look into this possibility?

Variable Initialization

In the discussion about the necessity to use begin-end construct and not only a block end like in Julia language I read some arguments that the Begin block is used to separate the data definition (types) from the data flow (manipulation and commands), but in my opinion this is not true.
In Pascal or ADA we can write a program with data definition and initialization before the begin:

ADA -> a:integer:= 1, b:real;
PASCAL -> a:integer = 1, b:real;

In the new Delphi we can write also:
for var i:integer =1 to ...

But in Oberon (also oberon+) we have to write

var
a:integer;

begin
a:=1
...
Then we have data also in the begin block and not only the manipulation of these data.
My question is why the language can´t really make a separation and put all the data (definition, type and initialization) in the same place?

Cannot create build directory '/private/var/folders/...'

During compile it appears that the examples contained in OberonSystem and NAppGUI are unable to compile, yielding rather a message similar to the following :

Cannot create build directory '/private/var/folders/jf/bk8r3yk16_gfl8c0q69h3znr0000gn/T/AppTranslocation/8806BAE5-680C-4212-9A9B-524D5499C4F9/d/build'

I have given both the OberonIDE.App and the mono executable "Full Disk Permission" via Privacy Settings.

I am using the M1 version of the Oberon distribution on an M2 MacBook Air.

Runnig on Windows 10 and detecting Mono installation

Interesting project! I like the practical changed done to the original Oberon version.
A remarkable powerful and simple language. It will be interesting to follow this project.

I was testing on Windows 10 and had to make a small modification for the Mono exe to run:

MonoEngine.cpp:

@@ -199,14 +199,18 @@ void Engine::run(const QString& assembly, const QStringList& args)
     if( workDir.isEmpty() )
         workDir = monoDir;
     d_proc->setWorkingDirectory(workDir);
+#ifdef Q_OS_WIN
+    d_proc->setProgram( QDir(monoDir).absoluteFilePath("mono.exe"));
+#else
     d_proc->setProgram( QDir(monoDir).absoluteFilePath("mono"));
+#endif

I also made a small change in order to detect the Mono installation if available:

ObxIde2.cpp:

@@ -32,6 +32,7 @@
 #include <QStandardPaths>
+#include <QSettings>

 bool Ide::checkEngine(bool withFastasm)
 {
+#ifdef Q_OS_WIN
+    QSettings s("HKEY_LOCAL_MACHINE\\SOFTWARE\\Mono", QSettings::NativeFormat);
+    if (s.contains("SdkInstallRoot")) {
+        d_eng->setMonoDir(s.value("SdkInstallRoot").toString() + "\\bin");
+    } else {
+        d_eng->setMonoDir(QApplication::applicationDirPath() + "\\mono");
+    }
+    return true;
+#else

This will look in the Windows registery for information regarding the installation
and use this if available. This was tested with Mono version 6.12.0.107
Older version will probably work, but are not tested.

In the future I will learn to make proper pull request and save you the hassle
of paste and hand editing.

Wrong assembly for some array of record

There seems to be an issue in Pelib, observable e.g. in Gen4Tests T3VariableDeclarations. Mono reacts with a runtime exception. The issue is not present when generating IL and creating the assembly with ILASM.

Error when compiling any Oberon code on Linux Mint

Following the manual compilation procedure, I get the folowwing error when trying to compile any module of the examples folder:

ObxIDE: ../PeLib/MethodSignature.cpp:122: DotNetPELib::Param* DotNetPELib::MethodSignature::getParam(int, bool) const: Assertion `false' failed.

I've tried other modules from the examples and from test cases and the same problem appears. Note that exporting to C seems to work, I didn't try to compile the generated C code in any way though.

PCALL / RAISE problem

With the same Sqlite wrapper a simple test of pcall/raise seems to fail and return error 127 when run:

module Test

import Sqlite

type DBError = record end

proc tryDB
var e: pointer to DBError
begin
	println("Start")
    if  Sqlite.open("test.db", db) # Sqlite.OK then
    	new(e)
    	raise(e)
    end
    println("Finish")		
end tryDB

var
	db: carray 1 of *Sqlite.DB
	res: pointer to anyrec
	
begin
	println("Begin")
    pcall(res, tryDB)
  	case res of
  	| DBError: println(Sqlite.errmsg(db[0])^)
	end
  	
    if db[0] # nil then
  		Sqlite.close(db[0])
  	end
	println("End")
end Test

Nothing gets printed, so probably something crashed before entering the main function.

Illegal IL Code generation

With my code compiled with INTEGER as INT32 I get this sort of problem:
System.InvalidProgramException: Invalid IL code in TestIntConstant2:StringHash (char[],long): IL_005f: stloc.s 4

at TestIntConstant2.Run () [0x0001c] in /home/slw/Develop/OberonCombined/ObxIDE/ASDLSupport/TestIntConstant2.Mod:29
at OBX.Runtime.pcall (OBX.Command cmd, System.Boolean report) [0x00000] in <886ef6ed1e5e447891bce617b8a05575>:0

with the test program: TestIntConstant2.txt

Issues with Sqlite binding code

Code in Gist

I introduced a procedure strcpy(src: *[]char): PString in Sqlite.obx with a loop to copy the string content as
a assignment gives an error:

error: right side CPOINTER TO CARRAY OF CHAR of assignment is not compatible with left side POINTER TO ARRAY OF CHAR

This can be improved or simplified?

Also there was an issue with accessing the returned error in Test.obx :

  pcall(res, testdb, db)
  case res of
  | Sqlite.TError: printerr(res) raise()
  end

With the error:

error: actual parameter type RECORD not compatible with formal type POINTER TO RECORD

However the code below works and seems to access the pointer?

  pcall(res, testdb, db)
  case res of
  | Sqlite.TError: println(res.str()^) println(db.errmsg()^) raise()
  end

Read from console

This is quite an impressive project. I've only skimmed the documentation since it is not a tutorial, but I'm having a hard time figuring out how to read user input from the console.

When I try to import the In module I get a compilation error.
Is there a read equivalent of println?

In general how exactly do you import "framework" libraries? (Apologies if I missed these instructions elsewhere)

Problems with super calls across Module boundaries

In my application I get an error that the IDE can't find:
PROCEDURE (VAR da:DynamicArrayDesc) Init*(initialSize:LONGINT);
even though I have a
PROCEDURE (da:DynamicArray) Init*(initialSize:LONGINT);
these should be interchangeable/identical/equivalent (depending on the implementation).
I have tried to construct some test modules as follows:

MODULE Test1;

TYPE
Element* = POINTER TO ElementDesc;
ElementDesc* = RECORD
END;
ElementArray* = POINTER TO ARRAY OF Element;

DynamicArray* = POINTER TO DynamicArrayDesc;

(* An adjustable size array of Elements )
DynamicArrayDesc
= RECORD
array*:ElementArray;
length*:LONGINT;
size*:LONGINT;
iterPos*:LONGINT;
(* status:Errors.ErrorRec; *)
END;

PROCEDURE (da:DynamicArray) Init*(initialSize:LONGINT);
BEGIN
da.length := 0;
da.size := initialSize;
da.iterPos := 0;
END Init;

(* PROCEDURE (VAR da:DynamicArrayDesc) Init*(initialSize:LONGINT);
BEGIN
da.length := 0;
da.size := initialSize;
da.iterPos := 0;
END Init;
)
PROCEDURE NewDynamicArray
(initialSize:LONGINT):DynamicArray;
VAR da:DynamicArray;
BEGIN
NEW(da);
IF initialSize <= 8 THEN initialSize := 8 END;
NEW(da.array, initialSize);
da.Init(initialSize);
RETURN da
END NewDynamicArray;

END Test1.

MODULE Test2;
IMPORT Test1;

TYPE
DynamicList* = POINTER TO DynamicListDesc;

DynamicListDesc* = RECORD (Test1.DynamicArrayDesc)

(*
list*: ElementArray;
length: LONGINT;
*)
END;

DynamicStringList* = POINTER TO DynStringListDesc;
DynStringListDesc* = RECORD (DynamicListDesc)
END;

PROCEDURE (dl:DynamicStringList) Init*(initialSize:LONGINT);
BEGIN
(*
dl.length := 0;
dl.size := initialSize;
(* dl.status := Errors.makeOKStatus(); *)
dl.iterPos := 0;
*)
dl.Init^(initialSize)
END Init;

PROCEDURE NewDynamicStringList*(initialSize:LONGINT):DynamicStringList;
VAR dl:DynamicStringList;
BEGIN
NEW(dl);
IF initialSize <= 8 THEN initialSize := 8 END;
NEW(dl.array, initialSize);
dl.Init(initialSize);
RETURN dl
END NewDynamicStringList;

PROCEDURE Run*;
VAR globalDSL:DynamicStringList;
BEGIN
globalDSL := NewDynamicStringList(8);
END Run;

END Test2.

which give the error:
System.MissingMethodException: Method not found: void .DynamicArrayDesc.Init(int)
at Test2.NewDynamicStringList (System.Int32 initialSize) [0x00029] in /home/slw/Develop/OberonCombined/ObxIDE/ASDLSupport/Test2.Mod:35
at Test2.Run () [0x00004] in /home/slw/Develop/OberonCombined/ObxIDE/ASDLSupport/Test2.Mod:42
at OBX.Runtime.pcall (OBX.Command cmd, System.Boolean report) [0x00000] in <886ef6ed1e5e447891bce617b8a05575>:0

Note that it works when the code is put into one Module suggesting some sort of linkage problem.
Note also that the execution does not step into PROCEDURE (dl:DynamicStringList) Init*(initialSize:LONGINT);
when single-stepping in Debug mode.

Program doesn't run (CTRL-R) on IDE built from sources

When trying to run a simple program (Hello World) in a OberonIDE built from sources a error dialog pops-up with the following message:

Cannot find the mono subdirectory under '/home/<user>/Descargas/OberonIde/Build/Oberon

Mono is installed in the system. The compiled program can be executed in the command line with mono Main#.exe and works

Problems with Set Command in IDE

If you do Set Command on one "main program" in your project, and then Set Command to a different "main program" and Run again, it re-executes the first program, even if you Save Project between the executions. You have to exit the IDE and re-start it to be able to run the second program. Even then it sometimes still executes the first program and the only cure seems to be to delete all the .dll in the build directory and fire up the IDE again. I ran into this problem in investigating the problem described in Issue #48 .

"Env" like module - access to shell environment variables?

Hi,

I am trying to figure out the analogue to the "Env" module which allows access to shell environment variables.

For instance, assume in a Linux bash shell that I have "SPECIALVAR=myvalue" and then I start an Oberon program ; how do I access that environment variable from within the program? I don't see it in the Oakwood set nor in either the In or Out modules which can be imported, which only seems to concern itself with Linux' stdin and stdout streams.

Trying to compile a simple example

Hi,

I like the interface very much! However I am trying to determine what I am doing wrong in the compilation step (C compile).

I am using Devuan 4.0 with gcc 10: gcc version 10.2.1 20210110 (Debian 10.2.1-6)

OBXMC version is OBXMC version: 2022-05-15 author: [email protected] license: GPL

coin1.obx:
coin1.txt

using what I believe are the proper options:

./OBXMC -build -out=coin1 -oak -c coin1.obx

I get when trying "cc -O2 --std=c99 *.c -lm" the following:

/usr/bin/ld: /tmp/cclgx6bM.o:(.bss+0x10): multiple definition of OBX$defaultException'; /tmp/ccq9ppAM.o:(.bss+0x28): first defined here /usr/bin/ld: /tmp/cclgx6bM.o:(.bss+0x18): multiple definition of OBX$Anyrec$class$'; /tmp/ccq9ppAM.o:(.bss+0x30): first defined here
/usr/bin/ld: /tmp/ccLRsJ8M.o:(.bss+0x8): multiple definition of OBX$defaultException'; /tmp/ccq9ppAM.o:(.bss+0x28): first defined here /usr/bin/ld: /tmp/ccLRsJ8M.o:(.bss+0x10): multiple definition of OBX$Anyrec$class$'; /tmp/ccq9ppAM.o:(.bss+0x30): first defined here
/usr/bin/ld: /tmp/ccMhCZYL.o:(.bss+0x0): multiple definition of OBX$defaultException'; /tmp/ccq9ppAM.o:(.bss+0x28): first defined here /usr/bin/ld: /tmp/ccMhCZYL.o:(.bss+0x8): multiple definition of OBX$Anyrec$class$'; /tmp/ccq9ppAM.o:(.bss+0x30): first defined here
/usr/bin/ld: /tmp/cck4UAbM.o:(.bss+0x0): multiple definition of OBX$defaultException'; /tmp/ccq9ppAM.o:(.bss+0x28): first defined here /usr/bin/ld: /tmp/cck4UAbM.o:(.bss+0x8): multiple definition of OBX$Anyrec$class$'; /tmp/ccq9ppAM.o:(.bss+0x30): first defined here
/usr/bin/ld: /tmp/ccrxtc5O.o:(.bss+0x0): multiple definition of OBX$defaultException'; /tmp/ccq9ppAM.o:(.bss+0x28): first defined here /usr/bin/ld: /tmp/ccrxtc5O.o:(.bss+0x8): multiple definition of OBX$Anyrec$class$'; /tmp/ccq9ppAM.o:(.bss+0x30): first defined here
/usr/bin/ld: /tmp/ccjS7NmN.o:(.bss+0x0): multiple definition of OBX$defaultException'; /tmp/ccq9ppAM.o:(.bss+0x28): first defined here /usr/bin/ld: /tmp/ccjS7NmN.o:(.bss+0x8): multiple definition of OBX$Anyrec$class$'; /tmp/ccq9ppAM.o:(.bss+0x30): first defined here
/usr/bin/ld: /tmp/cc4lNAFN.o:(.data.rel.local+0x0): multiple definition of OBX$defaultException'; /tmp/ccq9ppAM.o:(.bss+0x28): first defined here /usr/bin/ld: /tmp/cc4lNAFN.o:(.bss+0x0): multiple definition of OBX$Anyrec$class$'; /tmp/ccq9ppAM.o:(.bss+0x30): first defined here
/usr/bin/ld: /tmp/cchy0nsP.o:(.bss+0x0): multiple definition of OBX$defaultException'; /tmp/ccq9ppAM.o:(.bss+0x28): first defined here /usr/bin/ld: /tmp/cchy0nsP.o:(.bss+0x8): multiple definition of OBX$Anyrec$class$'; /tmp/ccq9ppAM.o:(.bss+0x30): first defined here
/usr/bin/ld: /tmp/ccdPOokL.o:(.bss+0x0): multiple definition of OBX$defaultException'; /tmp/ccq9ppAM.o:(.bss+0x28): first defined here /usr/bin/ld: /tmp/ccdPOokL.o:(.bss+0x8): multiple definition of OBX$Anyrec$class$'; /tmp/ccq9ppAM.o:(.bss+0x30): first defined here
/usr/bin/ld: /tmp/cclGMvoP.o:(.bss+0x8): multiple definition of OBX$defaultException'; /tmp/ccq9ppAM.o:(.bss+0x28): first defined here /usr/bin/ld: /tmp/cclGMvoP.o:(.bss+0x10): multiple definition of OBX$Anyrec$class$'; /tmp/ccq9ppAM.o:(.bss+0x30): first defined here
collect2: error: ld returned 1 exit status

Basic Types and some questions

First thank you for the great work with oberon+. I am learning your implementation and congratulations.
If possible I need some clarifications.
In the documentation (section 6.1) there are some types declared (INT8,...) but when a try to use these types in the program the compiler emit a error. These types are not implemented in the compiler or I need to import some additional module?
Another question is about the println procedure. There is some example in how to use it with integers, real, etc...
I don´t know if you look at the XDS-Modula-2 compiler, but there are some very cool procedure (printf like c) that can be used in the oberon+.
In pascal I really like the generic writeln and readln. You have println there is a readln equivalent?
You have plan to introduce Complex Number, Complex Math in the language?
And the last question (sorry for the long post) there is a way to call a extern command line program (for example gnuplot) in windows environment?
Thank you.

License does not Allow Closed Source Development

GCC and other compiler projects tend to have a GPL exception that states that the stdlib of the language is not under GPL. stdlib tends to be linked to the generated binaries/generated_code. Without the possibility to use the compiler for closed source development the compiler will become useless for freelancers like me, who have to deliver code that my clients can use as a closed source project. For example, software components under the the GNU Lesser General License are usable by me, because the GNU Lesser General License allows my clients' projects to stay closed source and I only have to publish my modifications to the components that others offered as open source software.

I am not a hypocrite with my such wishes, because the most restrictive license that I use for my own, personal, projects is BSD license.

Thank You for reading my comment.

Build failure FreeBSD on PowerPC64

I encounter the error below when compiling ObnlcMain.cpp:

#    define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text)))
                                                      ^
ObnlcMain.cpp:468:17: error: no type named 'FileGroups' in 'Obx::Model'
    Obx::Model::FileGroups fgs;
    ~~~~~~~~~~~~^
ObnlcMain.cpp:469:24: error: no member named 'FileGroup' in 'Obx::Model'
    fgs << Obx::Model::FileGroup();
           ~~~~~~~~~~~~^
53 warnings and 4 errors generated.

Out.String goes past 0x mark

The following code:

module TestDate
import Out
var
    a : [32]char
begin 
    a := "abc123"
    Out.String(a) Out.Ln()
    a[0] := 0x
    Out.String(a) Out.Ln()
end TestDate

Outputs:

Starting application...

abc123
bc123

The application finished with code 0

This is with the Mono backend.

System.DllNotFoundException: SDL2.dll on macOS M2 MacBook Air

When attempting to run the OberonSystem example the following exception is encountered :


System.DllNotFoundException: SDL2.dll
  at (wrapper managed-to-native) SDL.GetVersion(SDL/version*)
  at ObSdl.createRasterBuffer (System.Int32 length) [0x00008] in <c4d834eb88f245ae83ac2daea9ff7bff>:0 
  at ObsX.createRasterBuffer (System.Int32 length) [0x00000] in <c77eb3d44146414842b1c191f03b69c1>:0 
  at Display.beg?n () [0x000cc] in <ad61697745564c8249b810549aec1afa>:0 
  at Oberon.beg?n () [0x00022] in <3977234fb0c845dc6d9b741e07708547>:0 
  at OBX.Runtime.pcall (OBX.Command cmd, System.Boolean report) [0x00000] in <ff1ddc7e08a04893984d4f2c743f28e1>:0 
System.DllNotFoundException: SDL2.dll
  at (wrapper managed-to-native) SDL.WaitEventTimeout(SDL/Event*,int)
  at ObSdl.processEvents (System.Int32 sleep) [0x0002a] in <c4d834eb88f245ae83ac2daea9ff7bff>:0 
  at ObSdl.getState (ObSdl+InputState state) [0x00000] in <c4d834eb88f245ae83ac2daea9ff7bff>:0 
  at ObsX.getState (ObSdl+InputState state) [0x00000] in <c77eb3d44146414842b1c191f03b69c1>:0 
  at Input.Mouse (System.Int32& keys, System.Int32& x, System.Int32& y) [0x00006] in <62568a5358564a0ea09ab3bb42bed36f>:0 
  at Oberon.Loop () [0x00020] in <3977234fb0c845dc6d9b741e07708547>:0 
  at OBX.Runtime.pcall (OBX.Command cmd, System.Boolean report) [0x00000] in <ff1ddc7e08a04893984d4f2c743f28e1>:0 

The application finished with code 0```

OBX IDE under OpenBSD 7.0

Hi,

thanks for writing the OBX IDE. I have built the IDE under OpenBSD 7.0 (amd64 and arm64 platforms). But I've only had partial success. I proceeded as follows:

  • Download packages and populate build directory as per README.md.
  • Install Qt5 and Mono packages "pkg_add -v mono qt5"
  • Go to "Oberon" directory: Execute "qmake-qt5 OBXIDE2.pro"
  • (arm64 platform only) edit Makefile to add "-fsigned-char" to C and C++ compiler flags
  • Execute "gmake CC=clang CXX=clang++"

I can the start the IDE. Editing code works (I only tried a simple "hello, world" module. Attempting to compile or run results in a crash and a core dump. Exporting to IL and C works, with these caveats:

  • I can compile the C code by following the instructions in build.txt and substituting gcc with clang and adding compiler flags.
  • For IL, the build directory contains run.sh and build.sh. These contain references to "./ilasm" and "./mono". Replacing these by plain "ilasm" and "mono" makes these scripts work.

Again, many thanks!

Problems with type extension

The following small excerpt illustrates the problem:

MODULE Test;

CONST NullInteger* = MIN(LONGINT);

TYPE
Element* = POINTER TO ElementDesc;
ElementDesc* = RECORD
END;

IntElement* = POINTER TO IntElementDesc;
IntElementDesc* = RECORD (ElementDesc)
  value*:LONGINT
END;

VAR
SentinelElement*:Element;
SentinelIntElement*:IntElement;

PROCEDURE (le:Element) InitElement*();
BEGIN
END InitElement;

PROCEDURE NewElement*():Element;
VAR el:Element;
BEGIN
NEW(el);
el.InitElement();
RETURN el
END NewElement;

PROCEDURE (le:IntElement) InitIntElement*(initialValue:LONGINT);
BEGIN
le.InitElement();
le.value := initialValue
END InitIntElement;

PROCEDURE NewIntElement*(initialValue:LONGINT):IntElement;
VAR le:IntElement;
BEGIN
NEW(le);
le.InitIntElement(initialValue);
RETURN le
END NewIntElement;

BEGIN
SentinelElement := NewElement();
SentinelIntElement := NewIntElement(NullInteger)
END Test.

The compiler complains that the receiver (le:Element) must be of record or pointer to record type.
This code compiles correctly on several different oberon versions.
I have been using the Linz system for some time but have hit a limit of modules and imports with my large and growing software system so I thought I would try your system, but failed at the first hurdle. Please help

Handling strings from external sources

When experimenting with a wrapper of Sqlite I was wondering if there was a cleaner way to handle strings returned from functions in the wrapped dll.

Wrapper:

definition Sqlite [extern 'C', dll 'libsqlite3-0']
	type
	    DB = cstruct end
        
    const
    	OK = 0 		// Successful result
    	ERROR = 1	// Generic error
    
	proc libversion_number(): integer [alias 'sqlite3_libversion_number']
	proc libversion(): *[]char [alias 'sqlite3_libversion']
	proc open(filename: *[]char; dbref: *[]*DB): integer [alias 'sqlite3_open']
	proc close(db: *DB) [alias 'sqlite3_close']
	proc errmsg(db: *DB): *[]char [alias 'sqlite3_errmsg']	
end Sqlite

Test code:

module Test

import Sqlite

proc errmsg(msg : *[]char)
var
	buf : array 256 of char
	i : integer
begin
	while (msg[i] # 0x) & (i < 256) do
		buf[i] := msg[i]
		inc(i)
	end 
    buf[i] := 0x
    println(buf)	
end errmsg

var
	db: carray 1 of *Sqlite.DB
begin
    println(Sqlite.libversion_number())
    errmsg(Sqlite.libversion())
    
    if  Sqlite.open("test.db", db) # Sqlite.OK then
    	errmsg(Sqlite.errmsg(db[0]))
    	Sqlite.close(db[0])
    	halt(1)
    end	
  	Sqlite.close(db[0])
	println("Done")
end Test

In order to print the error message a separate procedure print was introduced.
Obviously the compiler does not know if the returned array of char is expected to be zero terminated,
but I expected an array copy buf := msg to work. Is there something I am missing here?

UTF-8 compiler switch?

UTF-8 is now everywhere and even the recent Windows 10 versions support this: Windows UTF8

UTF-16 is I believe only used by part of the legacy the Windows API.

Currently there is no easy way to use string constants with external libraries using UTF-8.
Should we perhaps have a compiler switch which interprets strings as UTF-8?

Further development of Oberon+

Dear Author,

I'm looking for an Oberon for Windows-64 that supports natively complex numbers and debugging. Is there any chance that Oberon+ will support the necessary features in future?

I have many projects written in XDS-Oberon for my computational physics tasks. If the Oberon+ would support the necessary features, I could convert them to Oberon+ and contribute in this way in testing of the compiler.

Sincerely yours,
GH.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.