• Welcome to Jose's Read Only Forum 2023.
 

Modules for O2

Started by Charles Pegge, August 16, 2022, 07:08:06 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Charles Pegge

Quote from: Theo Gottwald on August 07, 2022, 08:04:42 PM
Charles, the good thing is that we have the direct line to you so small wishes can get full filled.
It was never easy with PB to really get individual wishes fullfilled.
I remember that i asked for "Modules" and got "OBJECTS".
Long Years ago. :-)

I think modules could be very useful for bringing together pieces of code that have been developed separately. It avoids the need to alter conflicting global variables, and provides a level of organization above objects.

update:


General module structure
------------------------
module
  interface 'code globally visible
  ...
  inner 'code visible only inside the module
    ...
  end inner
end module


I've posted another update to support modules :)
https://github.com/Charles-Pegge/OxygenBasic/blob/master/OxygenBasic050P1.zip




Zlatko Vid

Charles
what is exactly purpose of this modules ?
I am asking because i don't need it  and looks to me like bloating compiler .
But maybe i am wrong ?

tnx

ps .what is latest version without them ?

Zlatko Vid

ps ...nothing to worry
i upload A043, SC 029 and SC 040 to my github
just to prevent lost of version even is still on sourceForge

all best

Charles Pegge

#3
Modules, being based on  existing constructs,  only occupy 0.005% of the compiler. So no bloating here :)

Large programs can be split into several modules for redeployment in other projects, without rewriting the code.

A DLL is a kind of module, but this allows multiple modules to be compiled from source into a single binary.

Zlatko Vid


Nicola_Piano

Hi Charles,
I find it really interesting to use the module.
Is there an example in version 050p1? If so, what is it called?

... thanks again for your work.

Cheers

Charles Pegge

#6
Hi Nicola,

I have not produced any examples yet. It is quite hard to demonstrate the potential of modules on a small scale.

As I see it, modules are placed at the top of the language structural hierarchy:

program
  module
    class
      procedure
        subroutine
          block
            statement
              expression
                instruction


Here is on example linking a visible function to an internal function:

========
module X
========

interface
'
!* fi(int a) as int
'
inner
  '
  function ff(int a) as int
    print "ok " a
  end function
  '
  'links
  @fi=@ff
  '
end inner
'
end module
'
fi(3)



Another example demonstrating how to retrofit a module around existing code, exposing only a few functions:

module
  sys p1,p2,p3,p4
  inner
    ============
    uses console
    ============
    p1=@input
    p2=@output
    p3=@cls
    p4=@getkey
  end inner
  ! input() as string at p1
  ! output(string s)  at p2
  ! cls  ()           at p3
  ! pause() as int    at p4
end module


Nicola_Piano

Charles,
it's really interesting. I tried and saw that you can have different outputs and inputs (console or win) with this module.
(Did I get it right?  :))


module
  sys p1,p2,p3,p4
  inner
    ============
    uses console
    ============
    p1=@input
    p2=@output
    p3=@cls
    p4=@getkey
  end inner
  ! input() as string at p1
  ! output(string s)  at p2
  ! cls  ()           at p3
  ! pause() as int    at p4
end module

string a=input  'input from console
output a        'print in console
print a        'print in wind
output a      'print in console
pause 'wait a key in console.

Zlatko Vid

well it looks like mini sub - program

Nicola_Piano

Hi
Rather than a sub, it creates an environment that can be interfaced with another environment.
Or am I wrong?

Cheers

Charles Pegge

#10
Yes, with a module you can create an interface for common use and hide the rest of the code, ensuring there are no name conflicts.

An alternative to using inner, would be to put console. inside its own namespace, which would enable access to all parts without a specific interface.

I have just released a new version of o2 with nested namespaces, and one bug fix :)
https://github.com/Charles-Pegge/OxygenBasic/blob/master/OxygenBasic050P2.zip


'modules and namespaces
module console
  namespace cn
  uses console
  end namespace
end module

'reopen the console namespace
'no need for namespace prefixes
namespace cn
print "ok1"
end namespace

'use namesoace prefixes
cn::print "ok2"
cn::getkey

Theo Gottwald

"Nested Namespaces"?
How is it implemented?

Does it mean, that a MODULE "GRAPHICS" could have the Sub-MODULES "SCREENPRINT" and "OUTPUT"?
Now there should be a way that the Sub-Modules can access Variables from their Father Modules.
Then this would be interesting as you could make different Modules with the same name Sub-Modules.

Now Let me ask for "INITIALIZATION" and "DESTRUCTION". This Feature is actually in PB Objects available.
Its often useful for Subprogrammes to have a "One Time Initialization" and have some "De-Allocation" when the Program ends.
Would it make sense to implement this also for MODULES?

