[Ironpython-users] PythonAst
Dino Viehland
dinov at microsoft.com
Thu Dec 15 20:06:30 CET 2011
I'd suggest adding a method in the walker which handles AssignmentStatements and looks to see if the left-hand side is a NameExpression. If it is then you can add it to a list of excluded variable names which you can remove from clnVariableNames after the walk is finished.
From: ironpython-users-bounces+dinov=microsoft.com at python.org [mailto:ironpython-users-bounces+dinov=microsoft.com at python.org] On Behalf Of Rutger Koperdraad
Sent: Thursday, December 15, 2011 8:34 AM
To: ironpython-users at python.org
Subject: [Ironpython-users] PythonAst
Hi,
I'm writing an application in Visual Basic .NET that allows the users to write scripts in IronPython for some specialized customization needs. Users provide a script, a number of variable names and values, and an expression. For example, to customize the displaying of dates, they could provide the following script, variables and expressions:
Script:
dateformat = 'dddd d MMMM yyyy'
prefix = 'Birth date: '
def format(d):
import System
dd = System.DateTime.Parse(d)
return dd.ToString(dateformat)
Variables:
birthdate = '10/04/1968'
Expression:
prefix + format(birthdate)
In Visual Basic .NET I create a ScriptRuntime, ScriptEngine, ScriptSource and ScriptScope. I add the variables to the ScriptScope, execute the script and evaluate the expression. That's working like a charm.
I would like to add functionality that automatically detects which variables need to be defined. In the above example, I would like the user to specify the script and the expression and the software to detect that the variable "birthdate" is needed and prompt for a value. I tried to do so with PythonAst, but I cannot find sufficient documentation on internet to get it working in general. The functions below work to some extent. They get all the names from the expression and then remove "format" for being a function name and not a variable name. But this function still returns "prefix", which it shouldn't. Any help or documentation would be appreciated.
Public Function GetVariableNames(ByVal strExpression As String) As StringCollection
Try
If Not String.IsNullOrEmpty(strExpression) Then
' Create a script runtime if needed
If m_objScriptRuntime Is Nothing Then
m_objScriptRuntime = ScriptRuntime.CreateFromConfiguration()
End If
' Create the objects needed by the expression walker
Dim objEngine As ScriptEngine = m_objScriptRuntime.GetEngine(ScriptLanguage)
Dim objSource As ScriptSource = objEngine.CreateScriptSourceFromString(strExpression, SourceCodeKind.Expression)
Dim objSourceUnit As SourceUnit = Providers.HostingHelpers.GetSourceUnit(objSource)
Dim objLanguageContext As LanguageContext = HostingHelpers.GetLanguageContext(objEngine)
Dim objCompilerContext As New CompilerContext(objSourceUnit, objLanguageContext.GetCompilerOptions(), ErrorSink.Default)
Dim objParser As Parser = Parser.CreateParser(objCompilerContext, New PythonOptions)
Dim objPythonAst As PythonAst = objParser.ParseSingleStatement()
Dim objExpressionWalker As New ExpressionWalker
' Determine the variable names
Call objPythonAst.Walk(objExpressionWalker)
Return objExpressionWalker.VariableNames
End If
Catch ex As Exception
Call LogException(strExpression, ex)
End Try
Return New StringCollection
End Function
Private Class ExpressionWalker
Inherits PythonWalker
Private clnVariableNames As New StringCollection
Public ReadOnly Property VariableNames As StringCollection
Get
Return clnVariableNames
End Get
End Property
Public Overrides Sub PostWalk(node As NameExpression)
Call clnVariableNames.Add(node.Name)
Call MyBase.PostWalk(node)
End Sub
Public Overrides Sub PostWalk(node As CallExpression)
Dim objNameExpression As NameExpression = TryCast(node.Target, NameExpression)
If Not objNameExpression Is Nothing Then
Call clnVariableNames.Remove(objNameExpression.Name)
End If
Call MyBase.PostWalk(node)
End Sub
End Class
With best regards,
Rutger Koperdraad.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ironpython-users/attachments/20111215/cd8707f8/attachment.html>
More information about the Ironpython-users
mailing list