dcal.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. '''*****************************************************************************
  2. AToMPM - A Tool for Multi-Paradigm Modelling
  3. Copyright (c) 2011 Raphael Mannadiar (raphael.mannadiar@mail.mcgill.ca)
  4. This file is part of AToMPM.
  5. AToMPM is free software: you can redistribute it and/or modify it under the
  6. terms of the GNU Lesser General Public License as published by the Free Software
  7. Foundation, either version 3 of the License, or (at your option) any later
  8. version.
  9. AToMPM is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  11. PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with AToMPM. If not, see <http://www.gnu.org/licenses/>.
  14. *****************************************************************************'''
  15. import sys
  16. from tconstants import TConstants as TC
  17. from dapi import DesignerAPI
  18. try :
  19. import spidermonkey
  20. except ImportError as ex :
  21. pass
  22. '''
  23. this class abstracts away the fact that designer code may be specified in
  24. more than one programming language '''
  25. class DesignerCodeAbstractionLayer :
  26. def __init__(self,username,aswid,mtwid) :
  27. self._dAPI = DesignerAPI(username,aswid,mtwid)
  28. self._execContexts = {}
  29. self._execContext = None
  30. '''
  31. configure this instance of DesignerCodeAbstractionLayer and its instance
  32. of DesignerAPI
  33. 1. lazy load an ExecutionContext given the specified programming language
  34. 2. configure DesignerAPI instance '''
  35. def configure(
  36. self,lang,graph,type,pl2gi,ex,pLabel=None,attr=None,journal=None) :
  37. if lang not in self._execContexts :
  38. if lang == TC.PYTHON :
  39. self._execContexts[lang] = PythonExecutionContext(self._dAPI)
  40. elif lang == TC.JAVASCRIPT and 'spidermonkey' in sys.modules :
  41. self._execContexts[lang] = JavaScriptExecutionContext(self._dAPI)
  42. else :
  43. assert False, 'unsupported designer code language :: '+str(lang)
  44. self._execContext = self._execContexts[lang]
  45. self._dAPI.configure(graph,type,pl2gi,ex,pLabel,attr,journal)
  46. '''
  47. have the given code evaluated by the current ExecutionContext and return
  48. its output '''
  49. def eval(self,code) :
  50. return self._execContext.eval(code)
  51. '''
  52. identify the language in which the given snippet of designer code is
  53. written in '''
  54. @staticmethod
  55. def identifyLanguage(code) :
  56. if code.startswith('"[JAVASCRIPT]"\n') :
  57. return TC.JAVASCRIPT
  58. elif code.startswith('"[PYTHON]"\n') :
  59. return TC.PYTHON
  60. return None
  61. '''
  62. this class provides means to evaluate javascript code that makes use of the
  63. DesignerAPI '''
  64. class JavaScriptExecutionContext :
  65. '''
  66. setup a spidermonkey javascript execution context such that evaluated
  67. javascript code will have access to DesignerAPI functions '''
  68. def __init__(self,dAPI) :
  69. self._context = spidermonkey.Runtime().new_context()
  70. self._context.bind_callable("getAttr",dAPI._getAttr)
  71. self._context.bind_callable("hasAttr",dAPI._hasAttr)
  72. self._context.bind_callable("setAttr",dAPI._setAttr)
  73. self._context.bind_callable("getAllNodes",dAPI._getAllNodes)
  74. self._context.bind_callable("getNeighbors",dAPI._getNeighbors)
  75. self._context.bind_callable("isConnectionType",dAPI._isConnectionType)
  76. self._context.bind_callable("httpReq",dAPI._httpReq)
  77. self._context.bind_callable("print",dAPI._print)
  78. self._context.bind_callable("printToDevCon",dAPI._printToDevCon)
  79. self._context.bind_callable("session_get",dAPI._session_get)
  80. self._context.bind_callable("session_put",dAPI._session_put)
  81. self._context.bind_callable("sys_call",dAPI._sys_call)
  82. self._context.bind_callable("sys_mkdir",dAPI._sys_mkdir)
  83. self._context.bind_callable("sys_readf",dAPI._sys_readf)
  84. self._context.bind_callable("sys_writef",dAPI._sys_writef)
  85. self._context.bind_callable("pauseTransformation",dAPI._pauseTransformation)
  86. self._context.bind_callable("resumeTransformation",dAPI._resumeTransformation)
  87. self._context.bind_callable("stopTransformation",dAPI._stopTransformation)
  88. '''
  89. evaluate a string of javascript code and return its output '''
  90. def eval(self,code) :
  91. return self._context.eval_script(code)
  92. '''
  93. this class provides means to evaluate python code that makes use of the
  94. DesignerAPI '''
  95. class PythonExecutionContext :
  96. '''
  97. setup a python execution context such that evaluated python code will have
  98. access to DesignerAPI class '''
  99. def __init__(self,dAPI) :
  100. self._context = \
  101. {'getAttr' : dAPI._getAttr,
  102. 'hasAttr' : dAPI._hasAttr,
  103. 'getAttrNames' : dAPI._getAttrNames,
  104. 'setAttr' : dAPI._setAttr,
  105. 'getAllNodes' : dAPI._getAllNodes,
  106. 'getNeighbors' : dAPI._getNeighbors,
  107. 'isConnectionType' : dAPI._isConnectionType,
  108. 'httpReq' : dAPI._httpReq,
  109. 'printToDevCon' : dAPI._printToDevCon,
  110. 'session_get' : dAPI._session_get,
  111. 'session_put' : dAPI._session_put,
  112. 'sys_call' : dAPI._sys_call,
  113. 'sys_mkdir' : dAPI._sys_mkdir,
  114. 'sys_readf' : dAPI._sys_readf,
  115. 'sys_writef' : dAPI._sys_writef,
  116. 'pauseTransformation' : dAPI._pauseTransformation,
  117. 'resumeTransformation' : dAPI._resumeTransformation,
  118. 'stopTransformation' : dAPI._stopTransformation}
  119. '''
  120. evaluate a string of python code and return its output
  121. NOTE:: before evaluating, we clear past results, if any '''
  122. def eval(self,code) :
  123. if 'result' in self._context :
  124. del self._context['result']
  125. exec(code) in self._context
  126. if 'result' not in self._context :
  127. return None
  128. return self._context['result']