· 9 years ago · Nov 25, 2016, 09:46 AM
1///ZScript Docs v0.6.9
2///12-JUNE-2016
3
4Preamble: The ZScript lexer uses string formatting detection to detect the type of instructions being fed to it.
5This falls into a strict syntax, with each element represented by a case or enum. The following are the legal types of components
6that the compiler recognises.
7
8When scanning a code file, for example, the following example lines may be evaluated:
9
10ffc script my_ffc{
11 void run(){
12 my_function();
13 }
14}
15
16The parser looks at this, one line at a time,as a string in a buffer, and matches symbolic concepts from that:
17
18ffc script my_ffc{
19 scans as
20TYPE TOKEN IEENTIFIER LBRACE
21
22The lexer then tries to match this to a type of possible legal string, and examines each of the internal keywords with
23a table.
24TYPE ffc
25TOKEN script
26IDENTIFIER my_ffc
27LBRACE {
28
29This tells the lexer that it is an ffc script, opening, with the name my_ffc. The LBRACE indicates that a codeblock will follow.
30
31
32LBRACE
33RBRACE
34CHARACTER
35QUOTEDSTRING
36FUNCTION
37QUOTE
38LPAREN
39LPAREN
40IDENTIFIER
41TYPE
42NUMBER
43SIGN
44LBRACKET
45RBRACKET
46OPERATOR
47
48
49Compiler Directives
50
51import
52
53Basic Types
54
55int
56float
57bool
58const *
59void
60
61ZScript types
62* ffc
63* lweapon
64* eweapon
65* npc
66* itemdata
67* item
68* !npcdata -> To be added.
69* wtf : This is used by the lexer when it can;t identify a legal type.
70 The lexer will return an error, e.g. 'Cannot cast from wtf to float'.
71
72Namespace and Class Types
73* link
74* screen
75* game
76
77
78Declarations
79* Variables
80* Arrays
81* Objects
82
83Arrays
84
85Pointers
86* General
87* Array
88* Link
89* This
90* Objects
91
92Strings
93* String Formatting
94* Strings vs. Arrays
95* String.zh
96
97
98Functions
99
100Making Functions
101Making Accessors
102
103Instructions & Statements`
104* Break
105* Continue
106* Return
107* While
108* Do
109-->Until
110* If
111* Else
112* Else If
113* True
114* False
115//* More
116//* Less
117
118Tokens and Operator Symbols (ffscript.ypp, ffscript.lpp)
119The scanner operates by reading your code in the form of strings, and scanning those strings for specific values that it translates
120into TOKENS. It uses these TOKENS to determine the syntax of your program, using various routines. The following are a list of
121all the legal types of TOKENS in ZScript, used by the scanner/parser:
122
123TYPE
124Type is the type of variable, function, or SCRIPT; for IDENTIFIERS and may be any of the following:
125
126FLOAT float
127BOOL bool
128VOID void
129FFC ffc
130ITEM item
131ITEMCLASS itemdata
132NPC npc
133LWEAPON lweapon
134EWEAPON eweapon
135
136SCRIPT script
137This is true, except if the TYPE token is preceded by the SCRIPT token, in which case, the only *legal* types are:
138
139GLOBAL global
140FFC ffc
141ITEM item
142
143
144STATEMENT
145
146FOR for
147BOOL bool
148VOID void
149IF if
150ELSE else
151RETURN return
152FLOAT float
153ELSE else
154RETURN return
155IMPORT import
156TRUE true
157FALSE false
158WHILE while
159ITEMCLASS itemclass
160BREAK break
161CONTINUE continue
162CONST const
163DO do
164NPC npc
165LWEAPON lweapon
166EWEAPON eweapon
167
168ASSIGN =
169SEMICOLON ;
170COMMA ,
171LBRACKET [
172RBRACKET ]
173LPAREN (
174RPAREN )
175DOT .
176LBRACE {
177BRACE }
178ARROW ->
179
180PLUSASSIGN +=
181MINUSASSIGN -=
182TIMESASSIGN *=
183DIVIDEASSIGN /=
184ANDASSIGN &&=
185ORASSIGN ||=
186BITANDASSIGN &=
187BITORASSIGN |=
188BITXORASSIGN ^=
189MODULOASSIGN %=
190LSHIFTASSIGN <<=
191RSHIFTASSIGN >>=
192
193QUOTEDSTRING "string"
194SINGLECHAR ' ? `
195ASSIGN =
196LSHIFT <<
197RSHIFT >>
198BITAND &
199BITOR |
200BITXOR ^
201AND &&
202OR ||
203NOT !
204BITNOT ~
205INCREMENT ++
206DECREMENT ==
207LE <=
208LT <
209GE >=
210GT >
211EQ ==
212NE !=
213PLUS +
214MINUS -
215TIMES *
216DIVIDE /
217MODULO %
218
219COMMENT //
220
221
222NUMBER 0 1 2 3 4 5 6 7 8 9 0 (any combination)
223NUMBER 0
224IDENTIFIER ABCDEFGHIJLKMNOPQRSTUVWXYZambcedghijklmnopqrstuvwxyz1234567890 (any combination)
225
226A NUMBER is differntiated from an IDENTIFIER int hat it has *noA* alpha chars in it, except A-F for Hex, and lowercase b
227for binary. The lexer reads a hexidecimal value by the prefix '0x', so any value starting with 0x that contains
228'0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f' in any combination is read as a NUMBER.
229Likewise, any string that has only chars 0 1 b where 'b' is at the end of the string, is recognised as a binary NUMBER
230and *not* an IDENTIFIER. Thus: 100010b is recognised as NUMBER< but 01102b is recognised as an IDENTIFIER.
231
232Otherwise, an IDENTIFIER always has at least one alpha character, and may mix NUMBERS and alpha chars that is not
233either a hexidecimal NUMBER, or a binary NUMBER.
234
235Support for octal NUMBERS may be added at a later time.
236
237A QUOTEDSTRING is recognised as any string of characters, other then the QUOTE ( " ) that are between two quotes, thus:
238"This 1023 string 0x1F is a QUOTEDSTRING 102b"
239This is a QUOTEDSTRING, and the values between the quote marks are the astring itself.
240
241because thw quote marks are the TOKENS for this, you cannot use quote marksa *inside* the string itself:
242int "The Dwarf said, "I cannot do this".";
243This is illegal, as the parser will read the following value as a QUOTESSTRING: int "The Dwarf said, "
244The chars that follow, will not be considered part of the string, and will throw an error.
245
246
247\'[^\']?\' { doLines();yylval = new ASTString(yytext, yylloc); return SINGLECHAR; }
248
249//* What is this one supposed to be?
250{WS} { ; }
251WS (set) { ; }
252A set is defined as a series of values between braces that follow an ASSIGN
253
254A COMMENT is defined as two div signs in sequence ( // ) followed by any combination fo characters, and a LINEBREAK.
255Anything between the COMMENT token and a LINEBREAK is considered a comment, and not parsed.
256
257###################
258## Illegal Chars ##
259###################
260
261SINGLECHAR in an IDENTIFIER
262Any SINGLECHAR that is not also registered in IDENTIFIER may not be used as part of an IDENTIFIER.
263Likewise,DOT, COLON, SEMICOLON, COMMA< LPAREN, RPAREN, LBRACE, RBRACE, LBRACKET, RBRACKET, any OPERATOR, and
264most symbols are not legal in identifiers. Many of these are however, legal inside a QUOTEDSTRING.
265
266#############
267## Parsing ##
268#############
269
270When you supply code to the parser, the scanner uses the above TOKENS and to determine how to match your formatting.
271A series of predefined routines is used, inm order to match code. For example:
272
273ffc script my_script{
274 void run(int id){
275 int x = 4;
276 for ( int q = 0; q < id; q++ ) exec_function();
277 }
278 void exec_function(){ x+=2;}
279}
280
281The scanner sees this as:
282
283FFC SCRIPT IDENTIFIER LBRACE
284VOID IDENTIFIER LPAREN RPAREN LBRACE
285INT IDENTIFIER ASSIGN NUMBER SEMICOLON
286FOR LPAREN INT IDENTIFIER ASSIGN NUMBER SEMICOLON IDENTIFIER LESSTHAN IDENTIFIER SEMICOLON IDENTIFIER INCREMENT RPAREN IDENTIFIER LPAREN RPAREN SEMICOLON
287RBRACE
288VOID IDENTIFIER LPAREN RPAREN LBRACE IDENTIFIER PLUSASSIGN NUMBER SEMICOLON RBRACE
289RBRACE
290
291This is then re-examined, by sorting sub-TOKENS into broader TOKENS:
292
293TYPE SCRIPT IDENTIFIER LBRACE
294TYPE IDENTIFIER LPAREN RPAREN LBRACE
295TYPE IDENTIFIER ASSIGN NUMBER SEMICOLON
296FOR LPAREN TYPE IDENTIFIER ASSIGN NUMBER SEMICOLON IDENTIFIER LESSTHAN IDENTIFIER SEMICOLON IDENTIFIER INCREMENT RPAREN IDENTIFIER LPAREN RPAREN SEMICOLON
297RBRACE
298TYPE IDENTIFIER LPAREN RPAREN LBRACE IDENTIFIER PLUSASSIGN NUMBER SEMICOLON RBRACE
299RBRACE
300
301From these tokens, it determines what the syntax is, using the following routines, to find loops, functions, and so forth:
302
303######################
304## PARSING ROUTINES ##
305######################
306
307#################
308## Upper-ASCII ##
309#################
310
311The parser does not itself use Auuper-ASCII, and use of Upper-ASCII is *not* legal in IDENTIFIERS,
312however it is possible (and legal) to include it in QUOTEDSTRINGS.
313
314###################
315## Code Comments ##
316###################
317
318Formatting for the Parser: The following are the symbols that the lexer eecognises, with regard to legal syntax.
319
320Global Statements
321
322The following TOKENS are part of DEFINITIONS, that the parser uses to scan lines.
323The scanner lexicon uses these as Sub-TOKENS when parsing scripts:
324
325
326
327
328Import
329
330
331
332####################################################
333## VarDecl : Variable Declarations and Statements ##
334####################################################
335
336The syntax for declaring variables is as follows:
337Type IDENTIFIER SEMICOLON int x;
338Type IDENTIFIER ASSIGN NUMBER SEMICOLON int x = 3;
339Type IDENTIFIER ASSIGN IDENTIFIER SEMICOLON int x = y;
340
341Variables may be of any TYPE, excluding VOID.
342
343#######################################
344## ConstDecl : Constant Declarations ##
345#######################################
346
347Constants are declared int he following syntax:
348
349CONST FLOAT IDENTIFIER ASSIGN NUMBER SEMICOLON const float THIRTYPOINTSIX = 30.6;
350CONST FLOAT IDENTIFIER ASSIGN MINUS NUMBER SEMICOLON const float NEGTHIRTYPOINTSIX = -30.6;
351CONST INT IDENTIFIER ASSIGN NUMBER SEMICOLON const float THIRTY= 30;
352CONST INT IDENTIFIER ASSIGN MINUS NUMBER SEMICOLON const float NEGTHIRTY = -30;
353
354Constants may only be type INT or FLOAT, and are resolve into numeric literals durinc compilation. The IDENTIFIER of the
355constant is not preserved after compilation.
356
357
358######################################
359## FuncDecl : Function Declarations ##
360######################################
361
362Function Declarations
363Type IDENTIFIER LPAREN ParamList RPAREN Block
364Type IDENTIFIER LPAREN RPAREN Block
365where block is the following syntax:
366LBRACE StmtList RBRACE
367LBRACE RBRACE
368
369########################
370## Array Declarations ##
371########################
372
373Declaring arrays may take any of the following formats:
374
375Type IDENTIFIER LBRACKET NUMBER RBRACKET
376 int MyArray[20];
377Type IDENTIFIER LBRACKET NUMBER RBRACKET ASSIGN LBRACE ArrayList RBRACE
378 int MyArray[5]={1,16,27,13,900};
379Type IDENTIFIER LBRACKET RBRACKET ASSIGN LBRACE ArrayList RBRACE
380 int MyArray[]={6,240,512.6,913.2198};
381
382Where 'Type' may be any legal type; and Arraylist is the field (set) of values as:
383LBRACE NUMBER | CONSTANT COMMA NUMBER | CONSTANT COMMA NUMBER | CONSTANT [...] RBRACE SEMICOLON
384 { 12, 17, MYCONSTANT, 16, 3 };
385 { 12 };
386 You may populate the list with as few as one element, uo to the size of the array declared, if you used an explicit size.
387 Otherwise, if you did not specify an explicit size, the array will autosize to the number of elements that you dseclare.
388 If you do not specify a size, and you do not include a set, the compiler will return an error.
389 Thus, the following is *illegal*:
390 int MyArray[];
391
392 You must either specify a size:
393 int MyArray[20];
394 ...or provide a set:
395 int MyArray[]={12,6,10,9,23};
396 In this case, the array willbe given a size of '5'.
397
398Arrays may be of any of the following types:
399FLOAT float
400INT int
401BOOL bool
402NPC npc
403ITEM item
404ITEMCLASS itemdata
405FFC ffc
406LWEAPON lweapon
407EWEAPON eweapon
408
409You may not declare a VOID type array.
410
411#########################
412## String Declarations ##
413#########################
414
415Declaring ZScript strings (not to be confused with ZQuest strings, in the string table; or true C strings, based ont he char
416or string types) follows this syntax:
417
418Type IDENTIFIER LBRACKET NUMBER RBRACKET ASSIGN QUOTEDSTRING
419Type IDENTIFIER LBRACKET RBRACKET ASSIGN QUOTEDSTRING
420
421For example:
422 int MyString[18]="This is a string.";
423 int MyString[]="This is a string.";
424 With strings, if you do not set a size, the string is sized to equal the number of chars in the QUOTEDSTRING
425 plus one (NULL) to terminate the string. If you set an *explicit size*, you must ensure that it is one value
426 greater than the number of chars that you anticipate storing in it, so that it will have a NULL char at the
427 end to terminate it.
428
429Strings are internally stored as arrays, with one element per character, plus one elemnt for NULL.
430Each character is stored in the array as its lower-ASCII equivalent:
431
432 int string[]="Is a string.";
433
434This is equivalent to:
435 int string[]={73,115,32,97,32,115,116,114,105,110,103,46,0};
436
437As you can saee, each ASCII char is converted to its numeric equivalent:
438I = 73, s = 115, (space) = 32, a = 97, (space) = 32, s = 115, t = 116, r = 114, i = 105, n = 110, g = 103, . = 46, NULL = 0
439
440You are free to create arrays with ASCII values directly. QUOTEDSTRING arrays are available as a convenient way to create
441strings in ZScript without needing to memorise ASCII charts, and to type natural syntax as the string itself.
442
443They merely automate the population of arrays holding numeric literals, and are not a proper *char* type, as C-based strings.
444
445QUOTEDSTRING should always have formatting as follows:
446QUOTE text QUOTE "textofstring"
447
448For this reason, it is not possible to use QUOTE ( " ) inside strings, as this is a tokenm that starts, or
449ends a QUOTEDSTRING. You may use the SINGLECHAR ' in sequence ( '' ) or ` in sequence (``) to simulate double-quotes
450inside a string, asthese are registered as SINGLECHAR.
451
452#########################
453## Script Declarations ##
454#########################
455
456Script Declarations:
457ScriptType SCRIPT IDENTIFIER ScriptBlock
458ScriptBlock:
459LBRACE ScriptStmtList RBRACE
460or
461LBRACE RBRACE
462ScriptStmtList is the field of the codeblock as text.
463
464Import Directives
465IMPORT QUOTEDSTRING
466
467
468
469#################################
470## ParamList : Parameter Lists ##
471#################################
472
473VarDecl COMMA ParamList
474
475############
476## Blocks ##
477############
478
479#######################
480## Stmt : Statements ##
481#######################
482
483Stmt : VarDecl SEMICOLON {$$ = $1;}
484 | ArrayDecl SEMICOLON {$$ = $1;}
485 | AssignStmt SEMICOLON {$$ = $1;}
486 | ShortcutAssignStmt SEMICOLON {$$=$1;}
487 | ForStmt {$$ = $1;}
488 | IfStmt {$$ = $1;}
489 | Block {$$ = $1;}
490 | ReturnStmt SEMICOLON {$$ = $1;}
491 | WhileStmt {$$ = $1;}
492 | DoStmt {$$ = $1;}
493 | SEMICOLON {$$ = new ASTStmtEmpty(@1);}
494 | Expr SEMICOLON {$$=$1;}
495 | BREAK SEMICOLON {$$ = new ASTStmtBreak(@1);}
496 | CONTINUE SEMICOLON {$$ = new ASTStmtContinue(@1);}
497 ;
498
499
500StmtNoSemi : VarDecl {$$ = $1;}
501 | ArrayDecl {$$ = $1;}
502 | AssignStmt {$$ = $1;}
503 | ShortcutAssignStmt {$$=$1;}
504 | ForStmt {$$ = $1;}
505 | IfStmt {$$ = $1;}
506 | Block {$$ = $1;}
507 | ReturnStmt {$$ = $1;}
508 | WhileStmt {$$ = $1;}
509 | DoStmt {$$ = $1;}
510 | {$$ = new ASTStmtEmpty(noloc);}
511 | Expr {$$=$1;}
512 | BREAK {$$ = new ASTStmtBreak(@1);}
513 | CONTINUE {$$ = new ASTStmtContinue(@1);}
514 ;
515
516ShortcutAssignStmt : DotExpr PLUSASSIGN Expr {SHORTCUT(ASTExprPlus,$1,$3,$$,@1,@2) }
517 | DotExpr MINUSASSIGN Expr {SHORTCUT(ASTExprMinus,$1,$3,$$,@1,@2) }
518 | DotExpr TIMESASSIGN Expr {SHORTCUT(ASTExprTimes,$1,$3,$$,@1,@2) }
519 | DotExpr DIVIDEASSIGN Expr {SHORTCUT(ASTExprDivide,$1,$3,$$,@1,@2) }
520 | DotExpr ANDASSIGN Expr {SHORTCUT(ASTExprAnd,$1,$3,$$,@1,@2) }
521 | DotExpr ORASSIGN Expr {SHORTCUT(ASTExprOr,$1,$3,$$,@1,@2) }
522 | DotExpr BITANDASSIGN Expr {SHORTCUT(ASTExprBitAnd,$1,$3,$$,@1,@2) }
523 | DotExpr BITORASSIGN Expr {SHORTCUT(ASTExprBitOr,$1,$3,$$,@1,@2) }
524 | DotExpr BITXORASSIGN Expr {SHORTCUT(ASTExprBitXor,$1,$3,$$,@1,@2) }
525 | DotExpr LSHIFTASSIGN Expr {SHORTCUT(ASTExprLShift,$1,$3,$$,@1,@2) }
526 | DotExpr RSHIFTASSIGN Expr {SHORTCUT(ASTExprRShift,$1,$3,$$,@1,@2) }
527 | DotExpr MODULOASSIGN Expr {SHORTCUT(ASTExprModulo,$1,$3,$$,@1,@2) }
528 ;
529
530
531AssignStmt : LVal ASSIGN Expr {$$ = new ASTStmtAssign((ASTStmt *)$1, (ASTExpr *)$3,@1);}
532 ;
533
534ForStmt : FOR LPAREN StmtNoSemi SEMICOLON Expr SEMICOLON StmtNoSemi RPAREN Stmt {ASTStmt *prec = (ASTStmt *)$3;
535 ASTExpr *term = (ASTExpr *)$5;
536 ASTStmt *incr = (ASTExpr *)$7;
537 ASTStmt *stmt = (ASTStmt *)$9;
538 $$ = new ASTStmtFor(prec,term,incr,stmt,@1);}
539 ;
540
541WhileStmt : WHILE LPAREN Expr RPAREN Stmt {ASTExpr *cond = (ASTExpr *)$3;
542 ASTStmt *stmt = (ASTStmt *)$5;
543 $$ = new ASTStmtWhile(cond,stmt,@1);}
544
545DoStmt : DO Stmt WHILE LPAREN Expr RPAREN {ASTExpr *cond = (ASTExpr *)$5;
546 ASTStmt *stmt = (ASTStmt *)$2;
547 $$ = new ASTStmtDo(cond,stmt,@1);}
548
549IfStmt : IF LPAREN Expr RPAREN Stmt {ASTExpr *cond = (ASTExpr *)$3;
550 ASTStmt *stmt = (ASTStmt *)$5;
551 $$ = new ASTStmtIf(cond,stmt,@1);}
552 | IF LPAREN Expr RPAREN Stmt ELSE Stmt {ASTExpr *cond = (ASTExpr *)$3;
553 ASTStmt *ifstmt = (ASTStmt *)$5;
554 ASTStmt *elsestmt = (ASTStmt *)$7;
555 $$ = new ASTStmtIfElse(cond,ifstmt,elsestmt,@1);}
556 ;
557
558ReturnStmt : RETURN Expr {$$ = new ASTStmtReturnVal((ASTExpr *)$2,@1);}
559 | RETURN {$$ = new ASTStmtReturn(@1);}
560 ;
561
562%%
563
564#####################
565## Dot Expressions ##
566#####################
567
568DotExpr : IDENTIFIER DOT IDENTIFIER
569IDENTIFIER LBRACKET Expr RBRACKET
570IDENTIFIER DOT IDENTIFIER LBRACKET Expr RBRACKET
571DotExpr ARROW IDENTIFIER
572DotExpr ARROW IDENTIFIER LBRACKET Expr RBRACKET
573
574#################
575## Expressions ##
576#################
577
578EXPR SYMBOL EXPR
579Where SYMBOL is of the following:
580OR AND BITOR BITXOR BITAND LSHIFT RSHIFT TIMES NOT MINUS DIVIDE MODULO PLUS MINUS BITNOT
581
582ExprList : Expr COMMA ExprList {ASTFuncCall *fc = (ASTFuncCall *)$3;
583 ASTExpr *e = (ASTExpr *)$1;
584 fc->addParam(e);
585 $$ = fc;}
586 | Expr {ASTFuncCall *fc = new ASTFuncCall(@1);
587 ASTExpr *e = (ASTExpr *)$1;
588 fc->addParam(e);
589 $$ = fc;}
590 ;
591
592############
593## MultOp ##
594############
595
596RelOp (GT, GE, LT, LE, EQ, NE ) : GREATERTHAN, GREATEROREQUAL, LESSTHAN, LESSOREQUAL, EQUAL, NOTEQUAL
597
598############
599## Factor ##
600############
601
602
603Factor : LPAREN Expr RPAREN {$$=$2;}
604 | DotExpr {$$ = $1;}
605 | DotExpr INCREMENT {ASTUnaryExpr *e = new ASTExprIncrement(@2);
606 ASTExpr *op = (ASTExpr *)$1;
607 e->setOperand(op);
608 $$=e;}
609 | INCREMENT DotExpr {ASTUnaryExpr *e = new ASTExprPreIncrement(@1);
610 ASTExpr *op = (ASTExpr *)$2;
611 e->setOperand(op);
612 $$=e;}
613 | DotExpr DECREMENT {ASTUnaryExpr *e = new ASTExprDecrement(@2);
614 ASTExpr *op = (ASTExpr *)$1;
615 e->setOperand(op);
616 $$=e;}
617 | DECREMENT DotExpr {ASTUnaryExpr *e = new ASTExprPreDecrement(@1);
618 ASTExpr *op = (ASTExpr *)$2;
619 e->setOperand(op);
620 $$=e;}
621 | NUMBER {ASTFloat *val = (ASTFloat *)$1;
622 $$ = new ASTNumConstant(val,@1);}
623 | SINGLECHAR {ASTString *as = (ASTString *)$1;
624 char val[15];
625 sprintf(val, "%d", as->getValue().at(1));
626 $$ = new ASTNumConstant(new ASTFloat(val,0,@1),@1);}
627 | BoolConstant {$$ = $1;}
628 | FuncCall {$$=$1;}
629 ;
630
631BoolConstant : TRUE {$$ = new ASTBoolConstant(true,@1);}
632 | FALSE {$$ = new ASTBoolConstant(false,@1);}
633 ;
634
635####################
636## Function Calls ##
637####################
638
639FuncCall : DotExpr LPAREN ExprList RPAREN {ASTFuncCall *fc = (ASTFuncCall *)$3;
640 ASTExpr *name = (ASTExpr *)$1;
641 fc->setName(name);
642 $$=fc;}
643 | DotExpr LPAREN RPAREN {ASTFuncCall *fc = new ASTFuncCall(@1);
644 ASTExpr *name = (ASTExpr *)$1;
645 fc->setName(name);
646 $$=fc;}
647 ;
648
649
650
651
652
653##########################
654## ZSCRIPT - FORMATTING ##
655##########################
656
657#####################
658## MAKING A SCRIPT ##
659## AND THE ##
660## run() ##
661## FUNCTION ##
662#####################
663
664################################
665## COMPILER ERROR DEFINITIONS ##
666################################
667
668Error codes are broken down by type:
669P** Preprocessing errors.
670S** Symbol table errors.
671T** Type-checking errors.
672G** Code Generation Errors
673** Array Errors ---We need to change these to A**
674
675Errors of each class are given unique numerical identifiers, ranging from 00 to 41, such as P01, or G33.
676The letter code will give you an indication of the type of error, and the full code will give you specific details.
677
678In ZQuest v2.50.2 and later, the compiler will report name of the script that generated (where possible).
679This applies only to errors caused by scripts, and not errors at a 'global' level, such as global functions.
680Thus, if you are using 2.50.2, or later, an error without a script name is likely to be caused at global scope.
681
682#####################
683## Specific Errors ##
684## Preprocessing ##
685#####################
686
687P00: Can't open or parse input file!
688
689Your script file contains illegal characters, or is not plain ASCII Text.
690
691Otherwise, it is possible that the compiler is unable to write to the disk, that the disk is out of space.
692
693Last, your file may be bad, such as a file in the qrong encoding format (not ASCII text).
694
695P01: Failure to parse imported file foo.
696
697Generally means that you are trying to call a file via the import directive that does not exist; or that
698you have a typo in the filename, or path.
699
700
701P02: Recursion limit of x hit while preprocessing.
702
703Caused by attempting to import a file recursively. For example:
704
705If you declare: import "script.z" ... and ... the file 'script.z' has the line: ' import "script.z" ' inside it.
706
707This error should no longer exist! Recursive imports should resolve as duplicate finction/variable/script declarations.
708
709Error P03: You may only place import statements at file scope.
710
711Import directives ( import "file.z" ) may only be declared at a global scope, not within
712a function, statement, or script.
713
714P35: There is already a constant with name 'foo' defined.
715You attempted to define the same constant more than once.
716The identifier (declared name) of all constants MUST be UNIQUE.
717
718
719#####################
720## Specific Errors ##
721## Symbol Table ##
722#####################
723
724S04: Function 'foo' was already declared with that type signature.
725
726You attempted to declare a function with the same parameters twice, int he same scope.
727This can occur when using different types, if the compiler cannot resolve a difference between the signatures.
728
729To fix this, remove one function,or change its signature (the arguments inside the parens) so that each is unique or;
730If you declare a functiona t a global scope, and the same at a local scope, remove one of the two.
731
732Note that return type is NOT enough to distinguish otherwise identical function declarations and that 'int' and 'float'
733types are the same type internally, so int/float is identical insofar as the signature is concerned.
734
735If two function type signatures are identical except that one has a parameter of type float where the other has the
736same parameter of type int, you will have a conflict.
737
738There are two additional subtle situations where you might get a conflict:
739
7401. A function declared at file scope might conflict with a function that's implicitly added to file scope
741by the preprocessor because of an import statement.
7422. A function might conflict with one already reserved by the ZScript standard library (std.zh).
743
744S05: Function parameter 'foo' cannot have void type.
745
746You cannot set a parameter (argument of a function) as a void type. e.g.:
747int foo(void var){ return var+1; }
748
749This is illegal, and the param 'var' muct be changed to a legal type.
750
751S06: Duplicate script with name 'foo' already exists.
752
753Script names must be wholly unique. For example, if there's already an ffc script named 'my_script' you cannot
754declare an item script with the name 'my_script'.
755
756S07: Variable 'foo' can't have type void.
757
758Variables at any scope may not have a void type. Only functions may have this type.
759
760S08: There is already a variable with name 'foo' defined in this scope.
761
762Variable identifiers must be unique at any given scope. Thus, this is illegal:
763
764ffc script my_ffc(){
765 void run(int x){
766 int v = 1;
767 int w = 10;
768 int x = 0.5;
769 int y = 13;
770 int z = v+w+x+y;
771 Trace(z);
772 }
773}
774
775As the variable 'x' is declared in the params of the run() function, it cannot be declared inside the function with
776the same identifier (name).
777
778
779S09: Variable 'foo' is undeclared.
780
781You attempted to reference a variable identifier (namme) that has not been declared.
782Usually this is due to a typo:
783
784int var;
785if ( val > 0 ) Link->X += var;
786
787Here, 'val' will return this error, as it was not declared.
788
789A variable with the give name could not be found in the current or any enclosing scope. Keep in mind the following subtleties:
7901. To access a different script's global variables, or to access a global variable from within a function delcared at file scope,
791you must use the dot operator: scriptname.varname.
7922. To access the data members of the ffc or item associated with a script, you must use the this pointer: this->varname.
7933. ZScript uses C++-style for loop scoping rules, so variables declared in the header part of the for loop cannot be
794accessed outside the loop:
795
796Code:
797
798for(int i=0; i<5;i++);
799i = 2; //NOT legal
800
801S10: Function 'foo' is undeclared.
802
803You attempted to call a function that was not declared. This is usually due to either a typo in your code, or failing
804to import a mandatory header. Check that you are importing 'std.zh' as well, as failing to do this will result in a slew
805of this error type.
806
807S11: Script 'foo' must implement void run().
808
809Every script must implement run() function call. The signature may be empty, or contain arguments.
810Zelda Classic uses all the code inside the run() function when executing the script, so a script without
811this function would do nothing, and will return an error.
812
813S12: Script 'foo's' run() must have return type void.
814
815Is this error even implemented? The run() function is automatic, and never declared by type, unless the user tries to declare
816a separate run(params) function with a different type.
817
818S26: Pointer types (ffc, etc) cannot be declared as global variables.
819
820/* It is illegal to declare a global variable (that is, a variable in script scope) or any type other than int, float, and bool.
821Why? Recall that global variables are permanent; they persist from frame to frame, screen to screen.
822Pointer types, on the other hand, reference ffcs or items that are transitory; they become stale after a single WAITFRAME,
823so it makes no sense to try to store them for the long term.
824*/
825
826This explanation may no longer be true, as pointers may no longer be dereferenced by Waitframe(),
827and global pointers may also be implemented in a future version.
828
829
830S30: Script foo may have only one run method.
831
832You may not call a run() function more than once per script.
833Your run method may have any type signature, but because of this flexibility, the compiler cannot
834determine which run script it the "real" entry point of the script if multiple run methods are declared.
835
836S32: Script foo is of illegal type.
837
838The only legal script tokens are: global, ffc, and item. You cannot declare other types (such as itemdata script).
839
840S38: Script-scope global variable declaration syntax is deprecated; put declarations at file scope instead.
841You cannot declare a global variable in a global script, outside the run function.
842
843Example:
844
845global script active{
846 int x;
847 void run(){
848 x = 16;
849 }
850}
851
852This is ILLEGAL. The declaration of variable 'x' must either be at a global scope, or at the scope of the
853run function. Do this, instead:
854
855int x;
856global script active{
857 void run(){
858 x = 16;
859 }
860}
861
862This creates a global variable at the file scope.
863
864S39: Array 'foo' can't have type void.
865Arrays may be types of int, float, bool, ffc, item, itemdata, npc, lweapon, or eweapon; but arrays
866with a void type are illegal.
867
868S40: Pointer types (ffc, etc) cannot be declared as global arrays.
869As of 2.50.2, global array declarations may only have the following types:
870int, float, bool
871Any other type is illegal.
872
873S41: There is already an array with name 'foo' defined in this scope.
874As with variables, and functions, arrays must have unique identifiers within the same scope.
875
876###################
877## LEXING ERRORS ##
878###################
879L24: Too many global variables.
880
881The assembly language to which ZScript is compiled has a built-in maximum of 256 global variables. ZScript can't do anything if you exceed this limit.
882
883#####################
884## Specific Errors ##
885## Type Checking ##
886#####################
887
888T13: Script 'foo' has id that's not an integer.
889
890/* I do not know what can cause this error, or if it ever occurs. */
891
892T14: Script 'foo's' id must be between 0 and 255.
893
894Occurs if you try to load more than 256 scripts of any given type at any given time.
895/* The maximum number of concurrent scripts (of any given type?) is 256. */
896
897T15: Script 'foo's' id is already in use.
898You attempted to laod two scripts into the same slot.
899/* I do not know if this is EVER possible. */
900
901T16: Cast from foo to bar.
902
903The only "safe" implicit casts are from int to float and vice-versa (since they are the same type),
904and from int (or float) to bool (0 becomes false, anything else true).
905The results of any other kind of cast are unspecified.
906
907/*
908Is this error still in effect? Casting from npc to itemdata, or others, usually results in a different error code.
909Further, Cannot cast from wtf to int, is a thing.
910*/
911
912Explicit casts are unimplemented and unnecessary.
913
914T17: Cannot cast from foo to bar.
915
916You attempted to typecast illegally, such as tyring to typecast from bool to float.
917
918T18: Operand is void.
919Occurs if you try to use a void type value in an operation.
920/* I do not know if this is EVER possible. */
921
922T19: Constant division by zero.
923
924While constant-folding, the compiler has detected a division by zero.
925
926Note that only division by a CONSTANT zero can be detected at compile time.
927The following code, for instace, compiles with no errors but will most likely still crash ZC:
928
929Code:
930
931int x=0;
9321/0;
933
934
935T20: Truncation of constant x.
936
937Constants can only be specified to four places of decimal precision, withing the legal range of values.
938Any extra digits are simply ignored by the compiler, which then issues this warning.
939
940Any values greater than MAX_CONSTANT, or less then MIN_CONSTANT will result in this error.
941
942## Applies to variables, but does not throw an error:
943Both floats and ints can only be specified to four places of decimal precision.
944Any extra digits are simply ignored by the compiler, which then issues this warning.
945
946Any values greater than MAX_VARIABLE, or less then MIN_VARIABLE will result in this error.
947
948########
949
950T21: Could not match type signature 'foo'.
951
952When calling a function, you used the wrong number, or types, of parameters.
953The compiler can determine no way of casting the parameters of a function call so that they
954match the type signature of a declared function.
955
956For instance, in the following snippet
957Code:
958
959int x = Sin(true);
960
961since true cannot be cast to a float, this function call cannot be matched to the library function Sin, triggering this error.
962
963
964T22: Two or more functions match type signature 'foo'.
965
966If there is ambiguity as to which function declaration a function call should matched to,
967the compiler will attempt to determine the "best fit."
968These measures are however occasionally still not enough. Consider for instance the following snippet:
969Code:
970
971void foo(int x, bool y) {}
972void foo(bool x, int y) {}
973foo(1,1);
974
975matching either of the two foo declarations requires one cast, so no match can be made.
976In contrast, the following code has no error:
977Code:
978
979void foo(int x, bool y) {}
980void foo(bool x, bool y) {}
981foo(1,1);
982
983(The first foo function is matched.)
984
985It is best to design functions so that noambiguity is possible, by addign extra params, to change the signature or by using
986different identifiers (function names) when using more params is not desirable.
987
988T23: This function must return a value.
989
990All return statements must be followed by an expression if the enclosing function returns a value.
991Note that the compiler does NOT attempt to verify that all executions paths of a function with non-void
992return type actually returns a value; if you fail to return a value, the return value is undefined.
993For instace, the following is a legal (though incorrect) ZScript program:
994
995int foo() {}
996
997/* I don't believe anythign ever returns this error.
998I've seen functions with int/float/bool types, and no returns compile, without errors.
999Perhaps we should fix this, and issue a warning during compilation? */
1000
1001T25: Constant bitshift by noninteger amount; truncating to nearest integer.
1002
1003The bitshift operators (<< and >>) require that their second parameters be whole integers.
1004
1005T27: Left of the arrow (->) operator must be a pointer type (ffc, etc).
1006
1007It makes no sense to write "x->foo" if x is of type int.
1008You may only use the dereference (->) operator on pointer types.
1009
1010T28: That pointer type does not have a function 'foo'.
1011
1012You tried to use the dereference operator (->) to call a function that does not exist for the pointer type being dereferenced.
1013Check the list of member variables and functions and verify you have not mistyped the function you are trying to call.
1014
1015This generally occurs when calling internal functions, using the incorrect class, or namespace, such as:
1016
1017Game->Rectangle() instead of Screen->Rectangle()
1018
1019The extra std.zh component 'shortcuts.zh' assists in preventing this error type.
1020
1021
1022T29: That pointer type does not have a variable 'foo'.
1023
1024You tried to use the dereference operator (->) to call a member variable that does not exist for the pointer type being dereferenced.
1025Check the list of member variables and verify you have not mistyped the variable you are trying to call.
1026
1027This generally occurs when calling internal variables, using the incorrect class, or namespace, such as:
1028
1029Link->D[] instead of Screen->D[]
1030
1031/* The extra std.zh component 'shortcuts.zh' assists in preventing this error type.
1032Probaby not, as this requires silly amounts of functions to handle variables with identical identifiers.
1033C'est la vie. perhaps we'll do it, but I really am not fond of the idea. */
1034
1035As above, but the member variable you tried to access does not exist.
1036
1037Error T31: The index of 'foo' must be an integer.
1038
1039/* This has been deprecated, so who cares? */
1040
1041
1042T36: Cannot change the value of constant variable 'foo'.
1043
1044You cannot assign a CONSTANT to another value.
1045
1046T37: Global variables can only be initialized to constants or globals declared in the same script.
1047You cannot (directly) simultaneously declare, and initialise a global value using the value of a variable at
1048the scope of another script, or function.
1049
1050Example:
1051int x = script.a;
1052ffc script foo{
1053 int a = 6;
1054 void run(){
1055 for ( int q = 9; q < Rand(15); q++ ) a++;
1056 }
1057}
1058
1059This is ILLEGAL. You cannot initialise the value of the global variable 'x' using the local value
1060of 'a' in the ffc script 'foo'.
1061
1062/* I believe this is deprecated, as I do not believe that script level declarations remain legal */
1063
1064T45 (old version, T38): Arrays can only be initialized to numerical values
1065You attempted to declare an array using a floating point value (e.g. 10.5), constant or equation,
1066rather than a numeric literal.
1067
1068
1069 Consider that you want to declare an array with an explicit size of '40':
1070 These are ILLEGAL:
1071 int my_arr[26+14];
1072 const int CONSTANT = 30;
1073 int my_arr[CONSTANT];
1074 int my_arr[CONSTANT/2+20]
1075
1076 YOu must declare an arrray with a numeric literal:
1077 int my_array[40];
1078 This is the only legal way to declare the size of an array as of 2.50.2.
1079
1080
1081#####################
1082## Specific Errors ##
1083## @Generation ##
1084#####################
1085
1086
1087G33: Break must lie inside of an enclosing for or while loop.
1088
1089The 'break' keyword aborts the loop (in a for, while, or do statement) in which it is called.
1090You must be in a loop to break out of one, so calling 'break' outside of a loop is illegal.
1091
1092
1093G34: Continue must lie inside of an enclosing for or while loop.
1094
1095The 'continue' keyword halts a loop, and repeats the loop from its head (in a for, while, or do statement) in which it is called.
1096You must be in a loop to continue one, so calling 'continue' outside of a loop is illegal.
1097
1098As the above error, but with the continue keyword. Continue aborts the current iteration of the loop and skips to the next iteration.
1099
1100
1101##################
1102## Array Errors ##
1103##################
1104
1105Error A42 (old, Error O1): Array is too small. ( Converting to A42 in 2.50.3 )
1106You attempted to declare an array, with a set of values, where the number of values in the set
1107exceeds an explicit array size declaration:
1108
1109int foo[4]={1,2,3,4,5};
1110The declared size is '4', but you tried to initialise it with five elements.
1111
1112/* THis doesn't seem right, as this seems to be covered by Err 02. Check the source to see what causes this. */
1113
1114Error O2: Array initializer larger than specified dimensions. ( Converting to A43 in 2.50.3)
1115You attempted to initialise an array, with a set of values, where the number of values in the set
1116exceeds an explicit array size declaration:
1117
1118int foo[4]={1,2,3,4,5};
1119The declared size is '4', but you tried to initialise it with five elements.
1120
1121Error O3: String array initializer larger than specified dimensions, space must be allocated for NULL terminator.
1122( Convering to A44 in 2.50.3 )
1123YOu attempted to seclare a QUOTEDSTRING of an explicit size, but you didn;t add space
1124for the NULL terminator; or you used more chars than you allocated:
1125
1126int my_string[17]="This is a string.";
1127 THis allocates only enough indices for the chars, but not for the NULL terminator.
1128 The array size here needs to be 18.
1129int my_string[12]="THis is a string.";
1130 You tried to initialise a QUOTEDSTRING that is longer than the array size.
1131 The minimum array size for this is '18'.
1132
1133 It is generally best either to declare strings with an implicit size (set by the initialiser):
1134 int my_string[]="This is a string";
1135 This reads the nuber of chars, adds one to the count (for NULL), and sizes the array to 18.
1136 ...or...
1137 Declare the string with an arbitrarily large size:
1138 int my_string[256]="This is a string";
1139 This reserves 256 chars. Only 18 are used, and the rest of the indices
1140 are initialised as '0' (NULL). YOu may later populate the unused space, if desired.
1141
1142
1143#################
1144## Misc Errors ##
1145#################
1146
1147FATAL FATAL ERROR I0: bad internal error code
1148A fallback error is no other type matches the problem.
1149
1150/* I have no idea what causes this. Be afraid, very afraid. */
1151
1152/* OTHER ERRORS
1153Document any further error codes here.
1154We need to convert the array errors from raw numeric, to A** codes.
1155*/
1156
1157
1158########################
1159## OPERATIONAL ERRORS ##
1160###################################################################################################
1161## These errors occur only during the operation of script execution (i.e. when running a script, ##
1162## in Zelda Classic while playing a quest). ##
1163## --------------------------------------------------------------------------------------------- ##
1164## In ZC versions 2.50.2, and later, operational script errors will return the ID of the script ##
1165## from which they were generated. ##
1166###################################################################################################
1167
1168//! These errors will be reported to allegro.log (or the ZConsole) when scripts run.
1169
1170
1171
1172////////////////////
1173/// Stack Errors ///
1174////////////////////
1175
1176 "Stack over or underflow, stack pointer = %ld\n"
1177
1178 "Invalid ZASM command %ld reached\n"
1179
1180////////////////////
1181/// Array Errors ///
1182////////////////////
1183
1184 "Invalid value (%i) passed to '%s'\n"
1185 "Invalid index (%ld) to local array of size %ld\n"
1186
1187You attempted to reference an array index that is either too small, or too large.
1188Check the size of your array, and try again.
1189Perhaps you have a for loop, or other loop that is parsing the array, and trying to read beyond its index ranges.
1190
1191
1192 "Invalid pointer (%i) passed to array (don't change the values of your array pointers)\n"
1193
1194Array pointers values in operation are 1 through 4095, ( and 4096 to 8164? as declared global pointers ?).
1195An array may not have a pointer of '0', nor may you reference an array for which a pointer does not exist.
1196Often, this error is caused by attempting to reference an array that you created, without updating the saved game slot
1197as the old save does not have the array allocated, but the script is attempting to reference its global ID.
1198
1199 "Script tried to deallocate memory at invalid address %ld\n"
1200 "Script tried to deallocate memory that was not allocated at address %ld\n"
1201
1202/* Script attempted to change the value of an array index // that does not exist // due to the inability to declare an array
1203because too many registers are in use?
1204
1205
1206 "You were trying to reference an out-of-bounds array index for a screen's D[] array (%ld); valid indices are from 0 to 7.\n"
1207You attempted to read, or write to a Screen->D[register] that was less than 1, or greater than 10.
1208Check for loops, and vriables that read/write to Screen->D for any that can fall outside the legal range.
1209
1210 "Array initialized to invalid size of %d\n"
1211You attempted to init array to a size less than 1, or a size greater than 214747, or;
1212You attempted to init array with a constant, a variable, a formula, or with a floating point value.
1213Arrays may ONLY be initialised with numeric literals (integers only) between 1 and 214747.
1214
1215 "%d local arrays already in use, no more can be allocated\n", MAX_ZCARRAY_SIZE-1);
1216The maximum number of arrays in operation at one time is 4095.
1217
1218"Invalid pointer value of %ld passed to global allocate\n"
1219 !
1220
1221/////////////////////////////
1222/// Object Pointer Errors ///
1223/////////////////////////////
1224
1225 "Invalid NPC with UID %ld passed to %s\nNPCs on screen have UIDs "
1226 "Invalid item with UID %ld passed to %s\nItems on screen have UIDs "
1227 "Invalid lweapon with UID %ld passed to %s\nLWeapons on screen have UIDs "
1228 "Invalid eweapon with UID %ld passed to %s\nEWeapons on screen have UIDs "
1229
1230 "Script attempted to reference a nonexistent NPC!\n"
1231 "You were trying to reference the %s of an NPC with UID = %ld; NPC on screen are UIDs "
1232
1233 "Script attempted to reference a nonexistent item!\n"
1234 "You were trying to reference an item with UID = %ld; Items on screen are UIDs: "
1235
1236 "Script attempted to reference a nonexistent LWeapon!\n"
1237 "You were trying to reference the %s of an LWeapon with UID = %ld; LWeapons on screen are UIDs "
1238
1239 "Script attempted to reference a nonexistent EWeapon!\n"
1240 "You were trying to reference the %s of an EWeapon with UID = %ld; EWeapons on screen are UIDs "
1241
1242You attempted to reference a game object that has a maximum legal range of 1 to 255.
1243It is possible that you tried to read outside that range, or that the pointer that you were loading is not valid.
1244Check NumItems(), NumLWeapons(), NumEWeapons(0, and NumNPCs() before referencing them; and verify that the object ->IsValid()
1245Check for loops that may attempt ro reference items outside of the range that actually exist.
1246Look for any for loops that access these objects, that start, or end at zero.
1247
1248The best way to ensure this does not occur, is to make a for loop as follows:
1249
1250 for ( int q = 1; q < Screen->NumLWeapons; q++ )
1251
1252 //or//
1253
1254 for ( int q = Screen->NumLWeapons(); q > 0; q-- )
1255
1256...replacing NumLWeapons() withthe appropriate type that you are attempting to load.
1257
1258You may be attempting to refrence a pointer that has fallen out of scope.
1259You may be attempting to reference a pointer that is no longer valid, or has been removed.
1260Check ( pinter->IsValid() ) by itself, to ensure this does not occur:
1261
1262 if ( pointer->IsValid ) {
1263 if ( pointer->ID == LW_FIRE ) //Do things.
1264 }
1265
1266This helps to prevent loading invalid pointers.
1267
1268////////////////////////////////
1269/// Maths and Logical Errors ///
1270////////////////////////////////
1271
1272"Script attempted to divide %ld by zero!\n"
1273"Script attempted to modulo %ld by zero!\n"
1274
1275"Script attempted to pass %ld into ArcSin!\n"
1276"Script attempted to pass %ld into ArcCos!\n"
1277"Script tried to calculate log of 0\n"
1278"Script tried to calculate log of %f\n"
1279"Script tried to calculate ln of 0\n"
1280"Script tried to calculate ln of %f\n"
1281"Script attempted to calculate 0 to the power 0!\n"
1282"Script attempted to calculate square root of %ld!\n"
1283
1284Look for scripts that pass a variable into these functions, or use a variable in a mathematical operation, that
1285may be zero at any point, and correct it to ensure that it is never zero, or that it is never illegal for the type of
1286mathematical operation you wish to perform.
1287
1288Chweck for any hardcoded values, or constants that are in use with these functions that may be illegal, or irrational.
1289
1290////////////////////////////////
1291/// System Limitation Errors ///
1292////////////////////////////////
1293
1294"Couldn't create lweapon %ld, screen lweapon limit reached\n"
1295"Couldn't create eweapon %ld, screen eweapon limit reached\n"
1296"Couldn't create item \"%s\", screen item limit reached\n"
1297"Couldn't create NPC \"%s\", screen NPC limit reached\n"
1298
1299You may create a maximum of 255 of any one object type on the screen at any one time.
1300Look for anything that is generating extra pointers, and add a statement such as:
1301 if ( Screen->NumNPCs() < 255 )
1302
1303 "Max draw primitive limit reached\n"
1304The maximum number of drawing function calls, per frame, is 1,000.
1305
1306/////////////////////
1307/// String Errors ///
1308/////////////////////
1309
1310 "Array supplied to 'Game->GetDMapMusicFilename' not large enough\n"
1311 "Array supplied to 'Game->GetSaveName' not large enough\n"
1312 "String supplied to 'Game->GetSaveName' too large\n"
1313 "Array supplied to 'Game->GetMessage' not large enough\n"
1314 "Array supplied to 'Game->GetDMapName' not large enough\n"
1315 "Array supplied to 'Game->GetDMapTitle' not large enough\n"
1316 "Array supplied to 'Game->GetDMapIntro' not large enough\n"
1317 "Array supplied to 'itemdata->GetName' not large enough\n"
1318 "Array supplied to 'npc->GetName' not large enough\n"
1319
1320The buffer for these actions must be equal to the size of the text to load into it, plus one, for NULL.
1321
1322If you wish to load a game name, with Game->LoadSaveName(), and the name on the file select is FOO, you must
1323supply a buffer with a size of [4] to hold it. (Three chars in the name, plus one for NULL.)
1324
1325////////////////////
1326/// Misc. Errors ///
1327////////////////////
1328
1329 "Waitdraw can only be used in the active global script\n"
1330You attempted to call Waitdrw() in an ffc script, or an item script; or in your global OnContinue,
1331global OnExit, or ~Init scripts.
1332You may only use the Waitdraw() function from a global active script.
1333
1334 "No other scripts are currently supported\n"
1335? You should never see this. May indicate that you have attempted to load more scripts than ZC can handle.
1336
1337
1338 "Invalid value (%i) passed to '%s'\n"
1339!
1340
1341 "Global scripts currently have no A registers\n"
1342This error can only occur if you are coding ZASM, and attempt to utilise an Address register with a global script.
1343
1344////////////////////////
1345/// Script Reporting ///
1346////////////////////////
1347
1348 //Events that will be recorded if Quest Rule 'Log Game Events to Allegro.log' is enabled:
1349
1350"Script created lweapon %ld with UID = %ld\n"
1351"Script created eweapon %ld with UID = %ld\n"
1352"Script created item \"%s\" with UID = %ld\n"
1353"Script created NPC \"%s\" with UID = %ld\n"
1354
1355When any new game object is generated by script, and reporting is enabled, the lweapon, and the name of the
1356script that generated it, will be reported to allegro.log.
1357
1358
1359##############################
1360## MIXING ZASM AND ZSCRIPT ##
1361##############################
1362
1363n general adding ASM scripts in slots unused by ZScript is safe. Just realize that if you write to global or screen registers, you may be writing over values used by some of the ZScript scripts.
1364
1365After every compilation the full ASM output of the compiler is written to allegro.log, so by inspecting this output you can determine what global variables are being used by ZScript, so that you can avoid (or not avoid!) using them in your ASM scripts.
1366
1367On the other hand, directly modifying the ASM output of a ZScript compilation requires very, very great care, for several reasons:
1368
13691. Almost all of the D registers (currently D0-D6) are reserved as important scratch spaces for things like computing the stack frame offset of local variables, and should not be overwritten by foreign code.
1370
13712. ZScript-compiled code is heavily reliant on the stack for storing everything from local variables to parameters of function calls to this pointers. The state of the stack must thus also be preserved by foreign code.
1372
13733. Changing the line numbers of ZScript code requires a lot of work verifying that references to those line numbers (in things like GOTO) are modified accordingly. Even more tricky is that line numbers are sometimes indirectly stored in registers, pushed onto the stack, then popped off much later and used as return values via GOTOR.
1374
13754. If you ever decide to modify the ZScript code and recompile, you'll of course need to reapply your "patch."