Difference between revisions of "LavishScript:Script Syntax"

From Lavish Software Wiki
Jump to navigation Jump to search
Line 216: Line 216:
 
   ''commands''
 
   ''commands''
 
  }
 
  }
 +
 +
Note that global atoms are not within the context of your script, but rather within the context of the global scope.  Therefore, you cannot directly refer to anything in the scope of your script, such as functions or variables, in a global atom.  Global atoms are also not destroyed when your script ends, thus making it easy to create custom commands.
  
 
== Examples ==
 
== Examples ==

Revision as of 16:04, 4 April 2006

Overview

Scripts may consist of comments, functions, code blocks, commands, control structures and object type definitions.

All scripts must have a function called main. The main function will be executed when the script is run, and any extra parameters given to the RunScript command will be passed to the function. The script ends naturally when the main function ends.

Scripts may have a function called atexit. The atexit function will be executed when the script ends for any reason (be it ending naturally, a script error, endscript command, etc) and is perfect for clearing up any UI elements, binds, aliases, global variables, etc.

Preprocessing

Before a script is used, it is sent through a preprocessor. The preprocessor's job is to take text (a single script file), and replace, remove, or insert parts, including other files. For example, the preprocessor allows the creation of entire sections of code that are conditionally used in the final version used by the system. Preprocessing directives and macros are recognized only by the preprocessor, not by the actual script or command interpreters.

Comments

Comment Type 1

Any line that starts with a semi-colon (;) is considered a comment, and will not be handled by the script (comments are actually removed by the preprocessor). These comments must be on their own line, never at the end of another line.

; good comment
echo hi ; this is not a comment and will be executed as a command!

Comment Type 2

The second type of comment, known to programmers as an ANSI-C comment, starts with /* and ends with */. These comments may be used anywhere at all, and may contain multiple lines.

/*
 * This is a sample ANSI-C comment
 * It has multiple lines
 * A style like this particular comment is often used for authorship and license notices in source code
 */
echo hi/* this is a valid comment and will not affect the echo output, which also contains: */ my name is bob
/* The above is effectively "echo hi my name is bob" */

Functions

Functions are defined like so:

function MyFunc1()
{
  commands
}
function MyFunc2(parameter1,parameter2,parameter3)
{
  commands
}
function MyFunc3(string parameter1,int parameter2)
{
  commands
}
function MyFunc4(string parameter1,int parameter2=10)
{
  commands
}

Functions may have any number of parameters, and each will default to the string type if a type is not given. Each parameter can also have a "default" value, denoted by an = followed by the value. If no default is given, the default "blank" value for its type is used (for example, 0 for numbers or empty string for strings). If a parameter is not passed to the function in the call statement, its default value will be used.

Functions can also have variable numbers of parameters by using ... as the object type for the final parameter given. All remaining parameters passed to the function will be placed in an array of strings with the given name.

function MyFunc5(... Parameters)
{
  commands
}
function MyFunc6(int Parameter1,... OtherParameters)
{
  commands
}

Each function must have its own code block. The function ends either at the final }, or from a return command. Either way, execution proceeds after the previous call statement, or ends the script if the function is main.

Code Blocks

Code blocks are defined by having a { to begin, and } to end, on their own lines. These blocks are used to define the scope of a function, and are also used by certain commands such as If and While. Code blocks can be used freely within functions, and do not modify variable scope within functions (i.e. variables declared within a local code block still exist after the code block, and must not be re-declared in a loop!).

Commands

Commands are simply LavishScript commands, as may be entered in a console or command file. See LavishScript Command Syntax for LavishScript command syntax rules.

Control Structures

Some commands available only to scripts can change the flow of execution of the script. These are not actually commands and follow only special rules for control structures. A control structure is generally made up of one or more keywords, such as "If", followed by a condition or other expression, along with one command or a code block. These structures may cause a section of code to repeat, or only be executed under a certain condition. These keywords along with the commands or code blocks they affect make up control structures. See Mathematical Formulae for insights on how "conditions" are processed (they are simply math!).

Conditional

Repetitive

Selective

Object Type Definitions

Object type definitions allow the creation of custom object types within a script. Object type definitions consist of an "objectdef" block which may contain "property" lines as well as functions, members and methods. Object types are defined like so:

objectdef mytype
{
  properties, functions, members, methods
}

Object type definitions can also inherit other object definitions. This means that a second object type definition defined like so...

objectdef othertype inherits mytype
{
  properties, functions, members, methods
}

