calling math functions at run time

  • Thread starter Thread starter Franky
  • Start date Start date
F

Franky

I don't know how to ask this so that someone will not misread it but here
goes.

At run time I want to be able to evaluate functions from the Math library,
but at design time I do not know what functions will be needed.

I know I can do

If Userinput = "SINE" Then zz = Sin(whatever)

but what I want to do is zz= MyMappingToMath(userinput)

e.g
Suppose the user inputs SINE(30) at run time
Is there some way I can get the value of SINE(30) if I made no special
provisions for SINE at design time?

Thanks
 
If I understand you correctly,

you could:
1. Create functions and/or operator overloads that define your
syntax,
2. Let the user provide the code and compile it to memory on the fly,

I mean the Activator.CreateInstance stuff and so on
(this requires some little familiarity with reflection, CodeDOM,
delegates ... )

http://www.thescripts.com/forum/thread348196.html
....

Franky ha scritto:
 
Thanks, I used that but now I'm wondering if I can actually interpret a
small Basic program


Thanks, just what I needed
 
I looked at that site and need to study it more but do I understand
correctly that I could, at run time, actually run a little Basic program
inputted by the user?


Thanks a lot
 
I'm looking for so doc on MSScriptControl.ScriptControlClass but do not see
it in Help.

How do I learn what the properties and methods are?

Thanks again
 
RIght you can compile any source program. You could define another
language if you wanted to :) You need a couple days digging into the
codedom and looking at the samples on the internet. VB.NET makes it
very "easy", after all ...

Franky ha scritto:
 
I'll look into it. I see much to read about it.

BTW - maybe you know

Is there any documentation about MSScriptControl.ScriptControlClass

I can't find out what properties and methods are available.

Do you know where they are documented.


Thanks for telling me about codedom
 
Hi Franky ,

I am not clear if you are realizing that Cor and I have been suggesting
2 distinct approaches to your problem (I am not talking about
MSScriptControl)...

They are different. MSScriptControl may be quicker to implement while
the other one has infinite flexibility. The choice is up to you ...

tommaso

Franky ha scritto:
 
Thanks for all the interest and help. I'm pursuing both approaches for two
different uses.

I've copied what Cor suggested to use for expression evaluation, and that
works on simple expressions - but I can't get Sin(PI/4) to work. I have been
unable to find any info on the control so I really can't go any further with
that.

I plan to use your suggestion for running BASIC-like programs. I've found
and copied much from the Internet and need to read it. In the book MS VB.Net
Programmers cookbook I found a example that I will use as a starting
example.

I wish I could find info about the control/class because I believe I could
easily finish that project and be done with it.


Thanks again
 
In regard to evaluating an expression, in contrast to compiling/running
Basic. I've read this.

Using the .NET framework compilation capabilities seem to be the most
obvious way to make an evaluator. However, in practice this technique has a
nasty side effect, it looks like it creates a new DLL in memory each time
you evaluate your function and it seems nearly impossible to unload the DLL.

I'm pretty sure he is referenceing a CodeProvider with GenerateInMemory =
true.

Do you agree with that there is such a problem now.


thanks

With regards to compiling and running Basic using a temp file, that appears
to be working fine. In fact, as a test, I've copied the complete Designer
generated code for my About folder and pasted it in as the Basic program and
it woks fine. Thanks for that
 
Franky ha scritto:
In regard to evaluating an expression, in contrast to compiling/running
Basic. I've read this.

Using the .NET framework compilation capabilities seem to be the most
obvious way to make an evaluator. However, in practice this technique has a
nasty side effect, it looks like it creates a new DLL in memory each time
you evaluate your function and it seems nearly impossible to unload the DLL.

I'm pretty sure he is referenceing a CodeProvider with GenerateInMemory =
true.

Do you agree with that there is such a problem now.

Hi Franky ,

I think this technique it's quite powerful and general. And it's fast.
I have never experienced any serious problem, in all occasions
I have used it. It takes some time to make a good use of it
and to write a friend way to interface with the user, but you have
all the possible flexibility...

It goes like :

