eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'JavaScriptParser':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: JavaScriptParser


Inheritance:

   Object
   |
   +--Scanner
      |
      +--JavaScriptScanner
         |
         +--JavaScriptParser
            |
            +--JavaScriptCompiler
            |
            +--JavaScriptCompletionParser
            |
            +--JavaScriptSyntaxHighlighter

Package:
stx:libjavascript
Category:
Languages-JavaScript-Compiling & Parsing
Version:
rev: 1.284 date: 2018/05/18 02:27:08
user: cg
file: JavaScriptParser.st directory: libjavascript
module: stx stc-classLibrary: libjavascript

Description:


reads JavaScript-like syntax, builds up an AST similar to the ST-AST.
Used for expecco, so be careful when changing.


Class protocol:

configuration
o  forInAllowed
^ false.

evaluation
o  evaluate: aStringOrStream
evaluate a javaScript expression.
A new environment is created, where variables are defined.
usage example(s):
     self evaluate:'1 + 2 * 3 + 4'
usage example(s):
     self evaluate:'
if (1 > 2) {
    Transcript.showCR(1);
} else {
    Transcript.showCR(2);
}
'
usage example(s):
     self evaluate:'
if (1 > 2) {
    Transcript.foo(1,2,3,4,5,6,7,8,9,10);
} else {
    Transcript.bar(1,2,3,4,5,6,7,8,9,10);
}
'
usage example(s):
     self evaluate:'
if (1 > 2) {
    Transcript.show(hello);
} else {
    Transcript.show(world);
}
Transcript.cr;
'

o  evaluate: aStringOrStream in: anEnvironment
like #evaluate, but take anEnvironment for variable/function declarations.
New vars/functions will be added to that one; lookup for vars/methods
is done there.
If a nil environment is given, a new one will be created for the
evaluation and discarded afterwards.

o  evaluate: aString in: anEnvironment receiver: someObject notifying: requestor logged: logged ifFail: failBlock

o  evaluate: aStringOrStream in: anEnvironment receiver: anObject notifying: requestor logged: logged ifFail: failBlock compile: compile
return the result of evaluating aStringOrStream, errors are reported to requestor.
Allow access to anObject as self and to its instVars (used in the inspector).
If logged is true, an entry is added to the change-file. If the failBlock argument
is non-nil, it is evaluated if an error occurs.
Finally, compile specifies if the string should be compiled down to
bytecode or instead be interpreted from the parseTree.
The first should be done for doIts etc, where a readable walkback is
required.
The latter is better done for constants, styleSheet and resource
reading and simple sends, where the overhead of compilation is bigger
than the interpretation overhead.

o  evaluate: aStringOrStream receiver: receiver in: anEnvironment
like #evaluate, but take anEnvironment for variable/function declarations.
New vars/functions will be added to that one; lookup for vars/methods
is done there.
If a nil environment is given, a new one will be created for the
evaluation and discarded afterwards.

o  evaluateDeclarationsFrom: aStringOrStream for: anEnvironment

o  evaluateFrom: aStringOrStream ifFail: exceptionValue
evaluate a javaScript expression.
A new environment is created, where variables are defined.

initialization
o  initialize

o  postAutoload
(comment from inherited method)
postAutoload is sent to a class after it has been autoloaded.
This gives it a chance to arrange for automatic unloading to be done
after a while ...
This is NOT sent to statically compiled in or explicitely filedIn
classes.
The default action here is to do nothing.

instance creation
o  for: aStringOrStream in: aClass
return a new parser, reading code for aClass from aStringOrStream

parsing
o  methodCommentFromSource: aStringOrStream
here, the methodComment is usually outside of the method's code,
so comments before the function are included in the search, but after it are not.
usage example(s):
     JavaScriptParser methodCommentFromSource:'
// foo bar baz
function x() { 
    halt(); 
}
// bla bla
'                 

o  methodCommentsFromSource: aStringOrStream
returns all comments found in aStringOrStream.
Here, the methodComment is usually outside of the method's code,
so comments before the function are included, but after it are not.
usage example(s):
     JavaScriptParser methodCommentsFromSource:'
// foo bar baz
function x() { 
    halt(); 
}
// bla bla
'            

o  parseClassDefinition: aStringOrStream

o  parseClassFile: aStringOrStream
aStringOrStream

o  parseExpression: aStringOrStream
self
parseExpression:'1 + 2 * 3 + 4'

usage example(s):
     self
        parseExpression:'1.1 + 2.2'