... will automatically have all properties, functions, members and methods provided by mytype, as well as othertype.

See Script-Defined Object Types for further information on usage and implementation.

Object Properties

A property is simply a variable defined in the scope of the object. Properties can be dynamically created by a function, member or method of this object using the "object" scope, or created here as part of the object type definition. Property lines contain an object type (can be any object type except for the object type being defined), a name for the property, and optionally a default value. If no default is given, the type's "blank" equivalent (such as 0 for integers or an empty string for strings) is automatically used. When a variable is created of this object type, all of its members are initialized to their default value. Properties are defined like so:

property string Name
property int Size
property int Height=52

Object Functions

Functions in objects look and behave exactly like normal functions, but are later called by prepending the function name with the name of a variable of this type and a period, as in accessing a member. For example:

objectdef myobject
{
   ;properties...
   property int Data=10

   function MyFunction2()
   {
     echo ${Data}
   }

   function MyFunction(string p1,int p2)
   {
     call MyFunction2
   }
}

function main()
{ 
  declare MyVariable myobject
  call MyVariable.MyFunction "parameter 1" 2
}

Within an object function, a special "object" variable scope exists, which allows you to access properties of the current object. Functions within the object may also be called without the object name. A special Top-Level Object called This also exists to retrieve the current object if necessary.

Object Members

An object member is an atom which can be used like a member of any normal object type. This can be used to abstract the functionality from the data used in the object. All members return a value. Script-defined objects currently always return a string object containing the return value.

The following example shows how two separate properties that contain a location can be combined into a single member. This effectively hides the fact that the properties are separate from the function that uses the member.

objectdef myobjecttype
{
  member Location()
  {
    return "${x},${y}"
  }
  property float x
  property float y
}

function main()
{
  declare MyVariable myobjecttype
  echo ${MyVariable.Location}
}

Object Methods

An object method is an atom which can be used like a method of any normal object type -- a method can be executed directly as a command or in a data sequence, and simpy performs an action. Any return value of a method is discarded.

The following example extends the Object Members example by adding a method to set the current location of the object.

objectdef myobjecttype
{
  member Location()
  {
    return "${x},${y}"
  }

  method SetLocation(float NewX, float NewY)
  {
    x:Set[NewX]
    y:Set[NewY]
  }

  property float x
  property float y
}

function main()
{
  declare MyVariable myobjecttype
  MyVariable:SetLocation[1020.5,774.3]
  echo ${MyVariable.Location}

  ; CAN be shortened to one command as follows:
  echo ${MyVariable:SetLocation[1020.5,774.3].Location}
}

Atoms

Atoms can be defined in the same way as functions, except using the word atom, like so:

atom MyAtom1()
{
  commands
}
atom MyAtom2(parameter1,parameter2,parameter3)
{
  commands
}
atom MyAtom3(string parameter1,int parameter2)
{
  commands
}
atom MyAtom4(string parameter1,int parameter2=10)
{
  commands
}

Atoms may additionally use the keyword global to create a global atom, like so:

global atom MyAtom1()
{
  commands
}
global atom MyAtom2(parameter1,parameter2,parameter3)
{
  commands
}
global atom MyAtom3(string parameter1,int parameter2)
{
  commands
}
global atom MyAtom4(string parameter1,int parameter2=10)
{
  commands
}

Note that global atoms are not within the context of your script, but rather within the context of the global scope. Therefore, you cannot directly refer to anything in the scope of your script, such as functions or variables, in a global atom. Global atoms are also not destroyed when your script ends, thus making it easy to create custom commands.

Examples

Example 1

Obligatory "Hello World" script

function main()
{
   echo Hello World
}

Example 2

A fairly pointless script that demonstrates looping, functions, variables, data methods

function MyFunction(int Count)
{
  return -${Count}
}

function main()
{
  Declare Count int 1
  do
  {
     call MyFunction ${Count}
     echo Count: ${Count} ${Return}
  }
  while "${Count:Inc}<=10"
}

Example 3

The same pointless script as above, but with a parameter passed to main to determine the size of the loop.

function MyFunction(int Count)
{
  return -${Count}
}

function main(int Max)
{
  if ${Max<1}
    return
  Declare Count int 1
  do
  {
     call MyFunction ${Count}
     echo Count: ${Count} ${Return}
  }
  while "${Count:Inc}<=${Max}"
}

The script may be run like so:

runscript myscript 10

See Also