Oxygen Basic

Programming => Bugs & Feature Requests => Topic started by: pber on July 02, 2014, 08:36:44 AM

Title: scope
Post by: pber on July 02, 2014, 08:36:44 AM
In the example c2 does not see variable scoped.
Don't undersand because not 100.

Code: [Select]
class Compiler
    method constructor(string src)
        sys p= compile src: call p
    end method
end class

int glob= 9
scope
    int scoped= 99

    new Compiler c1("glob++")
    new Compiler c2("scoped++")

    print glob cr   ' 10
    print scoped cr ' 99
end scope
Title: Re: scope
Post by: Peter on July 02, 2014, 09:56:25 AM
Hello Paolo,

Code: [Select]
class Compiler
    method constructor(string src)
        sys p= compile src: call p
    end method
end class

int glob= 9
'scope
    int scoped=99

    new Compiler c1("glob++")
    new Compiler c2("scoped++")

    print glob    ' 10
    print scoped  ' 100
'end scope
Title: Re: scope
Post by: pber on July 02, 2014, 10:01:22 AM
Hi Peter,
as you noticed scope is responsible.
But why?
It seems to me that the instance c2 should has rights
to see what is scoped where it works and/or where it is created.

isn't it?
Title: Re: scope
Post by: pber on July 02, 2014, 10:03:42 AM
oops... was not you serious? :-)
Title: Re: scope
Post by: Peter on July 02, 2014, 10:25:37 AM
Quote
oops... was not you serious?

Sorry Paolo, only little bit!  ;D
Title: Re: scope
Post by: Peter on July 02, 2014, 10:30:52 AM
Here, another bad thing.

Code: [Select]
indexbase 0

Class Exponent
    single Tab[20]
   
    Method List(single a)
        static sys i
        Tab[i] = a
        i +=1
    End Method

    Method Show(sys a) as single
        Return Tab[a]
    End Method
   
End Class

Exponent ex

a= pow(5,0) '1
ex.List a

a= pow(5,1) '5
ex.List a

a= pow(5,2) '25
ex.List a

a= pow(5,-2) '0,04
ex.List a

a= pow(-2,-3) '-0.125
ex.List a

For i=0 to 4
    e = ex.show i
    print e
Next
Title: Re: scope
Post by: Charles Pegge on July 02, 2014, 11:52:48 AM
Hi Paolo,

Interesting case!

The dynamic compiler cannot see the symbol scoped, It is no longer valid at the end of static compiling, since it has fallen out of scope. (The compilation fails, and the binary is set to a ret instruction.)

Scoping with dynamic compiling is a contingency I have not anticipated.

The dynamic compiler has access to all global variables which are valid at the end of static (main) compiling, and also the local/static variables in the procedure, defined above the position where dynamic compiling takes place.

Code: [Select]
class Compiler
    method constructor(string src)
        sys p= compile src
        er=error
        if er then
          print "Dynamic compiler " + er + src
        else
          call p
        end if
    end method
end class

int glob= 9
scope
    int scoped= 99
    new Compiler c1("glob++")
    new Compiler c2("scoped++")
    print glob    ' 10
    print scoped  ' 99
end scope
Title: Re: scope
Post by: Charles Pegge on July 02, 2014, 12:07:33 PM

Hi Peter,

To avoid precision errors showing with floats, you can limit the number of decimal places:

print str(e,6)

Any other bads?
Title: Re: scope
Post by: pber on July 02, 2014, 01:51:29 PM
The dynamic compiler cannot see the symbol scoped, It is no longer valid at the end of static compiling, since it has fallen out of scope. (The compilation fails, and the binary is set to a ret instruction.)

Clear.
I'll keep more careful, thanks.
Title: Re: scope
Post by: pber on July 02, 2014, 01:52:08 PM
Quote
oops... was not you serious?

Sorry Paolo, only little bit!  ;D

 :)
Title: Re: scope
Post by: pber on July 08, 2014, 08:47:21 AM
Charles: this program works with exo2.exe,
but not with Oxygen.dll nor RTL32.inc.

In latter 2 use cases dynamically compiled code
does not see the global mySys.

Code: [Select]
'#file       "xfoo.exe"
'$filename   "xfoo.exe"
'include     "f:\apps\basic\OxygenBasic_2\inc\RTL32.inc"

include once "console.inc"

class CodeBlock
   
    int compiled
    bstring src
    sys p
    string err
   
    method constructor(string src0)
        init src0
    end method

    method destructor()
        frees src
        if compiled then freememory p
    end method
   
    method init(bstring src0)
        this.src= src0
        'p_compile
    end method

    method p_compile()
        if not compiled
            p= compile src
            err= error
        end if
        if err then
            print "error " err cr
        else
            compiled=-1
        end if
    end method
   
    method run()
        p_compile
        if not this.err then
            call p
        end if
    end method
end class

class System
    int state
    method m()
        print "System::m()" cr
    end method
    method constructor()
    end method
end class

new System mySys

new CodeBlock cb("mySys.state=123")
cb.run
print mySys.state cr

new CodeBlock cb("mySys.m")
cb.run

waitkey