o  parseFunction: aStringOrStream
self
parseFunction:'function foo(a, b, c) {}'

usage example(s):
     self
        parseFunction:'function foo(a, b, c) { return a+b; }'

o  parseFunction: aStringOrStream in: aClass
self
parseFunction:'function foo(a, b, c) {}'

usage example(s):
     self
        parseFunction:'function foo(a, b, c) { return a+b; }'

o  parseMethod: aStringOrStream in: aClass
parse a method in a given class. Return a parser (instance of myself).
The parser can be queried for selector, receiver, args, locals,
used selectors, modified instvars, referenced classvars etc.

o  parseMethod: aStringOrStream in: aClass ignoreErrors: ignoreErrors ignoreWarnings: ignoreWarnings
parse a method in a given class. Return a parser (instance of myself).
The parser can be queried for selector, receiver, args, locals,
used selectors, modified instvars, referenced classvars etc.

o  parseMethodArgAndVarSpecificationSilent: aStringOrStream

o  parseMethodSilent: aString
parse a method.
Return a parser (if ok), nil (empty) or #Error (syntax).
The parser can be queried for selector, receiver, args, locals,
used selectors etc.
Like #parseMethod:, but warning/error messages are suppressed.

o  parseMethodSilent: aStringOrStream in: aClass

o  parseMethodSpecificationSilent: aStringOrStream

o  parseStatementBlockBody: aStringOrStream
self
parseStatementBlockBody:'1+2'

usage example(s):
     self
        parseStatementBlockBody:'var a; a'
usage example(s):
    Class nameSpaceQuerySignal
    answer:JavaScriptEnvironment
    do:[
     self
        parseStatementBlockBody:'Math.PI'
    ]

o  xx_parseMethodSpecification: aStringOrStream in: aClass ignoreErrors: ignoreErrors ignoreWarnings: ignoreWarnings

selector translation
o  commonTranslatedSelectorFor: jsSelector
common translation (both JS-in-ST and JS-in-HTML).
Given a javascript operator or function name,
translate it into a corresponding smalltalk selector for a message send

o  reverseCommonTranslatedSelectorFor: smalltalkSelector
reverse translation.
Given a smalltalk selector, return a corresponding JavaScript
operator or function name.
Used by the document generator only

o  reverseTranslatedJavaScriptSelectorFor: smalltalkSelector
translate javaScript selectors as req'd for compiled JTalk.
Given a javascript operator or function name,
translate it into a corresponding smalltalk selector for a message send
usage example(s):
     self reverseTranslatedJavaScriptSelectorFor:#show:    
     self reverseTranslatedJavaScriptSelectorFor:#at:      
     self reverseTranslatedJavaScriptSelectorFor:#at:put:  
     self reverseTranslatedJavaScriptSelectorFor:#+    
     self reverseTranslatedJavaScriptSelectorFor:#-    

o  selectorForFunctionName: name numArgs: n
given a javaScript function name,
return an appropriate valid smalltalk selector.
This is used when methods are compiled

temporary hacks for DWIM
o  parseMethod: aStringOrStream setup: setupBlock onError: onErrorBlock


Instance protocol:

accessing
o  currentNameSpace: aNameSpace

o  currentNamespace: aNameSpace

** This is an obsolete interface - do not use it (it may vanish in future versions) **

o  interactiveMode: something
support for stx-scripting service

o  methodCategory

o  methodCategory: something

o  moreSharedPools: aCollection

o  selector

o  targetClass

o  targetClass: aClass

o  tree
return the value of the instance variable 'tree' (automatically generated)

o  tree: something
set the value of the instance variable 'tree' (automatically generated)

debugging
o  inspector2TabParseTreeInspector

o  inspector2Tabs
(comment from inherited method)
Workaround for stc bug

dummy-syntax detection
o  markArgumentIdentifierFrom: pos1 to: pos2
intentionally left blank here

o  markFunctionNameFrom: pos1 to: pos2
intentionally left blank here

o  markGlobalIdentifierFrom: pos1 to: pos2
intentionally left blank here

o  markKeyword: kw from: pos1 to: pos2
intentionally left blank here

o  markLocalIdentifierFrom: pos1 to: pos2
intentionally left blank here

o  markSelector: id from: pos1 to: pos2 receiverNode: aReceiverNodeOrNil numArgs: numArgs
intentionally left blank here

o  markSelfFrom: pos1 to: pos2
intentionally left blank here

o  markSuperFrom: pos1 to: pos2
intentionally left blank here

o  markVariable: v
intentionally left blank here

