vorige
volgende
inhoudstafel


Hoofdstuk 3: Wireless Markup Language Script

3.1 Inleiding

Dit hoofdstuk bespreekt de mogelijkheden van WMLScript (Wireless Markup Language Script). WMLScript maakt deel uit van de applicatielaag van WAP, en men kan het gebruiken om procedurele logica toe te voegen aan WML cards en decks. De taal is gebaseerd op ECMAScript, maar werd aangepast om betere ondersteuning te bieden voor toestellen met een lage bandbreedte, zoals mobiele telefoons.

3.2 Voordelen van WMLScript

Het Wireless Application Protocol (WAP) omvat WMLScript, een scripttaal die kan gebruikt worden met de Wireless Markup Language (WML) om intelligente diensten aan te bieden. WMLScript kan daarnaast ook als afzonderlijke tool gebruikt worden.

WMLScript biedt een oplossing voor de beperkingen van WML:

3.3 WMLScript bytecode interpreter

3.3.1 Inleiding

Het tekstuele formaat van de WMLScripttaal moet gecompileerd worden in een binair formaat vooraleer het kan worden geïnterpreteerd door de WMLScript bytecode interpreter. Een WMLScript encoder vertaalt één WMLScript compilatie-eenheid in WMLScript bytecode gebruik makend van een voorgeschreven formaat. Een WMLScript compilatie-eenheid is een eenheid die een aantal WMLScript functies bevat. De WMLScript compiler neemt zo’n eenheid als input, en genereert WMLScript bytecode als output.

3.3.2 De architectuur van de interpreter

WMLScript interpreter neemt de WMLScript bytecode als invoer en voert de gecodeerde functies uit zoals ze opgeroepen worden. Onderstaande figuur bevat de hoofdonderdelen met betrekking tot de WMLScript bytecode interpretatie.

We zien duidelijk dat op de figuur dat scripts die je zelf gecodeerd hebt, eerst in WMLScript bytecode moeten omgezet worden alvorens ze geïnterpreteerd kunnen worden. Let ook op de 4 elementen van informatie die bijgehouden worden en die de toestand (state) bepalen tijdens het proces.

Libraries, Interpreter, Bytecode, State
Figuur 7: de architectuur van de WMLS bytecode interpreter

De WMLScript interpreter kan gebruikt worden om functies aan te roepen en uit te voeren die in een compilatie-eenheid zitten onder de vorm van WMLScript bytecode. Elke functie specificeert het aantal parameters dat ze nodig heeft, en de instructies die nodig zijn om haar gedrag uit te drukken. Vandaar dat de aanroep van een WMLScript functie volgende zaken moet bevatten: de functie zelf, de argumenten en de compilatie-eenheid in dewelke de functie gedeclareerd werd. Wanneer de uitvoering normaal verloopt, zal de WMLScript interpreter de berekende waarde teruggeven aan de oproeper.

Het uitvoeren van een WMLScriptfunctie betekent dus dat men een functie in WMLScript bytecode gaat interpreteren. Terwijl de functie geïnterpreteerd wordt, zal de WMLScript interpreter volgende informatie bijhouden:

3.4 Core WMLScript

Hoewel het niet tot de scope van dit werk behoort om een volledige beschrijving te geven van WMLScript, kan de lezer in deze paragraaf toch een aantal kernbegrippen en elementen vinden die iedereen in staat stellen om eenvoudige WMLScripts te genereren. De concepten worden besproken die van praktisch nut zijn bij het ontwerpen van toepassingen voor WAP. De lezer die al enigszins vertrouwd is met een of andere scripttaal zal de analogie zeker moeten onderkennen.

Opnieuw kan in de bibliografie een aantal referenties gevonden worden naar extra informatie die de materie dieper uitspit.

3.4.1 Variabelen en datatypes

3.4.1.1 Declaratie van variabelen