Secondly:
In my PB Programming i often have the Problem that during Initialization of Subprogrammes, i need also to initialize Global Variables.
This would also be something that would be interesting if i had inside the MODULE the Options:
1. "MGLOBAL" ..."MENDGLOBAL"
where all the stuff between will be added as "Global declaration". As Alternative to STATIC.
2. "MMAIN" ... "MENDMAIN" where all the stuff between will be added inside the MAIN Procedure at the start of this.

These are to some degree  pure Text Processing Options (You take all the stuff in between and move it behind the "GLOBAL or MAIN-Section"
and therefore can easily be added to the MODULE Definition.

Third:
Question, Can Sub-Modules in some way access Variables from their "Father Modules" where they are inside?
If so there could also be a need to treat these as "Global" to these Sub-Modules. Which sounds interesting.


Charles Pegge

#12
Quote
Does it mean, that a MODULE "GRAPHICS" could have the Sub-MODULES "SCREENPRINT" and "OUTPUT"?
Now there should be a way that the Sub-Modules can access Variables from their Father Modules.
Then this would be interesting as you could make different Modules with the same name Sub-Modules.

With nested namespaces it works the other way round: mothers can access their children. Also, different mothers may name their children the same, but they will be completely different children.

Currently,  modules are purely conceptual, and just provide a notional framework.


namespace motherX
  namespace childA
    ...
  end namespace
  namespace childB
    ...
  end namespace
  ...
end namespace

namespace motherY
  namespace childA
    ...
  end namespace
  namespace childB
    ...
  end namespace
  ...
end namespace



Quote
Now Let me ask for "INITIALIZATION" and "DESTRUCTION". This Feature is actually in PB Objects available.
Its often useful for Subprogrammes to have a "One Time Initialization" and have some "De-Allocation" when the Program ends.
Would it make sense to implement this also for MODULES?

Quote
Secondly:
In my PB Programming i often have the Problem that during Initialization of Subprogrammes, i need also to initialize Global Variables.
This would also be something that would be interesting if i had inside the MODULE the Options:
1. "MGLOBAL" ..."MENDGLOBAL"
where all the stuff between will be added as "Global declaration". As Alternative to STATIC.
2. "MMAIN" ... "MENDMAIN" where all the stuff between will be added inside the MAIN Procedure at the start of this.

These are to some degree  pure Text Processing Options (You take all the stuff in between and move it behind the "GLOBAL or MAIN-Section"
and therefore can easily be added to the MODULE Definition.


namespaced global code is executed inline as any other global code, so initializing is simply a matter of assigning values. If destructors are required then you can provide destructor procedures for each namespace. Mother destructors can invoke their child destructors, so it is easy to cascade the destruction process.


namespace motherX
  namespace childA
    'init
    int a=100
    '
    sub destructor()
      ...
    end sub
    '
  end namespace
  '
  namespace childB
    'init
    int a=200
    '
    sub destructor()
      a=0
    end sub
    '
  end namespace
  '
  'init
  int b=1000
  '
  ...
  '
  sub destructor()
    b=0
    namespace childA
    destructor()
    end namespace
    namespace childB
    destructor()
    end namespace
  end sub
end namespace




Theo Gottwald

#13
The way that you can access everything "down the line" sounds good.
From the implementation you say its a "textual implementation"?
Thats the fastest way to do it.

Then a child can not find out who is his mother?
Maybe you can find a way around this using some sort of "ME." Like in Powebasic?

For example:
LOCAL XY AS ??
XY=MyMother()

Then I could access variables from my parent using
A=XY.Varname

Should be easy doing if its textual implemented.
While Encapsulation is necessary to build "Building Blocks" for later use (reusable code),
there are often use cases where you need to break the hull.
For example if you want to make child-constructs that are universal for different parents.

Possibly a Variable could even be declared as
LOCAL A as Mother
Then you can simply use it as
A.Varname
to access Parents Variables.


Charles Pegge

#14
Hi Theo,

re: namespace

I wanted to keep modules and namespaces as separate concepts. A module may or may not use namespaces.

namespace is widely understood,  but the C++ ;; notation does not sit well with Basic, I agree. We could use double-dots instead. Unfortunately, single-dots would be too confusing when we have both nested namespaces and nested UDT members!

With nested namespaces, it becomes necessary to distinguish absolute names from relative names .  This can be done by prefixing the relative child names with double-dots.

It would also be possible to reference parental symbols using a triple-dot prefix.

However, to ensure modular independence, I still think it is a design error for a nested child to know anything about its parental symbols. If any mode-setting or any i/o is required, the parent should be the actor.