o  markVariable: v from: pos to: endPos
intentionally left blank here

error handling
o  parseError: aMessage position: position to: endPos

o  undefError: varName
self parseError:'unknown global: ' , varName.

o  warning: msg
^ super warning:msg

evaluation
o  evaluate: aString in: anEnvironment receiver: someObject notifying: requestor logged: logged ifFail: failBlock
true -- assuming that subclasses can compile

o  evaluate: aStringOrStream in: anEnvironment receiver: anObject notifying: requestor logged: logged ifFail: failBlock compile: compile
return the result of evaluating aStringOrStream, errors are reported to requestor.
Allow access to anObject as self and to its instVars (used in the inspector).
If logged is true, an entry is added to the change-file. If the failBlock argument
is non-nil, it is evaluated if an error occurs.
Finally, compile specifies if the string should be compiled down to
bytecode or instead be interpreted from the parseTree.
The first should be done for doIts etc, where a readable walkback is
required.
The latter is better done for constants, styleSheet and resource
reading and simple sends, where the overhead of compilation is bigger
than the interpretation overhead.

o  evaluateDeclarationFor: anEnvironment
this is used with the scripting interpreter, where an existing environment
is used and manipulated (i.e. declared variables are persistent across evaluations).
Reads a single decl; for function decls, declare them;
for statements & expressions, evaluate them.

o  evaluateDeclarationsFor: anEnvironment
read; for function decls, declare them; for statements & expressions,
evaluate them.
Returns the value of the last expression

helpers
o  commonTranslatedSelectorFor: jsSelector
common translation (both JS-in-ST and JS-in-HTML).
Given a javascript operator or function name,
translate it into a corresponding smalltalk selector for a message send

o  currentNameSpace

o  expect: expected

o  expectKeyword: expected

o  findNameSpaceWith: aVariableName
"/ private names have already been searched for.

o  ifRequiredTranslateSelectorIn: aNode
we are compiling a javaScript-script in a browser.

o  isOpAssignSymbol: token

o  selectorForFunctionName: arg1 numArgs: arg2

o  topEnvironment

o  translatedJSSelectorFor: selector numArgs: numArgs
translate selectors as req'd for HTML-scripts.
All selectors get a js_ prepended, to avoid conflicts with corresponding
smalltalk selectors.
This is especially req'd, as at:/at:put: in JS are 0-based,
while being 1-based in ST.
Thus, the translation allows for indexOf: to remain unchanged, and js_indexOf: returns a 0-based index.

o  translatedSmalltalkSelectorFor: jsSelector numArgs: numArgs
translate javaScript selectors as req'd for compiled JTalk.
Given a javascript operator or function name,
translate it into a corresponding smalltalk selector for a message send

initialization
o  environment: anEnvironment

o  foldConstants: aBoolean

o  initialize
(comment from inherited method)
initialize the scanner

o  isDoIt

o  isDoIt: aBoolean

o  parseForCode

o  setClassToCompileFor: aClass
set the class to be used for parsing/evaluating

o  setSelf: anObject
(classToCompileFor ~~ PrevClass) ifTrue:[

o  smalltalkCompatibilityMode
in smalltalk mode, array indexing is 1-based,
and conditions must be booleans.
in non-smalltalk (i.e. javaScript) mode, indexing is 0 based
and conditions can also be integers (treating 0 as false).
The default is true (and MUST remain so for expecco)

o  smalltalkCompatibilityMode: aBoolean
in smalltalk mode, array indexing is 1-based,
and conditions must be booleans.
in non-smalltalk (i.e. javaScript) mode, indexing is 0 based
and conditions can also be integers (treating 0 as false).
The default is true (and MUST remain so for expecco)

o  untranslatedJavaScriptSelectors1

o  untranslatedJavaScriptSelectors1: something

o  untranslatedJavaScriptSelectors2

o  untranslatedJavaScriptSelectors2: something

parsing
o  argList
arg | argList , arg

o  classDefinition
public class <name> extends <superName> {
<varDecls>
}

o  classNameIdentifier

o  constDeclaration
'const' name [ '=' constExpression ]';'

o  constDeclarationFor: anEnvironment
[ 'static' ] 'const' name ['=' initExpr] ';'

o  constOrVarDeclarationFor: anEnvironment isConst: isConstIn
[ 'static' ] ('const'|'var') name ['=' initExpr] ';'
| 'let' name ['=' initExpr] ';'

o  declareConstant: varName inEnvironment: anEnvironment

o  declareStaticConstant: varName
name (not eaten)

o  declareStaticVariable: varName
name (not eaten)

o  declareStaticVariable: varName isConstant: isConstant
name (not eaten)

o  declareVariable: varName inEnvironment: anEnvironment

o  declareVariable: varName inEnvironment: anEnvironment isConstant: isConstant
caveat: isConstant is currently ignored

o  function
function(args) stats ;

o  function: readOverClosingBrace
function(args) stats ;

o  functionBodyFor: functionNameOrNil asInnerFunction: asInnerFunction
(args) stats ;

o  functionBodyFor: functionNameOrNil asInnerFunction: asInnerFunction withStatements: withStatements
(args) stats ;

o  functionName
function name(args) stats ;
| function className.name(args) stats ;
| function className.class.name(args) stats ;

o  functionOrStaticFunction: readFinalBrace
]static] function(args) stats ;