De declaratie van een variabele gebeurt eenvoudigweg door het var element te gebruiken gevolgd door de naam van de variabele. Het spreekt voor zich dat een variabele moet gedeclareerd zijn voordat men deze kan gebruiken. Bovendien is het ook zo dat een variabele enkel toegankelijk is binnen de functie binnen dewelke deze werd gedeclareerd (= local variabele).

var x;	
var size = 3;

De laatste syntax declareert een variabele (net zoals de bovenste drie), wat betekent dat de variabele vanaf dan bestaat en kan gebruikt worden, maar doet iets extra. Ze kent er meteen de waarde drie aan toe.

3.4.1.2 Types van variabelen

Net zoals de meeste scripttalen is ook WMLScript zwak getypeerd. Volgende variabelen zijn intern ondersteund: boolean, integer, floating-point en string. Aan dit rijtje werd een vijfde type toegevoegd, met name invalid. Belangrijk is wel dat deze datatypes intern ondersteund worden. De programmeur moet dus de types niet specificeren en elke variabele kan elke informatie bevatten op elk ogenblik. WMLScript zal proberen om automatisch tussen de verschillende types te converteren als dat nodig is.

  var flag             = true;       // Boolean
  var number           = 12;         // Integer
  var temperature      = 37.7;       // Float
  number               = "XII"       // String
  var except           = invalid     // Invalid

3.4.2 Operatoren

3.4.2.1 De toewijzingsoperatoren

WMLScript beschikt over verschillende manieren om een waarde toe te wijzen aan een variabele. De eenvoudigste manier is de normale toewijzing (=), maar er zijn ook toewijzingen met operaties.

Operator Operatie = Toewijzing. += Tel getallen op/voeg strings bijeen en wijs toe. -= Trek af en wijs toe. *= Vermenigvuldig en wijs toe. /= Deel en wijs toe. div= Gehele deling en toewijzing. %= Rest bij deling en toewijzing. &= Bitsgewijze AND en toewijzing. ^= Bitsgewijze XOR en toewijzing. |= Bitsgewijze OR en toewijzing.

3.4.2.2 Rekenkundige operatoren

Operator Operatie + Tel getallen op/voeg strings bijeen (concatenatie). - Aftrekken. * Vermenigvuldigen. / Delen div Gehele deling.

3.4.2.3 Logische operatoren

Operator Operatie && Logische AND. || Logische OR. ! Logische NOT.

De logische AND operator evalueert de eerste operand en controleert het resultaat. Als het resultaat vals is, is het resultaat van de operatie vals en wordt de tweede operand niet meer gecontroleerd. Als de eerste operand waar is, zal het resultaat van de operatie afhangen van de evaluatie van de tweede operand. Is deze waar, dan is de operatie waar, is deze tweede operand vals dan is ook de operatie vals.

Deze opmerking kan volledig analoog voor de logische OR gemaakt worden.

3.4.2.4 String operatoren

WMLScript biedt dus ondersteuning voor het bijeenvoegen van strings (cf. string concatenation). De + en += operatoren, als ze gebruikt worden met strings als operand, realiseren deze functie. Andere operaties op strings worden ondersteund door een standaard String bibliotheek (zie paragraaf 3.5).

Bijvoorbeeld:

		Var str = "Beginning" + "End"
		Var str = String.charAt(str,10);  // chr = "E"

Dit voorbeeld voegt eerst de strings "Beginning" en "End" samen. De tweede regel is een functie (die in de standaardbibliotheek zit) die een teken op een bepaalde positie opvraagt. De concatenatie geeft als resultaat de string "BeginningEnd" en de tiende positie hieruit is inderdaad de letter E. De standaardfuncties omvatten trouwens niet alleen bewerkingen op strings. Een algemeen overzicht, zonder verdere uitleg, staat onder paragraaf 3.5.

3.4.2.5 Vergelijkingsoperatoren

Operator Operatie < Kleiner dan. <= Kleiner dan of gelijk aan. == Gelijk aan. >= Groter dan of gelijk aan. > Groter dan. != Verschillend van (ongelijkheid).