Dim VBCodeProvider As New VBCodeProvider
Me.CompilerParameters = New CompilerParameters
With CompilerParameters
.IncludeDebugInformation = False
.GenerateInMemory = True
.GenerateExecutable = False
...

'Add here various references ...
..ReferencedAssemblies.Add(Reference) ...
End With
...

CompilerResults =
G_MyVBCodeProvider.CompileAssemblyFromSource(Me.CompilerParameters,
someCode)

....handle errors ...


'create instance if ok

Activator.CreateInstance(TipoClasse)


[ sometimes, in general contexts, you may need
System.Delegate.CreateDelegate for invocation ]

Let me know if you experience particular problems ...

Tommaso
 
Found this in the doc

The get accessor for the CompiledAssembly property calls the Load method to
load the compiled assembly into the current application domain. After
calling the get accessor, the compiled assembly cannot be deleted until the
current AppDomain is unloaded.

is that the problem referred to in a previous post in this thread?

Bottom line, since I do not know what it means (AppDomain is unloaded) I'm
asking if this is a problem if a program does repeated calculations?



Thanks for all the help - almost everything is working





Franky ha scritto:
In regard to evaluating an expression, in contrast to compiling/running
Basic. I've read this.

Using the .NET framework compilation capabilities seem to be the most
obvious way to make an evaluator. However, in practice this technique has
a
nasty side effect, it looks like it creates a new DLL in memory each time
you evaluate your function and it seems nearly impossible to unload the
DLL.

I'm pretty sure he is referenceing a CodeProvider with GenerateInMemory
=
true.

Do you agree with that there is such a problem now.

Hi Franky ,

I think this technique it's quite powerful and general. And it's fast.
I have never experienced any serious problem, in all occasions
I have used it. It takes some time to make a good use of it
and to write a friend way to interface with the user, but you have
all the possible flexibility...

It goes like :

Dim VBCodeProvider As New VBCodeProvider
Me.CompilerParameters = New CompilerParameters
With CompilerParameters
.IncludeDebugInformation = False
.GenerateInMemory = True
.GenerateExecutable = False
...

'Add here various references ...
.ReferencedAssemblies.Add(Reference) ...
End With
...

CompilerResults =
G_MyVBCodeProvider.CompileAssemblyFromSource(Me.CompilerParameters,
someCode)

....handle errors ...


'create instance if ok

Activator.CreateInstance(TipoClasse)


[ sometimes, in general contexts, you may need
System.Delegate.CreateDelegate for invocation ]

Let me know if you experience particular problems ...

Tommaso
 
hi Franky ,

As to the specific aspect you ask about I have to confess that I have
not investigated it,
as I was more concerned to make the things works.

So actually I do not know what the complete answer to your question. I
guess that after
you use the instance and then set it to Nothing, probably the Garbage
Collector
would take care of it.

As to programming I never had problems: I could compile *the same
class* again and
again (with same or different code) in memory any number of times ...

I guess that the new class replace the old one, and the old one gets
disposed (??).
The fact that the last class remains in memory is not a problem, it
actualy just what we want...

If anyone can provide more details it would be nice to know about the
inner working

Let me know if you find out anything...


Tommaso

Franky ha scritto:
Found this in the doc

The get accessor for the CompiledAssembly property calls the Load method to
load the compiled assembly into the current application domain. After
calling the get accessor, the compiled assembly cannot be deleted until the
current AppDomain is unloaded.

is that the problem referred to in a previous post in this thread?

Bottom line, since I do not know what it means (AppDomain is unloaded) I'm
asking if this is a problem if a program does repeated calculations?



Thanks for all the help - almost everything is working





Franky ha scritto:
In regard to evaluating an expression, in contrast to compiling/running
Basic. I've read this.

Using the .NET framework compilation capabilities seem to be the most
obvious way to make an evaluator. However, in practice this technique has
a
nasty side effect, it looks like it creates a new DLL in memory each time
you evaluate your function and it seems nearly impossible to unload the
DLL.

I'm pretty sure he is referenceing a CodeProvider with GenerateInMemory
=
true.

Do you agree with that there is such a problem now.

Hi Franky ,

I think this technique it's quite powerful and general. And it's fast.
I have never experienced any serious problem, in all occasions
I have used it. It takes some time to make a good use of it
and to write a friend way to interface with the user, but you have
all the possible flexibility...

