Oxygen Basic
Programming => Bugs & Feature Requests => Topic started 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.
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
-
Hello Paolo,
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
-
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?
-
oops... was not you serious? :-)
-
oops... was not you serious?
Sorry Paolo, only little bit! ;D
-
Here, another bad thing.
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
-
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.
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
-
Hi Peter,
To avoid precision errors showing with floats, you can limit the number of decimal places:
print str(e,6)
Any other bads?
-
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.
-
oops... was not you serious?
Sorry Paolo, only little bit! ;D
:)
-
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.
'#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
.
-
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.
-
Hi Charles,
This is one of my attempts to work on the issue:
dim mySys as System*
new System mySys
...but it does not help.
Maybe there is some scope-related
behaviors I do not understand?
-
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.
-
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.
-
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:
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.
-
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?
-
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.
-
Paolo,
I have updated Oxygen to pass static symbol records to the binary:
http://www.oxygenbasic.org/o2zips/Oxygen.zip
This will now work:
#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
#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
-
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.
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
-
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
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
-
It makes me simply happy.
Thanks Charles.