Given a dynamic language (i.e. variables are used without declarations) that is described in following section. Goal is to create simple static analyser for this language.
We could have functions and following operators:
X = Y
X = INT
X = Y.Z
X.Y = Z
X.Y = INT
X = Y == Z
X = Y != Z
func <func>(X, Y, …) // function declaration
<func>(X, Y, …) // call of function without return
X = <func>(X, Y, …) // call of function with return
return X
-
There is no dedicated variable declaration: if variable is not used previously, then it is just newly created. All variables are local and integers.
-
It is possible to assign a = 1 even if a.x = 1 previously. Both are just not connected valid names.
-
Function are called by value. Side effect could be obtained only when you modify a field of an argument:
func foo(a, b) {
a.x = b
}
- We could not have nested function declarations.
- We could not have functions with same names.
- We could use function before its declaration. It is close to C++ way.
- We could not have assignments or field of structure as function argument.
- Variables names are strings.
Main intension of static analyses is to find not trivial constant values that come from comparisions. For example, in the following example, variable X will be always equal to 1:
Y = Z
X = Y == Z
Due to function invocations this task is not very simple.
Easiest, fastest and widely used way to create parsers for new languages is flex/bison. To create a rough parser for the language an adaptation of Toy LLVM compiler was made. In the future it is planned to be improved.