o  lambdaFunctionBodyWithArguments: argList
{ stats } ;

o  needSemi
;

o  parseDeclarationsFor: anEnvironment
read; for function decls, declare them; for statements & expressions,
parse (but do not evaluate) them.

o  parseExpressionWithSelf: anObject notifying: someOne ignoreErrors: ignoreErrors ignoreWarnings: ignoreWarnings inNameSpace: aNameSpaceOrNil
parse aString as an expression with self set to anObject;
Return the parseTree (if ok), nil (for an empty string
or comment only ) or #Error (syntactic error).

Errors and warnings are forwarded to someOne (usually some
codeView) which can highlight it and show a popup box,
iff ignoreErrors/ignoreWarnings is true respectively.

o  parseMethod

o  parseMethod: theCode in: aClass ignoreErrors: ignoreErrorsArg ignoreWarnings: ignoreWarningsArg

o  rememberAssignmentTo: var
type == #PoolVariable ifTrue:[

o  rememberReadOf: var
type == #PoolVariable ifTrue:[

o  varDeclaration
[ 'static' ] 'var' name ['=' initExpr] ';'
[ 'static' ] 'const' name ['=' initExpr] ';'
| 'let' name ['=' initExpr] ';'

o  varDeclarationFor: anEnvironment
[ 'static' ] 'var' name ['=' initExpr] ';'
[ 'static' ] 'const' name ['=' initExpr] ';'
| 'let' name ['=' initExpr] ';'

parsing-expressions
o  addExpression
addExpr -> mulExpr addOp mulExpr

o  arrayConstant
arrayConstant -> Integer-constant
| Float-constant
| String-constant
| true
| false
| null
| arrayLiteral
| objectLiteral

o  arrayIndexing: expr
arrayIndexing -> [...]

o  arrayIndexingExpression: recIn
arrayIndexingExpression -> variableOrFunctionExpression
| variableOrFunctionExpression[ indexExpr ]

o  arrayIndexingExpressionList: exprIn
arrayIndexingExpressionList ->
.identifier(...)
| [ array-expr ]

o  arrayLiteral
arrayLiteral -> [ literalConstant { , literalConstant } ] ']'
initial opening bracket has NOT been read.

o  bitAndExpression
bitAndExpression -> equalityExpr & equalityExpr

o  bitOrExpression
bitOrExpression -> bitXorExpr | bitXorExpr

o  bitShiftExpression
conditionalExpr -> addExpr shiftOp addExpr

o  bitXorExpression
bitXorExpression -> bitAndExpr ^ bitAndExpr

o  booleanAndExpression
booleanAndExpression -> bitOrExpr && bitOrExpr

o  booleanOrExpression
booleanAndExpression -> bitOrExpr || bitOrExpr

o  commaExpression
commaExpression -> conditionalExpression [, commaExpression ]

o  compareExpr
compareExpr -> bitShiftExpr relOp bitShiftExpr

o  compoundExpression

o  conditionalExpression
conditionalExpr -> boolOrExpr ? boolOrExpr

o  constantExpression

o  equalityExpression
equalityExpression -> compareExpr relOp compareExpr

o  expression
expression -> commaExpression

o  expressionList
expression | expressionList , expression

o  functionCallExpression
OOPS: almost same as primaryExpression - please refactor

** This is an obsolete interface - do not use it (it may vanish in future versions) **

o  functionCallExpression: recIn
functionCallExpression -> var
| var(argList)

o  functionCallNodeForReceiver: rec selector: id args: argList fold: fold
block evaluation - generate a value-send

o  implicitFunctionCallNodeForReceiver: rec selector: id args: argList fold: fold

