vrtc / pjass (public) (License: BSD) (since 2023-08-03) (hash sha1)
pjass is a free Jass scripting language parser. This repository is a fork of lep/pjass. The goal is to add Debian packaging. As of the time of this writing, it works for current stable, that is Debian 12 (bookworm).
List of commits:
Subject Hash Author Date (UTC)
Improved errors for function-calls. 5a50178a03c5aa3d153e8699070942327fde0b7b lep 2016-08-27 18:44:01
A very strange error with newlines and comments. d822cacbd889fe723102102c8a09d578d90f013e lep 2016-08-21 09:15:00
Added +nosyntaxerror and +nosemanticerror e755e12b3cab1d5069574e34d22633dd420bb230 lep 2016-05-07 13:42:57
Added +shadow description to -h 6a62b1ecf773175992a2a430a178fffb5532e467 lep 2016-03-13 19:35:20
Reduced duplicate code from variable decleration. 01d6f01ebf7c2df9f58aea1bba61bae8a270b520 lep 2016-03-13 19:03:34
Added optional variable shadowing warning. 2a0b36f50d2850c4c2ff09f503e6ffad6abf58d9 lep 2016-03-13 14:30:36
Removed the +s and +e<n> flags. 4ab97e853531f2767136602d88c6a86897089eea lep 2016-03-13 10:52:37
Added help target to Makefile a713b03be873950d11e62a7b9e4f2d9a8d2e0945 lep 2016-03-03 16:02:34
Removed strict downcasting check. 5f6ffd725b2ac9d24eff5917d96ceeeaaf748e5f lep 2016-03-03 16:00:49
Added filterreturnsbool check which can be enabled via //# filter 6828cb5e726e7f57cad0ec3f794209c2012c7908 lep 2016-03-03 15:58:59
Moved code into seperate files. 047c531a1c3affb43f53d102c94e765d772ecff3 lep 2016-02-17 20:57:30
Also pack testfiles into the release zip. e2d8ca45c7175b4f0192ddb6202ae71059369495 lep 2016-02-01 15:15:03
Fixed all Warnings. 981e0b8b51eebb4904a42c58c825fa10185f5d23 lep 2016-02-01 15:12:38
Added a test which checks if the utf8-bom can be used as whitespace. cb0ebe275982a65a2ebbd4aca831da4e31739eba lep 2016-01-31 15:04:12
Added utf8 bom as another whitespace token. ea1572ceaa7743fcdff89f206e24540df6358e7b lep 2016-01-31 13:23:27
Added tests to the git repo. 6aca6f760084ee65f8cdd469b18ad5cb37c42ee3 lep 2016-01-17 10:44:56
FreeBsd patches. 6c3acc1dff6ecd5fa486506fabed077be5347afc lep 2016-01-17 10:23:48
Cleaned up string and comment handling in the lexer ebec6e67e248bef82bf92416733b394399c4e1d4 lep 2016-01-17 09:51:44
Added \r, \n (\x10, \x13) as invalid escape characters. 85d0c7e4453c1879bcbc4db8be28527c5ce9f4f7 lep 2016-01-06 13:16:49
Fixed another rare crash. b6edcc3cfd5c1c837318b0efa5ded6f16e86b403 lep 2015-12-21 19:02:41
Commit 5a50178a03c5aa3d153e8699070942327fde0b7b - Improved errors for function-calls.
* Reports the function name which call to goes wrong.
* Reports the missing arguments when a function call has too few parameters.
* Reports the parameter name when the type cannot be converted.
Author: lep
Author date (UTC): 2016-08-27 18:44
Committer name: lep
Committer date (UTC): 2016-08-27 18:44
Parent(s): d822cacbd889fe723102102c8a09d578d90f013e
Signer:
Signing key:
Signing status: N
Tree: 957971868ed19047a619d4d25b65e264c03172a8
File Lines added Lines deleted
grammar.y 18 3
misc.c 45 19
misc.h 2 1
tests/should-fail/not-enough-parameters.j 7 0
tests/should-fail/too-many-arguments.j 5 0
tests/should-fail/wrong-types-in-call.j 7 0
File grammar.y changed (mode: 100644) (index bfa2fb6..8c58c0e)
... ... funcdefncore: funcbegin localblock codeblock funcend {
318 318 } }
319 319 fnannotations = 0; fnannotations = 0;
320 320 } }
321 | funcbegin localblock codeblock {yyerrorex(syntaxerror, "Missing endfunction"); ht_clear(&params); ht_clear(&locals); ht_clear(&initialized); curtab = &globals; fnannotations = 0;}
321 | funcbegin localblock codeblock {
322 yyerrorex(syntaxerror, "Missing endfunction");
323 ht_clear(&params);
324 ht_clear(&locals);
325 ht_clear(&initialized);
326 curtab = &globals;
327 fnannotations = 0;
328 }
322 329 ; ;
323 330
324 funcend: ENDFUNCTION { ht_clear(&params); ht_clear(&locals); ht_clear(&initialized); curtab = &globals; inblock = 0; inconstant = 0; infunction = 0; }
331 funcend: ENDFUNCTION {
332 ht_clear(&params);
333 ht_clear(&locals);
334 ht_clear(&initialized);
335 curtab = &globals;
336 inblock = 0;
337 inconstant = 0;
338 infunction = 0;
339 }
325 340 ; ;
326 341
327 342 returnorreturns: RETURNS returnorreturns: RETURNS
 