.
Title: Re: scope
Post by: Charles Pegge on July 08, 2014, 12:07:38 PM
Hi Paolo,

I am not sure why it works at all. mysys is global but does not exist, lexically speaking, until it is created with the line: new system mysys.. So the compiler method will not see it.







Title: Re: scope
Post by: pber on July 08, 2014, 12:34:48 PM
Hi Charles,

This is one of my attempts to work on the issue:
Code: [Select]
dim mySys as System*
new System mySys
...but it does not help.

Maybe there is some scope-related
behaviors I do not understand?
Title: Re: scope
Post by: Charles Pegge on July 08, 2014, 12:52:55 PM
We may be going up the wrong path here. If you can give me a brief overview of what you want to achieve, I may be able to find better matching solutions.
Title: Re: scope
Post by: pber on July 08, 2014, 02:47:20 PM
Thanks Charles,
but I argue I'm wrong because I'm not clear.

running programs with exo2.exe do not give me the problem.

running programs in exe form gives me the problem,
(both exe forms: Oxygen.dll and RTL'ed)

Which problem:
dynamically compiled code does not see global objects.

Your ... (deleted?) suggestion still suffers the problem.
Title: Re: scope
Post by: Charles Pegge on July 08, 2014, 02:52:01 PM
One potentially useful construct is a class that can be used without creating objects:

Such a class may contain methods and static variables, and these will be accessible, invoking the class by name:

Code: [Select]
class act
  method greet(string n) as string
  return "helo "+n
  end method
  method depart(string n) as string
  return "bye "+n
  end method
end class

class util
  method compile(string src) as sys
  sys a=compile src
  er=error
  if er then
    print er+src
    return 0
  else
    return a
  end if
  end method
end class

a=util.compile quote """ print act.greet "World" """
if a then call a

freememory a

PS:
The problem with the binary file (even when oxygen.dll is available) is that it does not carry any static symbolic data. So the dynamic compiler has no information about the classes.

Whereas under JIT compiling conditions, with gxo2/exo2, the static symbol data from primary compilation is retained, and made accessible to the dynamic compiler.
Title: Re: scope
Post by: pber on July 08, 2014, 03:21:36 PM
Thanks again Charles.
Sorry for my annoying ignorance of your architecture.

Now I see if I want to make use of Oxygen's JIT compiler from a binary
I have to bind application's objects to newly compiled code.
For functions and variables using native datatypes no problem.

But types and classes?
Do their structure get forget, as well as of all other static symbols, or retained?
Title: Re: scope
Post by: Charles Pegge on July 08, 2014, 03:47:18 PM
Yes, structures are also forgotten.

But it may be possible to modify Oxygen to retain selected symbols on-demand, for dynamic compiling purposes. I will need to think it through.
Title: Re: scope
Post by: Charles Pegge on July 09, 2014, 04:44:53 AM
Paolo,

I have updated Oxygen to pass static symbol records to the binary:

http://www.oxygenbasic.org/o2zips/Oxygen.zip

This will now work:
Code: [Select]
#file       "t.exe"

class act
  method greet(string n) as string
  return "helo "+n
  end method
  method depart(string n) as string
  return "bye "+n
  end method
end class

class util
  method compile(string src) as sys
  sys a=compile src
  er=error
  if er then
    print er+src
    return 0
  else
    return a
  end if
  end method
end class

a=util.compile quote """ print act.greet "World" """
if a then call a

freememory a

Also with an instantiation of Act

Act AA

Code: [Select]
#file       "t.exe"

class act
  method greet(string n) as string
  return "helo "+n
  end method
  method depart(string n) as string
  return "bye "+n
  end method
end class

act AA

class util
  method compile(string src) as sys
  sys a=compile src
  er=error
  if er then
    print er+src
    return 0
  else
    return a
  end if
  end method
end class

a=util.compile quote """ print AA.greet "World" """
if a then call a

freememory a

Title: Re: scope
Post by: pber on July 09, 2014, 11:13:44 AM
GREAT! Many thanks Charles.

...well: I didn't post immediately,
I wanted to try to see my program run as I expected...
I'm very frustrating on telling that no, it didn't.

Can I store the result of compile in an instance var,
for lately execute call on it?

I tryied to transform class util from your 2nd example.
Executing run causes a crash.

Code: [Select]
class util2
    sys a
    method compile(string src)
      a=compile src
      er=error
      if er then
        print er+src
      end if
  end method
  method run()
    call a
  end method
end class
Title: Re: scope
Post by: Charles Pegge on July 09, 2014, 12:55:34 PM
The solution is rather obscure, but simple. When the dynamically compiled code uses strings, it requires string management from the parent function. To trigger string management.the parent function (run) must include a string, even if the string is never used.

This is new territory!

  method run()
  string v
  call a
  end method

Code: [Select]
class util2
    sys a
    method compile(string src) as sys
      a=compile src
      er=error
      if er then
        print er+src
      end if
      return a
  end method
  method run()
  string v
  call a
  end method
end class

util2 u
u.compile quote """ print "ok" 123 """
u.run
Title: Re: scope
Post by: pber on July 09, 2014, 01:23:02 PM
It makes me simply happy.
Thanks Charles.