o  mulExpression
mulExpr -> unaryExpr mulOp unaryExpr

o  newExpression

o  nonCommaExpression

o  objectLiteral
objectLiteral -> '{' [ slotName ':' literal { , slotName ':' literal } ] '}'
opening brace has already been read

o  primaryExpression
primaryExpr ->
'(' expr ')'
'(' id1,...idN ')' '=>' '{' function-body '}'
| constant
| 'this'
| 'super'
| variable
| 'new' class
| 'new' funcOrClass '(' dim ')'
| 'function' '(' argList ')' '{' statements '}'

o  realFunctionCallNodeForReceiver: rec selector: id args: argList fold: fold
block evaluation - generate a value-send

o  typeofExpression

o  unaryExpression
unaryExpr -> ! unaryExpression
| ~ unaryExpression
| - unaryExpression
| ++unaryExpression
| --unaryExpression
| typeof(primaryExpression)
| primaryExpression
| primaryExpression--
| primaryExpression++

o  varDeclaringExpression

o  variable: idAlreadyScanned

o  variable: idAlreadyScanned ignoreErrors: ignoreErrors
if there is one in the current evaluationContext,

parsing-obsolete
o  assignmentExpression
assExpr -> var = condExpr


** This is an obsolete interface - do not use it (it may vanish in future versions) **

parsing-statements
o  breakStatement
breakStatement -> break ';'