3.4.2.6 Andere operatoren

Daarnaast zijn ook nog array operatoren, de komma-operator, de conditie-operator, de typeoff operator en de isvalid operator beschikbaar. Ze vallen echter buiten de scope van dit werk.

De komma-operator wordt gebruikt om het einde van een statement aan te geven.

Voor de resterende operatoren zijn opnieuw nuttige referenties beschikbaar in de bibliografie.

3.4.3 Functies

Een WMLScriptfunctie is een benoemd deel van de WMLScript compilatie-eenheid en kan aangeroepen worden om een bepaalde set van instructies uit te voeren en een waarde op te leveren.

3.4.3.1 Declaratie

Functiedeclaratie wordt gebruikt om de naam (Identifier) van een WMLScriptfunctie te declareren met zijn optionele parameters (FormalParameterList). Alle functies hebben volgende kenmerken:

De syntax voor een functiedeclaratie is:

	FunctionDeclaration:
Externopt function Identifier (FormalParameterListopt)
Block;opt

	FormalParameterList:
		Identifier
		FormalParameterList, Identifier

Argumenten:

Het optionele woord extern kan gebruikt worden om aan te geven dat de functie extern toegankelijk is. Externe functies kunnen dus van buiten de compilatie-eenheid in dewelke ze gedefinieerd zijn, aangeroepen worden. Identifier is de naam van de functie. FormalParameterList (optioneel) is een lijst met namen van argumenten, gescheiden door een komma. Block is dan de romp van de functie die wordt uitgevoerd wanneer de functie is aangeroepen en de parameters geïnitialiseerd zijn door middel van het doorgeven van argumenten.

Voorbeeld:

	function calculateVAT(amount, VAT) {
	  return amount*VAT;
	};

	extern function testIt() {
		var purchase_amount = 20000;
		var total_amount = calculateVAT(purchase_amount, 1.21);
};

Verklaring:

De eerste functie calculatieVAT is een functie die twee invoerargumenten nodig heeft, amount en VAT. Worden deze aangebracht, dan levert die functie het bedrag inclusief BTW op. Immers, de return-statement is amount*VAT.

De tweede functie testIt maakt de gebruik van de functie. Ze definieert eerst een variabele purchase_amount en kent de waarde 2000 hieraan toe. Vervolgens roept ze de functie calculateVAT op, geeft de twee vereiste argumenten door en stopt het resultaat in de variabele total_amount.

De meegegeven argumenten, vereist voor de functie, staan tussen haakjes. Purchase_amount is een variabele, en 1.21 het VAT-percentage. Hier is geopteerd om dit percentage als constante te beschouwen.

Merk op dat de functie testIt geen argumenten vereist!

3.4.3.2 Functie-aanroep

De manier waarop een functie wordt aangeroepen is afhankelijk van de plaats waar de opgeroepen functie werd gedeclareerd. We kunnen dan ook functies aanroepen op drie verschillende manier in WMLScript: de lokale en de externe functie-aanroep en het aanroepen van functies uit bibliotheken.

A) Lokale scriptfuncties

Deze functies (gedefinieerd binnen dezelfde compilatie-eenheid) kunnen eenvoudig aangeroepen worden door de functienaam op te geven en de lijst van argumenten. We vestigen hier nogmaals de aandacht op het feit dat het aantal argumenten in de lijst gelijk moet zijn aan het aantal parameters die door de functie geaccepteerd worden.

Syntax:

	LocalScriptFunctionCall:
		FunctionName Arguments

	FunctionName:
		Identifier

	Arguments:
		( )
		(ArgumentsList)

	ArgumentsList:
		Assignexpression
		ArgumentList, Assignexpression

Functies binnen een zelfde compilatie-eenheid kunnen aangeroepen worden voor ze gedeclareerd zijn, zoals onderstaand voorbeeld duidelijk aantoont.

Voorbeeld:

function test2(param) {
	  return test1(param+1);
	};

	function test1(val) {
	  return val*val;
	};

Verklaring:

Aan de hand van dit voorbeeld wordt de werking van bovenstaande functies uitgelegd. Stel dat we functie test2 willen uitvoeren en we geven één argument mee, zoals vereist: de variabele param met waarde 2. Deze functie roept de functie test1 aan, en geeft op zijn beurt de variabele 3 aan functie test1 door. Immers, ze verhoogt de variabele die ze zelf ontvangt, met 1. De functie test1 geeft als resultaat 9 (3x3) terug aan de functie test2. Het resultaat van functie test2 is dus 9.

B) Externe functies

De aanroep van functies moet met de externe functie-aanroep gebeuren wanneer de functie gedeclareerd is in een externe compilatie-eeneheid. Deze functie-aanroep is zeer analoog met de voorgaande. Hier moet echter de functie-aanroep voorafgegaan worden door de naam van de externe compilatie-eenheid.

Syntax:

	ExternalScriptFunctionCall:
		ExternalScriptName # FunctionName Arguments

	ExternalScriptName:
		Identifier

Use URL moet gebruikt worden om de externe compilatie-eenheid te specificeren. Het definieert dan ook de mapping tussen de externe eenheid en een naam die kan gebruikt worden binnen de functiedeclaratie. Deze naam en het hekje (#) worden gebruikt om de normale syntax van een functie-aanroep vooraf te gaan.

Voorbeeld:

use url OtherScript http://www.host.com/script

Function test3(param) {
  Return OtherScript#test2(param+1);
};

Verklaring:

We willen een script uitvoeren dat zich ergens anders bevindt. Daartoe gaan we eerst een referentie toekennen aan die locatie. Dat gebeurt via het statement use url naam locatie (hier: Otherscript). Als dit is gebeurd, zal telkens wanneer we Otherscript gebruiken, automatisch aan de betreffende locatie worden gerefereerd.

Dat gebeurt dan ook in de functie test3. We geven het argument param mee. Deze variabele wordt met één verhoogd, en dient zo als invoer voor de functie test2 die dus ergens anders staat. Deze laatste wordt geadresseerd door de referentie aan te geven en de specifieke functie die is gevraagd binnen deze referentie (via het kardinaalteken), want er kunnen daar ook meerdere functies staan. De functie test2 voert een bewerking uit met de variabele, en de uitvoer is het resultaat van de functie test3. Wil ik de functie Squeeze gebruiken in de referentie Otherscript, dan wordt de syntax return Otherscript#Squeeze.

C) Bibliotheekfuncties

Hiervoor wordt een derde aanroepwijze gehanteerd. De lezer vindt meer over deze bibliotheekfuncties in paragraaf 3.5 en 3.6). Een uitgebreide bespreking van een aantal van de standaardbibliotheekfuncties komt ook in hoofdstuk 10 voor.

Syntax:

	LibraryFunctionCall:
		LibraryName . FunctionName Arguments

	LibraryName:
		Identifier

Voorbeeld:

	Function test4(param) {
	  Return Float.sqrt(Lang.abs(param)+1);
	};

Verklaring:

Deze functie test4 heeft als argument een variabele. Als uitvoer geeft deze functie de vierkantswortel van de absolute waarde van deze variabele verhoogd met één. Als het meegegeven argument bijvoorbeeld -8 is, dan is het resultaat van de functie test4 gelijk aan de vierkantswortel van de 9.

3.4.4 Statements

WMLScript statements bestaan uit expressies en sleutelwoorden met de daarbij horende syntax. Een enkele statement kan meerdere lijnen code betekenen. En omgekeerd kunnen meerdere statements soms op één lijn worden gecodeerd. Ook hier kan opnieuw verwezen worden naar bijvoorbeeld JavaScript, omdat de analogie met WMLScript zeer groot is.

