TDL Version 0.9 Development Notes
TDL 0.9 requires python 2.6(!!!) and numpy 1.2.1 or higher.
This version of tdl relies on the ast module from python 2.6 for code parsing and interpretation. This module exposes Python's own abstract syntax tree, which is an intermediate representation of the code as it is interpreted. From an implementation view, using this module means:
- parsing, correct precedence, tricky syntax etc are trivial and correct (ie, == python), including taking subarrays, accessing object properties, loops and control flow!
to use this module, tdl code is first translated to python and then interpreted. That means that any tdl code can be converted into python with a tdl2py utility and saved.
tdl may have different namespace lookup rules from python, for example (LocalGroup, ModuleGroup, can be set at runtime.
- the code implementing tdl is much shorter, much less magic, and way easier to understand.
- the symbol table is rewritten, with Groups as simple container objects of python objects and other Groups, and name lookup is just a matter of whether an object has an attribute.
- tdl symbols now hold any python object, which can have object attributes/methods used.
Version 0.9.0 of this code can be found in the svn repo or here: tdl_0.9.0.tar.gz
The basic usage hasn't changed much, and several important bits work:
- basic variables and math
- array slicing, sub-indexing, object attributes, methods
- control flow: if/else/elseif, while, for. try/except is broken, see below
- tdl procedures (equivalent to functions)
- defined variables
- import, from-import work, importing either tdl or python modules(!)
But there are many things left to be done:
- error/exception handling (I'd call it "implemented badly, but I know how to fix it").
- built in help system.
- move existing modules (mostly Tom's) to new version
- guis
- scipy issue: Since tdl requires python2.6, but scipy is not yet available on Windows for python2.6. I assume this will get fixed eventually, but that creates a problem for some existing modules, and for Ifeffit2.
A simple sample session:
tdl> x = 1
tdl> y = sqrt(10)
tdl> g = group(x = 5, str = 'hello', arr = arange(10)/3)
tdl> g
<Group: 3 items, id=0x2aaab0fb3190>
tdl> show_group(g)
== <Group: 3 items, id=0x2aaab0fb3190> ==
arr: array([ 0. , 0.33333333, 0.66666667, 1. , 1.33333333,
1.66666667, 2. , 2.33333333, 2.66666667, 3. ])
str: 'hello'
x: 5
tdl> while y < 100:
...> y = y * g.x
...> print y
...> #endwhile
15.8113883008
79.0569415042
395.284707521
Syntax differences between TDL and Python
1. tdl does not use indentation level. Rather a block
- is ended with one of
- 'end', '#end', 'endXXX', or '#endXXX'
2. a Defined Variable can be defined with
- def [symbol_name] = expression
In tdl->python translation, this is converted to
- _builtin._definevar_('symbol_name','expression')
which creates a DefinedVariable() instance that stores the ast representation of the expression. On each name lookup for a DefinedVariable(), the expression is re-evaluated and the appropriate value inserted.
3. command syntax is allowed in some cases, so that parentheses
- are not required for all function calls. If the first word of a line of code contains a word that is is a valid symbol name (and not a reserved word) and the second word that is either a valid name or a number, and if the line does not end with a ')', the first word is taken as a function name and parentheses are added, so that
command arg1, arg2 => command(arg1, arg2)