o  catchPartFor: tryBlockNode
tryCatchStatement -> try {
...
statements
...
}
catch(Error [exVar] ) {
...
statements
...
}
[ finally {
...
statements
...
}

Notice: try { ... } has already been parsed.

o  continueStatement
continueStatement -> continue ';'

o  doWhileStatement
doWhileStatement -> do stat while (expression)

o  finallyPart
finallyPart -> finally {
...
statements
...
}

o  forStatement
forStatement -> for (initexpr ; condexpr ; increxpression) stat
| for (variable in array) stat

o  functionDefinition
ok without semi

o  ifStatement
ifStatement -> if (expression) stat [ else stat ]

o  returnStatement
returnStatement -> return [ expression ] ['from' outerFunctionName ] ';'

o  statement
statement -> expression ;

o  statementBlock
statementBlock -> { statList } | statement

o  statementBlock: readClosingBraceBoolean
statementBlock -> { statList } | statement

o  statementBlockBody
statementBlock -> [ var decl ] statList

o  statementBlockBodyFor: anEnvironment
statementBlock -> [ var decl ] statList

o  statementWithSemi: needSemi
statement ->
var varName ....
let varName ....
const varName ....
static var varName ....
function ....
ifStatement
whileStatement
doStatement
returnStatement
forStatement
switchStatement
breakStatement
continueStatement
tryStatement
throwStatement
{ statementBlock }
expression ;

o  statements
statement -> expression ;

usage example(s):
this is encountered, when reading a javaScript, in which statements

o  switchStatement
switchStatement -> switch (expression) {
case constant-expression1:
...
stat
...
break ;
case constant-expression2:
...
default:
...
}

o  throwStatement
throwStatement -> throw expression ';'

o  tryStatement
tryStatement -> try {
...
statements
...
}
( catchPart | finallyPart ]

o  whileStatement
whileStatement -> while (expression) stat

private
o  handleCategoryDirective: categoryString
callback from the scanner, whenever it encountered a category comment-directive

o  isSyntaxHighlighter

o  nameSpaceSelectorFor: aSymbol
Caring for the current namespace, return the real selector used for a send.

queries
o  isEmptyMethod
return true (after a parse) if this is an empty (documentation) method

o  methodArgs

o  methodVars

o  wasParsedForCode
a kludge for compatibility

queries-statistic
o  messagesPossiblySent
return a collection with possible message selectors (valid after parsing).
Includes things known or possibly used with #perform or in specs.
Not yet implemented here.
usage example(s):
^ (messagesPossiblySent ? #()) collect:[:each | each asSymbol]

o  messagesSent
return a collection with sent message selectors (valid after parsing).
Includes all sent messages (i.e. also sent super messages)

o  messagesSentToSelf
that is not true - for now, to make the browser happy

o  messagesSentToSuper
that is not true - for now, to make the browser happy

o  modifiedClassVars

o  modifiedGlobals

o  modifiedInstVars

o  usedClassVars

o  usedGlobals

o  usedInstVars

o  usedVars

o  usesSuper
return true if the parsed method uses super (valid after parsing)

statistic
o  rememberClassVarModified: name

o  rememberClassVarRead: name

o  rememberClassVarUsed: name

o  rememberGlobalModified: name

o  rememberGlobalRead: name

o  rememberGlobalUsed: name

o  rememberInstVarModified: name

o  rememberInstVarRead: name

o  rememberInstVarUsed: name

o  rememberLocalModified: name
modifiedLocalVars isNil ifTrue:[

o  rememberLocalRead: name
readLocalVars isNil ifTrue:[

o  rememberLocalUsed: name
usedLocalVars isNil ifTrue:[

o  rememberVariableUsed: name

temporary hacks for DWIM
o  nodeGenerationCallback: nodeGenerationHook

o  rememberNodes: aBoolean

o  rememberTokens: aBoolean

utilities
o  ensureBooleanExpression: expr
relops are guaranteed to return booleans...


Private classes:

    AndExpressionNode
    ArrayAccessNode
    ArrayStoreNode
    BreakStatementNode
    CommaExpression
    ConditionalNode
    ContinueStatementNode
    DoWhileStatementNode
    ForStatementNode
    FunctionCallNode
    IfStatementNode
    ImplicitFunctionCallNode
    IncDecNode
    InnerJavaBlockNode
    JavaScriptAssignmentNode
    JavaScriptBinaryNode
    JavaScriptReturnNode
    JavaScriptStatementNode
    JavaScriptUnaryNode
    NewNode
    OrExpressionNode
    PostIncDecNode
    PreIncDecNode
    StatementBlockNode
    SwitchStatementNode
    ThisNode
    ThrowStatementNode
    TryCatchStatementNode
    TypeOfNode
    WhileStatementNode

Examples:


    JavaScriptParser parseExpression:'3 != 4'  
JavaScriptParser parseExpression:'0b11 + 0b100'
    (JavaScriptParser parseExpression:'3 + 4 * 5') evaluate  
    JavaScriptParser parseExpression:'(3 != 4) && (5 == 5)' 
    (JavaScriptParser parseExpression:'(3 == 4) || (5 == 5)') evaluate 
    JavaScriptParser parseExpression:'!(3 != 4)'      
    (JavaScriptParser parseExpression:'(3 != 4)') evaluate
    (JavaScriptParser parseExpression:'!(3 != 4)') evaluate
    #(
        '1 + 2 * 3 + 4'
        '1 * 2 * 3 * 4'
        '1 + 2 / 3'
        '10 / 3'
        '11 & 3'
        '0x8000'
        '0377'
        '3 == 3'
        '3 != 3'
        '3 == 4'
        '3 != 4'
        '3 > 3'
        '3 >= 3'
        '3 < 3'
        '3 <= 3'
        '3 > 4'
        '3 >= 4'
        '3 < 4'
        '3 <= 4'
        '4 > 3'
        '4 >= 3'
        '4 < 3'
        '4 <= 3'
        '0x8>>2'
        '8 << 2'
        '8 >>> 2'
    ) do:[:s |
        Transcript
            show:'''';
            show:s;
            show:'''';
            show:' ->  ';
            showCR:(JavaScriptParser parseExpression:s) evaluate.
    ]
     JavaScriptParser
        parseFunction:'function foo(a, b, c) {}'
     JavaScriptParser
        parseFunction:'function foo(a, b, c) {
            if (a > 1) {
                return a;
            } else {
                return b;
            }
        }'
     JavaScriptParser
        parseFunction:'
function bar(a, b, c) {
    var sum;

    while (a > 1) {
        sum += a;
        a--;
    }
    return sum;
}'
     JavaScriptParser
        parseFunction:'
function bar(a, b, c) {
    var sum;
    var j;
    if ( foo(a,b) ) {
        for (j=0; j<=a.length; j++) {
            if (c[j] <= c[j+1])
                break;
        }
    }
    return sum;
}'
     JavaScriptParser
        parseFunction:'
function bar(a, b, c) {
    var sum;

    if ( foo(a,b) ) {
        for (var j=0; j<=a.length; j++) {
            if (c[j] <= c[j+1])
                break;
        }
    }
    return sum;
}'
     JavaScriptParser
        parseFunction:'
        function switch_time(value) {
          if (value < 0.5) sw = 0;
                else sw=-1;
        }
'
     JavaScriptParser
        parseFunction:'
        function f(a) {
          return ( function (b) { return (a + b); } );        
        }
'


ST/X 7.1.0.0; WebServer 1.663 at exept.de:8081; Sat, 21 Jul 2018 19:32:37 GMT