We behandelen de belangrijke statements die praktisch bij een implementatie kunnen gebruikt worden. Meer informatie kan gevonden worden in de bibliografische lijst.

3.4.4.1 Empty Statement

Een empty statement kan gebruikt worden wanneer een statement vereist is, maar geen operatie.

Syntax:

	EmptyStatement:
	           ;

Voorbeeld:

	While (!poll(device));		// Wacht totdat poll() waar is

3.4.4.2 Expression Statement

Deze worden onder meer gebruikt om waarden toe te wijzen, rekenkundige berekeningen uit te werken en ook om functieaanroepen te maken.

Syntax:

	ExpressionStatement:
		Expression;

	Expression:
		AssignmentExpression
		Expression, AssignExpression

Voorbeelden:

	Str  = "Hey" + yourName
	Val3 = prevVal + 4;
	Counter++;
	MyValue = counter, myValue2 = val3;
	Alert("Watch out!");
	RetVal = 16*Lang.max(val3, counter)

3.4.4.3 Block Statement

Een set van statements omsloten door { } is een block statement.

Syntax:

	Block:
		{StatementListopt}

	StatementList:
		Statement
		StatementList Statement

Voorbeeld:

	{
		var I = 0;
		var x = Lang.abs(b);
		popUp(“Remember the times!”);
	}

3.4.4.4 Variable Statement

Dit statement declareert variabelen met initialisatie.

Syntax:

		VariableStatement:
			var VariableDeclarationList;

		VariableDeclarationList:
			VariableDeclaration
			VariableDeclarationList, VariableDeclaration

		VariableDeclaration:
			Identifier VariableInitializeropt

		VariableInitializer:
			= ConditionalExpression

Argumenten:

Identifier is de naam van de variabele. ConditionalExpression is de beginwaarde van de variabele die elke toegelaten expressie kan zijn. Deze expressie wordt geëvalueerd telkens wanneer de variable statement wordt uitgevoerd.

Voorbeelden:

	function count(str) {
	  var result = 0;		// Wordt één keer geïnitialiseerd.
	  while (str !="") {
	    var ind = 0;		// Wordt iedere keer geïnitialiseerd.
	    // modify string
	  };
	return result
	};

	function example(param) {
	  var a = 0;
	  if (param > a) {
	    var b = a + 1;	// a en b kunnen gebruikt worden
	  } else {
	    var c = a + 2;	// a, b en c kunnen gebruikt worden
	  };
	  return a;			// a, b en c zijn toegankelijk
	};

3.4.4.5 IF Statement

Syntax:

	IfStatement:
		if (Expression) Statement else Statement
		if (expression) Statement

Voorbeeld:

	if (sunShines) {
	   myDay = "Good";
	   goodDays++;
	} else
	   myday = "Oh well...";

Deze syntax implementeert een keuze. Als sunShines waar is, dan krijgt mijn dag het label goed, en verhoog ik mijn aantal goede dagen met één. Zoniet geef ik een ander label aan mijn dag.

3.4.4.6 WHILE Statement

Syntax:

	WhileStatement:
		while (Expression) Statement

Voorbeeld:

	var counter = 0;
	var total = 0;
	while (counter < 3) {
	  counter++;
	  total += c;
	};

Deze syntax is een vertaling van volgende omschrijving: zolang de waarde van counter (die geïnitialiseerd wordt op een waarde 0) kleiner is dan drie, verhoog de counter met één en verhoog het totaal met een waarde c.

3.4.4.7 FOR Statement

Syntax:

	for (Expressionopt; Expressionopt; Expressionopt) Statement
	for (var VariableDeclarationList; Expressionopt; Expressionopt) Statement

Voorbeeld:

	for (var index = 0; index < 100; index++) {
	  Count += index;
	  myFunc(count);
	};

Dit stukje code doet het volgende: zolang index kleiner is dan 100 (en opnieuw is index geïnitialiseerd op waarde 0) wordt index bij count geteld, en deze count door de functie myFunc verrekend. Daarna wordt de waarde van index met één verhoogd.