It goes like :

Dim VBCodeProvider As New VBCodeProvider
Me.CompilerParameters = New CompilerParameters
With CompilerParameters
.IncludeDebugInformation = False
.GenerateInMemory = True
.GenerateExecutable = False
...

'Add here various references ...
.ReferencedAssemblies.Add(Reference) ...
End With
...

CompilerResults =
G_MyVBCodeProvider.CompileAssemblyFromSource(Me.CompilerParameters,
someCode)

....handle errors ...


'create instance if ok

Activator.CreateInstance(TipoClasse)


[ sometimes, in general contexts, you may need
System.Delegate.CreateDelegate for invocation ]

Let me know if you experience particular problems ...

Tommaso
 
I copied my code and pu it into the form that opens when the user clicks the
"About" menu item.
Took out commments to make it shorter.
First time I click About 10 appears in the "Output" pane
The second time I get the error
See anything wrong?

Thanks

Private Sub FormAbout_Load(ByVal sender As Object, ByVal e As EventArgs)
Handles MyBase.Load
Dim VBCodeProvider As New VBCodeProvider
Dim Param As New CompilerParameters()
With Param
..IncludeDebugInformation = False
..GenerateInMemory = True
..GenerateExecutable = False
Dim Asm As System.Reflection.Assembly
For Each Asm In AppDomain.CurrentDomain.GetAssemblies()
Param.ReferencedAssemblies.Add(Asm.Location)
Next
End With
Dim code As String = "Imports System " & vbCrLf
code += "Imports System.Math" & vbCrLf
code += "NameSpace Calculate" & vbCrLf
code += " Public Class Evaluator" & vbCrLf
code += " Public Shared Function Calc() as double" & vbCrLf
code += " Return " & "5+5" & vbCrLf
code += "End Function" & vbCrLf
code += "End Class" & vbCrLf
code += "End NameSpace" & vbCrLf
Dim Results As CompilerResults =
VBCodeProvider.CompileAssemblyFromSource(Param, code)
If Results.Errors.Count > 0 Then
Dim Err As CompilerError
Dim ErrorString As String = ""
For Each Err In Results.Errors
ErrorString &= vbCrLf & Err.ToString()
Next
MessageBox.Show(ErrorString, "Compiler Error", MessageBoxButtons.OK,
MessageBoxIcon.Error)
Else
Dim Assem As Assembly = Results.CompiledAssembly
Dim Eval As Object = Assem.CreateInstance("Calculate.Evaluator")
Dim typeOfEval As Type = Eval.GetType()
Dim calcInfo As MethodInfo = typeOfEval.GetMethod("Calc")
Console.WriteLine(calcInfo.Invoke(Eval, Nothing).ToString)
Assem = Nothing
Eval = Nothing
typeOfEval = Nothing
calcInfo = Nothing
End If
VBCodeProvider = Nothing
Param = Nothing
End Sub
 
Guess I didn't mention this in this thread.

The reason I included the code in my last post is:

The first time I click "About", to compile and run the sample code it works
OK

The second time I click "About", to compile and run the same sample code I
get the following:

vbc : Command line (0,0) : error BC2006: option 'r' requires':<file_list>'


Been trying to find out what the command line is when the compiler is run
but haven't figured out how yet.



Thanks for any helpful suggestions
 
dont think you need
For Each Asm In AppDomain.CurrentDomain.GetAssemblies()
....
removing that seems fine.


Dim VBCodeProvider As New VBCodeProvider
Dim Param As New CodeDom.Compiler.CompilerParameters()
With Param
.IncludeDebugInformation = False
.GenerateInMemory = True
.GenerateExecutable = False
'Dim Asm As System.Reflection.Assembly
'For Each Asm In AppDomain.CurrentDomain.GetAssemblies()
' Param.ReferencedAssemblies.Add(Asm.Location)
'Next
End With

Franky ha scritto:
 
Ok that did it

I included that earlier because I wanted Math and did not know how to
reference it in
Param.ReferencedAssemblies.Add(????)

So I thougt I'd grab them all and fix it later.



Thanks
 
Back
Top