... ... localblock: endlocalsmarker
520 535 | newline localblock | newline localblock
521 536 ; ;
522 537
523 endlocalsmarker: /* empty */ { fCurrent = 0; }
538 endlocalsmarker: /* empty */ { fCurrent = NULL; }
524 539 ; ;
525 540
526 541 lvardecl: LOCAL vardecl { } lvardecl: LOCAL vardecl { }
File misc.c changed (mode: 100644) (index dd7921c..679d3ed)
... ... void validateGlobalAssignment(const char *varname)
263 263 } }
264 264
265 265
266 void checkParameters(const struct paramlist *func, const struct paramlist *inp, bool mustretbool)
266 void checkParameters(const struct funcdecl *fd, const struct paramlist *inp, bool mustretbool)
267 267 { {
268 const struct paramlist *func = fd->p;
268 269 const struct typeandname *fi = func->head; const struct typeandname *fi = func->head;
269 270 const struct typeandname *pi = inp->head; const struct typeandname *pi = inp->head;
270 271 while(true) { while(true) {
271 272 if (fi == NULL && pi == NULL) if (fi == NULL && pi == NULL)
272 273 return; return;
273 274 if (fi == NULL && pi != NULL) { if (fi == NULL && pi != NULL) {
274 yyerrorex(semanticerror, "Too many arguments passed to function");
275 char buf[1024];
276 snprintf(buf, 1024, "Too many arguments passed to function %s. ", fd->name);
277 yyerrorex(semanticerror, buf);
275 278 return; return;
276 279 } }
277 280 if (fi != NULL && pi == NULL) { if (fi != NULL && pi == NULL) {
278 yyerrorex(semanticerror, "Not enough arguments passed to function");
281 char buf[1024];
282 snprintf(buf, 1024, "Not enough arguments passed to function %s. ", fd->name);
283 strncat(buf, "Still missing: ", 1024);
284 bool addComma = false;
285 for(; fi; fi = fi->next){
286 if(addComma){
287 strncat(buf, ", ", 1024);
288 }
289 strncat(buf, fi->name, 1024);
290 addComma = true;
291 }
292 yyerrorex(semanticerror, buf);
279 293 return; return;
280 294 } }
281 canconvert(pi->ty, fi->ty, 0);
295 char buf[1024];
296 if(! canconvertbuf(buf, 1024, pi->ty, fi->ty )){
297 char pbuf[1024];
298 snprintf(pbuf, 1024, " in parameter %s in call to %s", fi->name, fd->name);
299 strncat(buf, pbuf, 1024);
300 yyerrorex(semanticerror, buf);
301 }
282 302 if(flagenabled(flag_filter) && mustretbool && typeeq(pi->ty, gCodeReturnsNoBoolean)){ if(flagenabled(flag_filter) && mustretbool && typeeq(pi->ty, gCodeReturnsNoBoolean)){
283 303 yyerrorex(semanticerror, "Function passed to Filter or Condition must return a boolean"); yyerrorex(semanticerror, "Function passed to Filter or Condition must return a boolean");
284 304 return; return;
 
... ... const struct typenode *combinetype(const struct typenode *n1, const struct typen
331 351 return mkretty(gNone, ret); return mkretty(gNone, ret);
332 352 } }
333 353
334 // this is used for reducing expressions in many places (if/exitwhen conditions, assignments etc.)
335 void canconvert(const struct typenode *ufrom, const struct typenode *uto, const int linemod)
354 bool canconvertbuf(char *buf, size_t buflen, const struct typenode *ufrom, const struct typenode *uto)
336 355 { {
337 356 const struct typenode *from = ufrom, *to = uto; const struct typenode *from = ufrom, *to = uto;
338 char ebuf[1024];
339 357 if (from == NULL || to == NULL) if (from == NULL || to == NULL)
340 return;
358 return true;
341 359 if (typeeq(from, gAny) || typeeq(to, gAny)) if (typeeq(from, gAny) || typeeq(to, gAny))
342 return;
360 return true;
343 361 if (isDerivedFrom(from, to)) if (isDerivedFrom(from, to))
344 return;
362 return true;
345 363 if (getTypePtr(from)->typename == NULL || getTypePtr(to)->typename == NULL) if (getTypePtr(from)->typename == NULL || getTypePtr(to)->typename == NULL)
346 return;
364 return true;
347 365 if (typeeq(from, gNone) || typeeq(to, gNone)) if (typeeq(from, gNone) || typeeq(to, gNone))
348 return;
366 return true;
349 367 from = getPrimitiveAncestor(from); from = getPrimitiveAncestor(from);
350 368 to = getPrimitiveAncestor(to); to = getPrimitiveAncestor(to);
351 369 if (typeeq(from, gNull) && !typeeq(to, gInteger) && !typeeq(to, gReal) && !typeeq(to, gBoolean)) if (typeeq(from, gNull) && !typeeq(to, gInteger) && !typeeq(to, gReal) && !typeeq(to, gBoolean))
352 return;
370 return true;
353 371 if (typeeq(from, gInteger) && (typeeq(to, gReal) || typeeq(to, gInteger))) if (typeeq(from, gInteger) && (typeeq(to, gReal) || typeeq(to, gInteger)))
354 return;
372 return true;
355 373 if (typeeq(from, to) && (typeeq(from, gBoolean) || typeeq(from, gString) || typeeq(from, gReal) || typeeq(from, gInteger) || typeeq(from, gCode))) if (typeeq(from, to) && (typeeq(from, gBoolean) || typeeq(from, gString) || typeeq(from, gReal) || typeeq(from, gInteger) || typeeq(from, gCode)))
356 return;
374 return true;
357 375
358 snprintf(ebuf, 1024, "Cannot convert %s to %s", ufrom->typename, uto->typename);
359 yyerrorline(semanticerror, lineno + linemod, ebuf);
360 return;
376 snprintf(buf, buflen, "Cannot convert %s to %s", ufrom->typename, uto->typename);
377 return false;
378 }
379
380 // this is used for reducing expressions in many places (if/exitwhen conditions, assignments etc.)
381 void canconvert(const struct typenode *ufrom, const struct typenode *uto, const int linemod)
382 {
383 char buf[1024];
384 if(! canconvertbuf(buf, 1024, ufrom, uto ) ){
385 yyerrorline(semanticerror, lineno + linemod, buf);
386 }
361 387 } }
362 388
363 389 // this is used for return statements only // this is used for return statements only
 
... ... union node checkfunccall(const char *fnname, struct paramlist *pl)
557 583 } }
558 584 if (fd == fCurrent && fCurrent) if (fd == fCurrent && fCurrent)
559 585 yyerrorex(semanticerror, "Recursive function calls are not permitted in local declarations"); yyerrorex(semanticerror, "Recursive function calls are not permitted in local declarations");
560 checkParameters(fd->p, pl, fd == fFilter || fd == fCondition);
586 checkParameters(fd, pl, fd == fFilter || fd == fCondition);
561 587 ret.ty = fd->ret; ret.ty = fd->ret;
562 588 } }
563 589 return ret; return ret;
File misc.h changed (mode: 100644) (index 83d6ad4..817d16a)
... ... void getsuggestions(const char*, char*, size_t, int, ...);
54 54
55 55 const struct typenode *binop(const struct typenode *a, const struct typenode *b); const struct typenode *binop(const struct typenode *a, const struct typenode *b);
56 56 const struct typenode *combinetype(const struct typenode *n1, const struct typenode *n2); const struct typenode *combinetype(const struct typenode *n1, const struct typenode *n2);
57 void checkParameters(const struct paramlist *func, const struct paramlist *inp, bool mustretbool);
57 void checkParameters(const struct funcdecl *fd, const struct paramlist *inp, bool mustretbool);
58 58 const struct typeandname *getVariable(const char *varname); const struct typeandname *getVariable(const char *varname);
59 59
60 bool canconvertbuf(char *buf, size_t buflen, const struct typenode *ufrom, const struct typenode *uto);
60 61 void canconvert(const struct typenode *ufrom, const struct typenode *uto, const int linemod); void canconvert(const struct typenode *ufrom, const struct typenode *uto, const int linemod);
61 62 void canconvertreturn(const struct typenode *ufrom, const struct typenode *uto, const int linemod); void canconvertreturn(const struct typenode *ufrom, const struct typenode *uto, const int linemod);
62 63
File tests/should-fail/not-enough-parameters.j added (mode: 100644) (index 0000000..f2b5327)
1 native Foo takes integer x, real bla, string wat, handle asdf, integer y returns nothing
2
3
4 function test takes nothing returns nothing
5 call Foo(3, 3.1, "bla")
6 endfunction
7
File tests/should-fail/too-many-arguments.j added (mode: 100644) (index 0000000..2f4e304)
1 native Foo takes integer a returns nothing
2
3 function test takes nothing returns nothing
4 call Foo(1, 2, 3)
5 endfunction
File tests/should-fail/wrong-types-in-call.j added (mode: 100644) (index 0000000..425408b)
1 native Foo takes integer x, real bla returns nothing
2
3
4 function test takes nothing returns nothing
5 call Foo(3.4, "foo" )
6 endfunction
7
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/vrtc/pjass

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/vrtc/pjass

Clone this repository using git:
git clone git://git.rocketgit.com/user/vrtc/pjass

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main