3.4.4.8 Break Statement

Deze statement wordt gebruikt om een huidige while of for loop te beëindigen en verder te gaan met de uitvoering van het programma vanaf het statement volgend op de beëindigde loop. Het is fout wanneer de break statement buiten een while of een for statement wordt gebruikt.

Syntax:

	BreakStatement:
		Break;

Voorbeeld:

	function testBreak(x) {
	  var index = 0;
	  while (index < 6) {
	    if (index ==3) break;
	    index++;
	  };
	  return index*x;
	};

Dit script vervult volgende taak: zolang de waarde van index kleiner is dan 6, wordt het tussenliggende blok uitgevoerd (in vet weergegeven). Als index gelijk is aan 3 wordt er een break uitgevoerd en wordt de eerstvolgende regel buiten de while-loop uitgevoerd, dus wordt return index*x uitgevoerd. Als index niet gelijk is aan 3 wordt index met één verhoogd. Concreet betekent dit hier dat de while-loop bij de vierde keer onderbroken wordt, en het resultaat van testBreak dus 9 wordt als we als waarde (voor het argument x) 3 meegaven.

3.4.4.9 Continue Statement

Syntax:

	ContinueStatement:
		Continue;

Voorbeeld:

	var index = 0;
	var count = 0;
	while (index < 5) {
	  index++;
	  if (index == 3)
	      continue;
	  count += index;
	};

Dit statement wordt gebruikt om de uitvoering van een blok van statements binnen een while of een for lus te beëindigen, en verder te gaan met de uitvoering van de lus met de volgende iteratie. Dit statement zorgt dus niet voor de beëindiging van de lus.

Als we bovenstaand voorbeeld van naderbij bestuderen, dan kunnen we de werking als volgt verklaren.

Eerst worden de variabelen index en count gedeclareerd en krijgen beiden de waarde 0 toegewezen. De while-lus zorgt ervoor dat, zolang index kleiner is dan 5, het in vet gemarkeerde blok van statements uitgevoerd worden. Er wordt hierin nagegaan of de waarde van index gelijk is aan 3. Is dit zo, dan wordt via continue automatisch naar de volgende iteratie overgegaan. Zoniet wordt de waarde count verhoogd met de waarde van index.

3.4.4.10 Return Statement

Dit statement kan gebruikt worden binnen een functie om de waarde die de functie teruggeeft te specificeren. Is er geen return statement bepaald, of geen enkele van de return statement van de functie uitgevoerd (omdat bijvoorbeeld niet voldoende argumenten werden aangeleverd), wordt standaard een lege string gegenereerd.

Syntax:

return Expressionopt

Voorbeeld:

function square(x) {
		if (!(Lang.isFloat(x))) return invalid;
		return x*x;
};

3.5 WMLScript standaardbibliotheken

De Lang bibliotheek is altijd aanwezig. Volgende standaardbibliotheken zijn tevens beschikbaar:

BibliotheekBeschrijving
Float Deze bibliotheek bevat een set van typische rekenkundige floating-point functies die vaak door applicaties worden gebruikt.
String Deze bibliotheek bevat functies om met strings te werken.
URL Deze bibliotheek bevat een set van functies om met URL’s om te gaan.
WMLBrowser Deze bibliotheek omvat functies die door WMLScript gebruikt worden om toegang te krijgen tot de bijhorende WML context.
Dialogs Deze bibliotheek bevat een set van typische user interface functies.

We geven hieronder nog een heel summier overzicht van de beschikbare functies in elk van de bibliotheken. Voor elk van deze functies kan een uitvoerige beschrijving worden gevonden in de WMLScript Library Specification.

3.6 Niet-standaard bibliotheken

WMLScript bevat ook een bibliotheek die niet standaard is en een aantal debugfuncties bevat. Deze functies kunnen gebruikt worden om de scripttoepassingen foutvrij te maken.


vorige
volgende
inhoudstafel