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)
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
Fixed various warnings. 6027429ad1895baef4796ac4ae43952ed51f6174 lep 2015-10-28 09:27:40
Added prof target to makefile 9c4b383d3f7416a30a8bde79c735097edaf8d84a lep 2015-10-27 19:14:20
Added gprof support. 374f624967a563dd4c356a3fc104f8ced49fd692 lep 2015-10-27 18:10:13
Changed //! +rb to //# +rb 63af0d3664320cc94ee6e284c308b1983bcfdab2 lep 2015-10-27 17:17:04
Fixed rare segmentation fault. 13a129c8800d306c4117a54cf62cabbb86db3092 lep 2015-10-25 16:11:55
Makefile fixes. 08a5e4d203b0917d78c9fb479ff197d04f473b33 lep 2015-10-25 10:51:12
Makefile improvements (-O3 -flto) 035a361468f060b12bc473e5ec6b0d59db0765d3 lep 2015-10-24 09:16:16
Moved tests into this folder. 099d64a6284a26eafde87ef274c1210455db6f3e lep 2015-10-05 21:29:42
pjass now checks against //! +rb instead of //+rb. Whitespace allowed. 27da8d5250f0b815ef5d8765e0eac766ac4cce6b lep 2015-10-04 21:52:31
Optimized //+rb marker check. cb4a086136acb1a8d7b0bc8397237bbfbdc56191 lep 2015-10-04 18:11:13
Commit 047c531a1c3affb43f53d102c94e765d772ecff3 - Moved code into seperate files.
Author: lep
Author date (UTC): 2016-02-17 20:57
Committer name: lep
Committer date (UTC): 2016-02-17 20:57
Parent(s): d6f672df87fc07421b82041fa740763deaf5ebcc
Signer:
Signing key:
Signing status: N
Tree: aba6d2ab4eead15381cfa4ab2c98037210ad7e9e
File Lines added Lines deleted
.gitignore 1 0
Makefile 16 7
funcdecl.c 12 0
funcdecl.h 16 0
grammar.y 55 103
hashtable.c 124 0
hashtable.h 23 0
main.c 171 0
misc.c 230 590
misc.h 31 61
paramlist.c 21 0
paramlist.h 15 0
token.l 2 3
typeandname.c 71 0
typeandname.h 37 0
File .gitignore changed (mode: 100644) (index fe00ea4..c1ca229)
... ... pjass
13 13 tests/Blizzard.j tests/Blizzard.j
14 14 tests/common.j tests/common.j
15 15 tests/map-scripts/ tests/map-scripts/
16 *.d
File Makefile changed (mode: 100644) (index 1898741..c2029f6)
1 CFLAGS = -O3 -Wall -Wextra
1 CFLAGS = -O3 -Wall -Wextra -std=c11 -MMD -Weverything
2 2 VERSION := $(shell git rev-parse --short HEAD) VERSION := $(shell git rev-parse --short HEAD)
3 3
4 4 # when testing and releasing, we can't run both in parallel # when testing and releasing, we can't run both in parallel
 
... ... pjass-git-$(VERSION)-src.zip: | test
14 14 endif endif
15 15 endif endif
16 16
17 OBJS := token.yy.o grammar.tab.o misc.o main.o \
18 hashtable.o paramlist.o funcdecl.o typeandname.o
19
20
17 21
18 22 .PHONY: all release clean debug prof clean-release-files clean-prof-files clean-build-files .PHONY: all release clean debug prof clean-release-files clean-prof-files clean-build-files
19 23
 
... ... debug: pjass
25 29 prof: CFLAGS = -w -pg prof: CFLAGS = -w -pg
26 30 prof: pjass prof: pjass
27 31
28 pjass: token.o grammar.tab.o misc.o
32 -include $(OBJS:.o=.d)
33
34 pjass: $(OBJS)
29 35 $(CC) $(CFLAGS) $^ -o $@ $(CC) $(CFLAGS) $^ -o $@
30 36
31 token.o: token.yy.c grammar.tab.h
32 $(CC) $(CFLAGS) -c -o $@ $<
33 37
34 misc.o: misc.c misc.h grammar.tab.h
38 main.o: main.c
35 39 $(CC) $(CFLAGS) -c -o $@ $< -DVERSIONSTR="\"git-$(VERSION)\"" $(CC) $(CFLAGS) -c -o $@ $< -DVERSIONSTR="\"git-$(VERSION)\""
36 40
37 41 %.o: %.c %.h %.o: %.c %.h
38 42 $(CC) $(CFLAGS) -c -o $@ $< $(CC) $(CFLAGS) -c -o $@ $<
39 43
44
45 token.yy.o: token.yy.c | grammar.tab.h
46 main.o: main.c | grammar.tab.h
47
40 48 # see token.l options block # see token.l options block
41 49 %.yy.c %.yy.h: %.l %.yy.c %.yy.h: %.l
42 50 flex $< flex $<
 
... ... clean: clean-build-files clean-release-files clean-prof-files
48 56
49 57 clean-build-files: clean-build-files:
50 58 rm -f grammar.tab.h grammar.tab.c token.yy.c token.yy.h \ rm -f grammar.tab.h grammar.tab.c token.yy.c token.yy.h \
51 misc.o grammar.tab.o token.o \
52 pjass.exe pjass
59 $(OBJS) $(OBJS:.o=.d) \
60 pjass.exe pjass
53 61
54 62 clean-release-files: clean-release-files:
55 63 rm -f pjass-git-*.zip rm -f pjass-git-*.zip
 
... ... test: should-fail should-check map-scripts
96 104
97 105 print-test: pjass print-test: pjass
98 106 @echo 'Testing... ' @echo 'Testing... '
107
File funcdecl.c added (mode: 100644) (index 0000000..e2d0c0f)
1 #include <stdlib.h>
2
3 #include "funcdecl.h"
4
5 struct funcdecl *newfuncdecl()
6 {
7 struct funcdecl *fd = calloc(sizeof(struct funcdecl), 1);
8 fd->name = NULL;
9 fd->p = NULL;
10 fd->ret = NULL;
11 return fd;
12 }
File funcdecl.h added (mode: 100644) (index 0000000..99ca506)
1 #ifndef FUNCDECL_H
2 #define FUNCDECL_H
3
4 #include "typeandname.h"
5 #include "paramlist.h"
6
7 struct funcdecl {
8 char *name;
9 int isconst;
10 struct paramlist *p;
11 const struct typenode *ret;
12 };
13
14 struct funcdecl *newfuncdecl(void);
15
16 #endif
File grammar.y changed (mode: 100644) (index 8b5dc95..839455d)
10 10 #include "token.yy.h" #include "token.yy.h"
11 11 #include "misc.h" #include "misc.h"
12 12
13 #define YYMAXDEPTH 100000
14 #define YYDEBUG 1
15
16 void yyerrorline (int errorlevel, int line, char *s)
17 {
18 if (showerrorlevel[errorlevel]) {
19 haderrors++;
20 printf ("%s:%d: %s\n", curfile, line, s);
21 }
22 else
23 ignorederrors++;
24 }
25
26 void yyerrorex (int errorlevel, char *s)
27 {
28 if (showerrorlevel[errorlevel]) {
29 haderrors++;
30 printf ("%s:%d: %s\n", curfile, lineno, s);
31 }
32 else
33 ignorederrors++;
34 }
35
36 void yyerror (char *s) /* Called by yyparse on error */
37 {
38 yyerrorex(0, s);
39 }
40
41 int main(int argc, char **argv)
42 {
43 init();
44 doparse(argc, argv);
45
46 if (!haderrors && didparse) {
47 printf("Parse successful: %8d lines: %s\n", totlines, "<total>");
48 if (ignorederrors)
49 printf("%d errors ignored", ignorederrors);
50
51 return 0;
52 }
53 else {
54 if (haderrors)
55 printf("Parse failed: %d error%s total\n", haderrors, haderrors == 1 ? "" : "s");
56 else
57 printf("Parse failed\n");
58 if (ignorederrors)
59 printf("%d errors ignored", ignorederrors);
60 return 1;
61 }
62 }
63 13
64 14 #define YYSTYPE union node #define YYSTYPE union node
15 #define YYMAXDEPTH 100000
16 #define YYDEBUG 1
65 17
66 18 %} %}
67 19
 
... ... expr: intexpr { $$.ty = gInteger; }
190 142 | realexpr { $$.ty = gReal; } | realexpr { $$.ty = gReal; }
191 143 | stringexpr { $$.ty = gString; } | stringexpr { $$.ty = gString; }
192 144 | boolexpr { $$.ty = gBoolean; } | boolexpr { $$.ty = gBoolean; }
193 | FUNCTION rid { struct funcdecl *fd = lookup(&functions, $2.str);
145 | FUNCTION rid { struct funcdecl *fd = ht_lookup(&functions, $2.str);
194 146 if (fd == NULL) { if (fd == NULL) {
195 147 char ebuf[1024]; char ebuf[1024];
196 148 snprintf(ebuf, 1024, "Undefined function %s", $2.str); snprintf(ebuf, 1024, "Undefined function %s", $2.str);
 
... ... expr: intexpr { $$.ty = gInteger; }
256 208 snprintf(ebuf, 1024, "Index missing for array variable %s", $1.str); snprintf(ebuf, 1024, "Index missing for array variable %s", $1.str);
257 209 yyerrorex(3, ebuf); yyerrorex(3, ebuf);
258 210 } }
259 if(infunction && lookup(curtab, $1.str) && !lookup(&initialized, $1.str) ){
211 if(infunction && ht_lookup(curtab, $1.str) && !ht_lookup(&initialized, $1.str) ){
260 212 char ebuf[1024]; char ebuf[1024];
261 213 snprintf(ebuf, 1024, "Variable %s is uninitialized", $1.str); snprintf(ebuf, 1024, "Variable %s is uninitialized", $1.str);
262 214 //yyerrorex(3, ebuf); //yyerrorex(3, ebuf);
 
... ... expr: intexpr { $$.ty = gInteger; }
280 232 ; ;
281 233
282 234 funccall: rid LPAREN exprlistcompl RPAREN { funccall: rid LPAREN exprlistcompl RPAREN {
283 struct funcdecl *fd = lookup(&functions, $1.str);
235 struct funcdecl *fd = ht_lookup(&functions, $1.str);
284 236 if (fd == NULL) { if (fd == NULL) {
285 237 char ebuf[1024]; char ebuf[1024];
286 238 snprintf(ebuf, 1024, "Undeclared function %s", $1.str); snprintf(ebuf, 1024, "Undeclared function %s", $1.str);
 
... ... funccall: rid LPAREN exprlistcompl RPAREN {
301 253 } }
302 254 | rid LPAREN exprlistcompl newline { | rid LPAREN exprlistcompl newline {
303 255 yyerrorex(0, "Missing ')'"); yyerrorex(0, "Missing ')'");
304 struct funcdecl *fd = lookup(&functions, $1.str);
256 struct funcdecl *fd = ht_lookup(&functions, $1.str);
305 257 if (fd == NULL) { if (fd == NULL) {
306 258 char ebuf[1024]; char ebuf[1024];
307 259 snprintf(ebuf, 1024, "Undeclared function %s", $1.str); snprintf(ebuf, 1024, "Undeclared function %s", $1.str);
 
... ... funcdecl: nativefuncdecl { $$.fd = $1.fd; }
356 308
357 309 nativefuncdecl: NATIVE rid TAKES optparam_list RETURNS opttype nativefuncdecl: NATIVE rid TAKES optparam_list RETURNS opttype
358 310 { {
359 if (lookup(&locals, $2.str) || lookup(&params, $2.str) || lookup(&globals, $2.str)) {
311 if (ht_lookup(&locals, $2.str) || ht_lookup(&params, $2.str) || ht_lookup(&globals, $2.str)) {
360 312 char buf[1024]; char buf[1024];
361 313 snprintf(buf, 1024, "%s already defined as variable", $2.str); snprintf(buf, 1024, "%s already defined as variable", $2.str);
362 314 yyerrorex(3, buf); yyerrorex(3, buf);
363 } else if (lookup(&types, $2.str)) {
315 } else if (ht_lookup(&types, $2.str)) {
364 316 char buf[1024]; char buf[1024];
365 317 snprintf(buf, 1024, "%s already defined as type", $2.str); snprintf(buf, 1024, "%s already defined as type", $2.str);
366 318 yyerrorex(3, buf); yyerrorex(3, buf);
 
... ... funcdefncore: funcbegin localblock codeblock funcend {
390 342 } }
391 343 fnhasrbannotation = 0; fnhasrbannotation = 0;
392 344 } }
393 | funcbegin localblock codeblock {yyerrorex(0, "Missing endfunction"); clear(&params); clear(&locals); clear(&initialized); curtab = &globals; fnhasrbannotation = 0;}
345 | funcbegin localblock codeblock {yyerrorex(0, "Missing endfunction"); ht_clear(&params); ht_clear(&locals); ht_clear(&initialized); curtab = &globals; fnhasrbannotation = 0;}
394 346 ; ;
395 347
396 funcend: ENDFUNCTION { clear(&params); clear(&locals); clear(&initialized); curtab = &globals; inblock = 0; inconstant = 0; infunction = 0; }
348 funcend: ENDFUNCTION { ht_clear(&params); ht_clear(&locals); ht_clear(&initialized); curtab = &globals; inblock = 0; inconstant = 0; infunction = 0; }
397 349 ; ;
398 350
399 351 returnorreturns: RETURNS returnorreturns: RETURNS
 
... ... returnorreturns: RETURNS
401 353 ; ;
402 354
403 355 funcbegin: FUNCTION rid TAKES optparam_list returnorreturns opttype { funcbegin: FUNCTION rid TAKES optparam_list returnorreturns opttype {
404 if (lookup(&locals, $2.str) || lookup(&params, $2.str) || lookup(&globals, $2.str)) {
356 if (ht_lookup(&locals, $2.str) || ht_lookup(&params, $2.str) || ht_lookup(&globals, $2.str)) {
405 357 char buf[1024]; char buf[1024];
406 358 snprintf(buf, 1024, "%s already defined as variable", $2.str); snprintf(buf, 1024, "%s already defined as variable", $2.str);
407 359 yyerrorex(3, buf); yyerrorex(3, buf);
408 } else if (lookup(&types, $2.str)) {
360 } else if (ht_lookup(&types, $2.str)) {
409 361 char buf[1024]; char buf[1024];
410 362 snprintf(buf, 1024, "%s already defined as type", $2.str); snprintf(buf, 1024, "%s already defined as type", $2.str);
411 363 yyerrorex(3, buf); yyerrorex(3, buf);
 
... ... funcbegin: FUNCTION rid TAKES optparam_list returnorreturns opttype {
419 371 $$.fd->ret = $6.ty; $$.fd->ret = $6.ty;
420 372 $$.fd->isconst = 0; $$.fd->isconst = 0;
421 373 put(&functions, $$.fd->name, $$.fd); put(&functions, $$.fd->name, $$.fd);
422 fCurrent = lookup(&functions, $2.str);
374 fCurrent = ht_lookup(&functions, $2.str);
423 375 struct typeandname *tan = $4.pl->head; struct typeandname *tan = $4.pl->head;
424 376 for (;tan; tan=tan->next) { for (;tan; tan=tan->next) {
425 377 tan->lineno = lineno; tan->lineno = lineno;
426 378 tan->fn = fno; tan->fn = fno;
427 379 put(&params, strdup(tan->name), newtypeandname(tan->ty, tan->name)); put(&params, strdup(tan->name), newtypeandname(tan->ty, tan->name));
428 if (lookup(&functions, tan->name)) {
380 if (ht_lookup(&functions, tan->name)) {
429 381 char buf[1024]; char buf[1024];
430 382 snprintf(buf, 1024, "%s already defined as function", tan->name); snprintf(buf, 1024, "%s already defined as function", tan->name);
431 383 yyerrorex(3, buf); yyerrorex(3, buf);
432 } else if (lookup(&types, tan->name)) {
384 } else if (ht_lookup(&types, tan->name)) {
433 385 char buf[1024]; char buf[1024];
434 386 snprintf(buf, 1024, "%s already defined as type", tan->name); snprintf(buf, 1024, "%s already defined as type", tan->name);
435 387 yyerrorex(3, buf); yyerrorex(3, buf);
 
... ... funcbegin: FUNCTION rid TAKES optparam_list returnorreturns opttype {
442 394 //showfuncdecl($$.fd); //showfuncdecl($$.fd);
443 395 } }
444 396 | CONSTANT FUNCTION rid TAKES optparam_list returnorreturns opttype { | CONSTANT FUNCTION rid TAKES optparam_list returnorreturns opttype {
445 if (lookup(&locals, $3.str) || lookup(&params, $3.str) || lookup(&globals, $3.str)) {
397 if (ht_lookup(&locals, $3.str) || ht_lookup(&params, $3.str) || ht_lookup(&globals, $3.str)) {
446 398 char buf[1024]; char buf[1024];
447 399 snprintf(buf, 1024, "%s already defined as variable", $3.str); snprintf(buf, 1024, "%s already defined as variable", $3.str);
448 400 yyerrorex(3, buf); yyerrorex(3, buf);
449 } else if (lookup(&types, $3.str)) {
401 } else if (ht_lookup(&types, $3.str)) {
450 402 char buf[1024]; char buf[1024];
451 403 snprintf(buf, 1024, "%s already defined as type", $3.str); snprintf(buf, 1024, "%s already defined as type", $3.str);
452 404 yyerrorex(3, buf); yyerrorex(3, buf);
 
... ... funcbegin: FUNCTION rid TAKES optparam_list returnorreturns opttype {
464 416 tan->lineno = lineno; tan->lineno = lineno;
465 417 tan->fn = fno; tan->fn = fno;
466 418 put(&params, strdup(tan->name), newtypeandname(tan->ty, tan->name)); put(&params, strdup(tan->name), newtypeandname(tan->ty, tan->name));
467 if (lookup(&functions, tan->name)) {
419 if (ht_lookup(&functions, tan->name)) {
468 420 char buf[1024]; char buf[1024];
469 421 snprintf(buf, 1024, "%s already defined as function", tan->name); snprintf(buf, 1024, "%s already defined as function", tan->name);
470 422 yyerrorex(3, buf); yyerrorex(3, buf);
471 } else if (lookup(&types, tan->name)) {
423 } else if (ht_lookup(&types, tan->name)) {
472 424 char buf[1024]; char buf[1024];
473 425 snprintf(buf, 1024, "%s already defined as type", tan->name); snprintf(buf, 1024, "%s already defined as type", tan->name);
474 426 yyerrorex(3, buf); yyerrorex(3, buf);
 
... ... statement: newline { $$.ty = gEmpty; }
511 463 } }
512 464 if (inconstant) if (inconstant)
513 465 validateGlobalAssignment($2.str); validateGlobalAssignment($2.str);
514 if(infunction && lookup(curtab, $2.str) && !lookup(&initialized, $2.str)){
466 if(infunction && ht_lookup(curtab, $2.str) && !ht_lookup(&initialized, $2.str)){
515 467 put(&initialized, $2.str, (void*)1); put(&initialized, $2.str, (void*)1);
516 468 } }
517 469 } }
 
... ... rid: ID
611 563 ; ;
612 564
613 565 vartypedecl: type rid { vartypedecl: type rid {
614 if (lookup(&functions, $2.str)) {
566 if (ht_lookup(&functions, $2.str)) {
615 567 char buf[1024]; char buf[1024];
616 568 snprintf(buf, 1024, "Symbol %s already defined as function", $2.str); snprintf(buf, 1024, "Symbol %s already defined as function", $2.str);
617 569 yyerrorex(3, buf); yyerrorex(3, buf);
618 } else if (lookup(&types, $2.str)) {
570 } else if (ht_lookup(&types, $2.str)) {
619 571 char buf[1024]; char buf[1024];
620 572 snprintf(buf, 1024, "Symbol %s already defined as type", $2.str); snprintf(buf, 1024, "Symbol %s already defined as type", $2.str);
621 573 yyerrorex(3, buf); yyerrorex(3, buf);
622 574 } }
623 575 struct typeandname *tan = newtypeandname($1.ty, $2.str); struct typeandname *tan = newtypeandname($1.ty, $2.str);
624 576 $$.str = $2.str; $$.str = $2.str;
625 struct typeandname *existing = lookup(&locals, $2.str);
577 struct typeandname *existing = ht_lookup(&locals, $2.str);
626 578 if (!existing) { if (!existing) {
627 existing = lookup(&params, $2.str);
579 existing = ht_lookup(&params, $2.str);
628 580 if (!existing) if (!existing)
629 existing = lookup(&globals, $2.str);
581 existing = ht_lookup(&globals, $2.str);
630 582 } }
631 583 if (existing) { if (existing) {
632 584 tan->lineno = existing->lineno; tan->lineno = existing->lineno;
 
... ... vartypedecl: type rid {
640 592 if (afterendglobals) { if (afterendglobals) {
641 593 yyerrorex(3, "Local constants are not allowed"); yyerrorex(3, "Local constants are not allowed");
642 594 } }
643 if (lookup(&functions, $3.str)) {
595 if (ht_lookup(&functions, $3.str)) {
644 596 char buf[1024]; char buf[1024];
645 597 snprintf(buf, 1024, "Symbol %s already defined as function", $3.str); snprintf(buf, 1024, "Symbol %s already defined as function", $3.str);
646 598 yyerrorex(3, buf); yyerrorex(3, buf);
647 } else if (lookup(&types, $3.str)) {
599 } else if (ht_lookup(&types, $3.str)) {
648 600 char buf[1024]; char buf[1024];
649 601 snprintf(buf, 1024, "Symbol %s already defined as type", $3.str); snprintf(buf, 1024, "Symbol %s already defined as type", $3.str);
650 602 yyerrorex(3, buf); yyerrorex(3, buf);
 
... ... vartypedecl: type rid {
652 604 struct typeandname *tan = newtypeandname($2.ty, $3.str); struct typeandname *tan = newtypeandname($2.ty, $3.str);
653 605 $$.str = $3.str; $$.str = $3.str;
654 606 tan->isconst = 1; tan->isconst = 1;
655 struct typeandname *existing = lookup(&locals, $3.str);
607 struct typeandname *existing = ht_lookup(&locals, $3.str);
656 608 if (!existing) { if (!existing) {
657 existing = lookup(&params, $3.str);
609 existing = ht_lookup(&params, $3.str);
658 610 if (!existing) if (!existing)
659 existing = lookup(&globals, $3.str);
611 existing = ht_lookup(&globals, $3.str);
660 612 } }
661 613 if (existing) { if (existing) {
662 614 tan->lineno = existing->lineno; tan->lineno = existing->lineno;
 
... ... vartypedecl: type rid {
667 619 } }
668 620 put(curtab, $3.str, tan); } put(curtab, $3.str, tan); }
669 621 | type ARRAY rid { | type ARRAY rid {
670 if (lookup(&functions, $3.str)) {
622 if (ht_lookup(&functions, $3.str)) {
671 623 char buf[1024]; char buf[1024];
672 624 snprintf(buf, 1024, "Symbol %s already defined as function", $3.str); snprintf(buf, 1024, "Symbol %s already defined as function", $3.str);
673 625 yyerrorex(3, buf); yyerrorex(3, buf);
674 } else if (lookup(&types, $3.str)) {
626 } else if (ht_lookup(&types, $3.str)) {
675 627 char buf[1024]; char buf[1024];
676 628 snprintf(buf, 1024, "Symbol %s already defined as type", $3.str); snprintf(buf, 1024, "Symbol %s already defined as type", $3.str);
677 629 yyerrorex(3, buf); yyerrorex(3, buf);
 
... ... vartypedecl: type rid {
681 633 struct typeandname *tan = newtypeandname($1.ty, $3.str); struct typeandname *tan = newtypeandname($1.ty, $3.str);
682 634 $$.str = $3.str; $$.str = $3.str;
683 635 tan->isarray = 1; tan->isarray = 1;
684 struct typeandname *existing = lookup(&locals, $3.str);
636 struct typeandname *existing = ht_lookup(&locals, $3.str);
685 637 if (!existing) { if (!existing) {
686 638 char buf[1024]; char buf[1024];
687 existing = lookup(&params, $3.str);
639 existing = ht_lookup(&params, $3.str);
688 640 if (afterendglobals && existing) { if (afterendglobals && existing) {
689 641 snprintf(buf, 1024, "Symbol %s already defined as function parameter", $3.str); snprintf(buf, 1024, "Symbol %s already defined as function parameter", $3.str);
690 642 yyerrorex(3, buf); yyerrorex(3, buf);
691 643 } }
692 644 if (!existing) { if (!existing) {
693 existing = lookup(&globals, $3.str);
645 existing = ht_lookup(&globals, $3.str);
694 646 if (afterendglobals && existing) { if (afterendglobals && existing) {
695 647 snprintf(buf, 1024, "Symbol %s already defined as global variable", $3.str); snprintf(buf, 1024, "Symbol %s already defined as global variable", $3.str);
696 648 yyerrorex(3, buf); yyerrorex(3, buf);
 
... ... vartypedecl: type rid {
711 663 yyerrorex(3, "Invalid variable name \"type\""); yyerrorex(3, "Invalid variable name \"type\"");
712 664 struct typeandname *tan = newtypeandname($1.ty, "type"); struct typeandname *tan = newtypeandname($1.ty, "type");
713 665 $$.str = "type"; $$.str = "type";
714 struct typeandname *existing = lookup(&locals, "type");
666 struct typeandname *existing = ht_lookup(&locals, "type");
715 667 if (!existing) { if (!existing) {
716 existing = lookup(&params, "type");
668 existing = ht_lookup(&params, "type");
717 669 if (!existing) if (!existing)
718 existing = lookup(&globals, "type");
670 existing = ht_lookup(&globals, "type");
719 671 } }
720 672 if (existing) { if (existing) {
721 673 tan->lineno = existing->lineno; tan->lineno = existing->lineno;
 
... ... vartypedecl: type rid {
733 685 struct typeandname *tan = newtypeandname($2.ty, "type"); struct typeandname *tan = newtypeandname($2.ty, "type");
734 686 $$.str = "type"; $$.str = "type";
735 687 tan->isconst = 1; tan->isconst = 1;
736 struct typeandname *existing = lookup(&locals, "type");
688 struct typeandname *existing = ht_lookup(&locals, "type");
737 689 if (!existing) { if (!existing) {
738 existing = lookup(&params, "type");
690 existing = ht_lookup(&params, "type");
739 691 if (!existing) if (!existing)
740 existing = lookup(&globals, "type");
692 existing = ht_lookup(&globals, "type");
741 693 } }
742 694 if (existing) { if (existing) {
743 695 tan->lineno = existing->lineno; tan->lineno = existing->lineno;
 
... ... vartypedecl: type rid {
752 704 struct typeandname *tan = newtypeandname($1.ty, "type"); struct typeandname *tan = newtypeandname($1.ty, "type");
753 705 $$.str = "type"; $$.str = "type";
754 706 tan->isarray = 1; tan->isarray = 1;
755 struct typeandname *existing = lookup(&locals, "type");
707 struct typeandname *existing = ht_lookup(&locals, "type");
756 708 if (!existing) { if (!existing) {
757 existing = lookup(&params, "type");
709 existing = ht_lookup(&params, "type");
758 710 if (!existing) if (!existing)
759 existing = lookup(&globals, "type");
711 existing = ht_lookup(&globals, "type");
760 712 } }
761 713 if (existing) { if (existing) {
762 714 tan->lineno = existing->lineno; tan->lineno = existing->lineno;
 
... ... vardecl: vartypedecl newline {
793 745 if (tan->isarray) { if (tan->isarray) {
794 746 yyerrorex(3, "Arrays cannot be directly initialized"); yyerrorex(3, "Arrays cannot be directly initialized");
795 747 } }
796 if(infunction && !lookup(&initialized, tan->name)){
748 if(infunction && !ht_lookup(&initialized, tan->name)){
797 749 put(&initialized, tan->name, (void*)1); put(&initialized, tan->name, (void*)1);
798 750 } }
799 751 canconvert($3.ty, tan->ty, -1); canconvert($3.ty, tan->ty, -1);
 
... ... vardecl: vartypedecl newline {
803 755 ; ;
804 756
805 757 typedef: TYPE rid EXTENDS type { typedef: TYPE rid EXTENDS type {
806 if (lookup(&types, $2.str)) {
758 if (ht_lookup(&types, $2.str)) {
807 759 char buf[1024]; char buf[1024];
808 760 snprintf(buf, 1024, "Multiply defined type %s", $2.str); snprintf(buf, 1024, "Multiply defined type %s", $2.str);
809 761 yyerrorex(3, buf); yyerrorex(3, buf);
810 } else if (lookup(&functions, $2.str)) {
762 } else if (ht_lookup(&functions, $2.str)) {
811 763 char buf[1024]; char buf[1024];
812 764 snprintf(buf, 1024, "%s already defined as function", $2.str); snprintf(buf, 1024, "%s already defined as function", $2.str);
813 765 yyerrorex(3, buf); yyerrorex(3, buf);
 
... ... typeandname: type rid { $$.tan = newtypeandname($1.ty, $2.str); }
822 774
823 775 type: primtype { $$.ty = $1.ty; } type: primtype { $$.ty = $1.ty; }
824 776 | rid { | rid {
825 if (lookup(&types, $1.str) == NULL) {
777 if (ht_lookup(&types, $1.str) == NULL) {
826 778 char buf[1024]; char buf[1024];
827 779 snprintf(buf, 1024, "Undefined type %s", $1.str); snprintf(buf, 1024, "Undefined type %s", $1.str);
828 780 getsuggestions($1.str, buf, 1024, 1, &types); getsuggestions($1.str, buf, 1024, 1, &types);
 
... ... type: primtype { $$.ty = $1.ty; }
830 782 $$.ty = gAny; $$.ty = gAny;
831 783 } }
832 784 else else
833 $$.ty = lookup(&types, $1.str);
785 $$.ty = ht_lookup(&types, $1.str);
834 786 } }
835 787 ; ;
836 788
837 primtype: HANDLE { $$.ty = lookup(&types, yytext); }
838 | INTEGER { $$.ty = lookup(&types, yytext); }
839 | REAL { $$.ty = lookup(&types, yytext); }
840 | BOOLEAN { $$.ty = lookup(&types, yytext); }
841 | STRING { $$.ty = lookup(&types, yytext); }
842 | CODE { $$.ty = lookup(&types, yytext); }
789 primtype: HANDLE { $$.ty = ht_lookup(&types, yytext); }
790 | INTEGER { $$.ty = ht_lookup(&types, yytext); }
791 | REAL { $$.ty = ht_lookup(&types, yytext); }
792 | BOOLEAN { $$.ty = ht_lookup(&types, yytext); }
793 | STRING { $$.ty = ht_lookup(&types, yytext); }
794 | CODE { $$.ty = ht_lookup(&types, yytext); }
843 795 ; ;
844 796
845 797 newline: NEWLINE { rbannotated = 0; } newline: NEWLINE { rbannotated = 0; }
File hashtable.c added (mode: 100644) (index 0000000..6fd3bb8)
1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdlib.h>
4
5 #include "hashtable.h"
6
7 static uint32_t hashfunc(const char *key)
8 {
9 //murmur3_32
10 static const uint32_t c1 = 0xcc9e2d51;
11 static const uint32_t c2 = 0x1b873593;
12 static const uint32_t r1 = 15;
13 static const uint32_t r2 = 13;
14 static const uint32_t m = 5;
15 static const uint32_t n = 0xe6546b64;
16
17 uint32_t len = strlen(key);
18 uint32_t hash = 0;
19
20 const int nblocks = len / 4;
21 const uint32_t *blocks = (const uint32_t *) key;
22 int i;
23 for (i = 0; i < nblocks; i++) {
24 uint32_t k = blocks[i];
25 k *= c1;
26 k = (k << r1) | (k >> (32 - r1));
27 k *= c2;
28
29 hash ^= k;
30 hash = ((hash << r2) | (hash >> (32 - r2))) * m + n;
31 }
32
33 const uint8_t *tail = (const uint8_t *) (key + nblocks * 4);
34 uint32_t k1 = 0;
35
36 switch (len & 3) {
37 case 3:
38 k1 ^= tail[2] << 16;
39 case 2:
40 k1 ^= tail[1] << 8;
41 case 1:
42 k1 ^= tail[0];
43
44 k1 *= c1;
45 k1 = (k1 << r1) | (k1 >> (32 - r1));
46 k1 *= c2;
47 hash ^= k1;
48 }
49
50 hash ^= len;
51 hash ^= (hash >> 16);
52 hash *= 0x85ebca6b;
53 hash ^= (hash >> 13);
54 hash *= 0xc2b2ae35;
55 hash ^= (hash >> 16);
56
57 return hash;
58 }
59
60 void ht_init(struct hashtable *h, size_t size)
61 {
62 h->count = 0;
63 h->size = size;
64 h->bucket = calloc(sizeof(struct hashnode), h->size);
65 }
66
67 void * ht_lookup(struct hashtable *h, const char *name)
68 {
69 size_t start = hashfunc(name);
70 size_t idx = (start + 1) % h->size;
71 for(; idx != start; idx = (idx + 1) % h->size){
72 if(h->bucket[idx].name){
73 if(!strcmp(h->bucket[idx].name, name)){
74 return h->bucket[idx].val;
75 }
76 }else{
77 break;
78 }
79 }
80 return NULL;
81 }
82
83 static void resize(struct hashtable *h)
84 {
85 struct hashtable new;
86 ht_init(&new, h->size*2 +1);
87 size_t i;
88 for(i = 0; i != h->size; i++){
89 if(h->bucket[i].name){
90 ht_put(&new, h->bucket[i].name, h->bucket[i].val);
91 }
92 }
93 free(h->bucket);
94 h->bucket = new.bucket;
95 h->size = new.size;
96 h->count = new.count;
97 }
98
99 bool ht_put(struct hashtable *h, const char *name, void *val)
100 {
101 if (ht_lookup(h, name) != NULL) {
102 return false;
103 }
104
105 size_t start = hashfunc(name);
106 size_t idx = (start + 1) % h->size;
107 for(; /*idx != start*/; idx = (idx + 1) % h->size){
108 if(!h->bucket[idx].name){
109 h->bucket[idx].name = name;
110 h->bucket[idx].val = val;
111 break;
112 }
113 }
114 h->count++;
115 if(h->count*3/2 > h->size){
116 resize(h);
117 }
118 return true;
119 }
120
121 void ht_clear(struct hashtable *h) {
122 memset(h->bucket, 0, h->size*sizeof(struct hashnode));
123 h->count = 0;
124 }
File hashtable.h added (mode: 100644) (index 0000000..905a180)
1 #ifndef HASHTABLE_H
2 #define HASHTABLE_H
3
4 #include <stdint.h>
5 #include <stdbool.h>
6
7 struct hashnode {
8 const char *name;
9 void *val;
10 };
11
12 struct hashtable {
13 size_t size;
14 size_t count;
15 struct hashnode *bucket;
16 };
17
18 void ht_init(struct hashtable *h, size_t size);
19 void *ht_lookup(struct hashtable *h, const char *name);
20 bool ht_put(struct hashtable *h, const char *name, void *val);
21 void ht_clear(struct hashtable *h);
22
23 #endif
File main.c added (mode: 100644) (index 0000000..32d1254)
1 #include "token.yy.h"
2 #include "grammar.tab.h"
3
4 #include "misc.h"
5
6 #ifndef VERSIONSTR
7 #define VERSIONSTR "1.0-git"
8 #endif
9 #define ERRORLEVELNUM 4
10
11 static struct typenode* addPrimitiveType(const char *name) {
12 struct typenode *new = newtypenode(name, NULL);
13 put(&types, name, new);
14 return new;
15 }
16
17
18 static void init() {
19 ht_init(&functions, 8191);
20 ht_init(&globals, 8191);
21 ht_init(&locals, 23);
22 ht_init(&params, 11);
23 ht_init(&types, 511);
24 ht_init(&initialized, 23);
25
26 gHandle = addPrimitiveType("handle");
27 gInteger = addPrimitiveType("integer");
28 gReal = addPrimitiveType("real");
29 gBoolean = addPrimitiveType("boolean");
30 gString = addPrimitiveType("string");
31 gCode = addPrimitiveType("code");
32
33 gNothing = newtypenode("nothing", NULL);
34 gNull = newtypenode("null", NULL);
35
36 gAny = newtypenode("any", NULL);
37 gNone = newtypenode("none", NULL);
38 gEmpty = newtypenode("empty", NULL);
39
40 curtab = &globals;
41 fno = 0;
42 strict = 0;
43 returnbug = 0;
44 fnhasrbannotation = 0;
45 rbannotated = 0;
46 haderrors = 0;
47 ignorederrors = 0;
48 islinebreak = 1;
49 inblock = 0;
50 isconstant = 0;
51 inconstant = 0;
52 infunction = 0;
53 fCurrent = 0;
54 }
55
56 static void dofile(FILE *fp, const char *name) {
57 lineno = 1;
58 islinebreak = 1;
59 isconstant = 0;
60 inconstant = 0;
61 inblock = 0;
62 afterendglobals = 0;
63 int olderrs = haderrors;
64 yy_switch_to_buffer(yy_create_buffer(fp, BUFSIZE));
65 curfile = name;
66
67 while ( yyparse() ) ;
68
69 if (olderrs == haderrors){
70 printf("Parse successful: %8d lines: %s\n", lineno, curfile);
71 }else{
72 printf("%s failed with %d error%s\n", curfile, haderrors - olderrs,(haderrors == olderrs + 1) ? "" : "s");
73 }
74 totlines += lineno;
75 fno++;
76 }
77
78 static void printversion() {
79 printf("Pjass version %s by Rudi Cilibrasi, modified by AIAndy, PitzerMike, Deaod and lep\n", VERSIONSTR);
80 }
81
82 static void doparse(int argc, char **argv) {
83 int i;
84 for (i = 1; i < argc; ++i) {
85 if (argv[i][0] == '-' && argv[i][1] == 0) {
86 dofile(stdin, "<stdin>");
87 didparse = 1;
88 continue;
89 }
90 if (strcmp(argv[i], "-h") == 0) {
91 printversion();
92 printf(
93 "To use this program, list the files you would like to parse in order.\n"
94 "If you would like to parse from standard input (the keyboard), then\n"
95 "use - as an argument. If you supply no arguments to pjass, it will\n"
96 "parse the console standard input by default.\n"
97 "To test this program, go into your Scripts directory, and type:\n"
98 "pjass common.j common.ai Blizzard.j\n"
99 "pjass accepts some options:\n"
100 "pjass -h Display this help\n"
101 "pjass -v Display version information and exit\n"
102 "pjass -e1 Ignores error level 1\n"
103 "pjass +e2 Undo Ignore of error level 2\n"
104 "pjass +s Enable strict downcast evaluation\n"
105 "pjass -s Disable strict downcast evaluation\n"
106 "pjass +rb Enable returnbug\n"
107 "pjass -rb Disable returnbug\n"
108 "pjass - Read from standard input (may appear in a list)\n"
109 );
110 exit(0);
111 }
112 if (strcmp(argv[i], "-v") == 0) {
113 printf("%s version %s\n", argv[0], VERSIONSTR);
114 exit(0);
115 }
116 if (strcmp(argv[i], "+s") == 0) {
117 strict = 1;
118 continue;
119 }
120 if (strcmp(argv[i], "-s") == 0) {
121 strict = 0;
122 continue;
123 }
124 if (strcmp(argv[i], "+rb") == 0) {
125 returnbug = 1;
126 continue;
127 }
128 if (strcmp(argv[i], "-rb") == 0) {
129 returnbug = 0;
130 continue;
131 }
132
133 FILE *fp;
134 fp = fopen(argv[i], "rb");
135 if (fp == NULL) {
136 printf("Error: Cannot open %s\n", argv[i]);
137 haderrors++;
138 continue;
139 }
140
141 dofile(fp, argv[i]);
142 didparse = 1;
143 fclose(fp);
144 }
145 if (argc == 1) {
146 didparse = 1;
147 dofile(stdin, "<stdin>");
148 }
149 }
150 int main(int argc, char **argv)
151 {
152 init();
153 doparse(argc, argv);
154
155 if (!haderrors && didparse) {
156 printf("Parse successful: %8d lines: %s\n", totlines, "<total>");
157 if (ignorederrors)
158 printf("%d errors ignored", ignorederrors);
159
160 return 0;
161 }
162 else {
163 if (haderrors)
164 printf("Parse failed: %d error%s total\n", haderrors, haderrors == 1 ? "" : "s");
165 else
166 printf("Parse failed\n");
167 if (ignorederrors)
168 printf("%d errors ignored", ignorederrors);
169 return 1;
170 }
171 }
File misc.c changed (mode: 100644) (index ca389be..3c449d2)
9 9 #include <assert.h> #include <assert.h>
10 10 #include <stdlib.h> #include <stdlib.h>
11 11 #include <stdint.h> #include <stdint.h>
12 #include "token.yy.h"
13 #include "grammar.tab.h"
12
14 13 #include "misc.h" #include "misc.h"
15 14
16 #ifndef VERSIONSTR
17 #define VERSIONSTR "1.0-git"
18 #endif
19 #define ERRORLEVELNUM 4
20 15
21 16 int fno; int fno;
22 17 int lineno; int lineno;
 
... ... int inloop;
37 32 int afterendglobals; int afterendglobals;
38 33 int *showerrorlevel; int *showerrorlevel;
39 34
40 uint32_t hashfunc(const char *name);
41 void inittable(struct hashtable*, int);
42 struct hashtable functions, globals, locals, params, types, initialized;
35 struct hashtable functions;
36 struct hashtable globals;
37 struct hashtable locals;
38 struct hashtable params;
39 struct hashtable types;
40 struct hashtable initialized;
41
43 42 struct hashtable *curtab; struct hashtable *curtab;
43
44 44 const struct typenode *retval; const struct typenode *retval;
45 45 const char *curfile; const char *curfile;
46 46 struct typenode *gInteger, *gReal, *gBoolean, *gString, *gCode, *gHandle, *gNothing, *gNull, *gAny, *gNone, *gEmpty; struct typenode *gInteger, *gReal, *gBoolean, *gString, *gCode, *gHandle, *gNothing, *gNull, *gAny, *gNone, *gEmpty;
47 47 struct typenode *gEmpty; struct typenode *gEmpty;
48 48 struct funcdecl *fCurrent; struct funcdecl *fCurrent;
49 49
50 void addPrimitiveType(const char *name, struct typenode **toSave)
50
51 void yyerrorline (int errorlevel, int line, const char *s)
52 {
53 //if (showerrorlevel[errorlevel]) {
54 haderrors++;
55 printf ("%s:%d: %s\n", curfile, line, s);
56 //}
57 //else
58 // ignorederrors++;
59 }
60
61 void yyerrorex (int errorlevel, const char *s)
51 62 { {
52 put(&types, name, *toSave = newtypenode(name, NULL));
63 //if (showerrorlevel[errorlevel]) {
64 haderrors++;
65 printf ("%s:%d: %s\n", curfile, lineno, s);
66 //}
67 //else
68 // ignorederrors++;
53 69 } }
54 70
55 void init()
71 void yyerror (const char *s) /* Called by yyparse on error */
56 72 { {
57 int i;
58
59 inittable(&functions, 8191);
60 inittable(&globals, 8191);
61 inittable(&locals, 23);
62 inittable(&params, 11);
63 inittable(&types, 511);
64 inittable(&initialized, 23);
65
66 addPrimitiveType("handle", &gHandle);
67 addPrimitiveType("integer", &gInteger);
68 addPrimitiveType("real", &gReal);
69 addPrimitiveType("boolean", &gBoolean);
70 addPrimitiveType("string", &gString);
71 addPrimitiveType("code", &gCode);
72
73 gNothing = newtypenode("nothing", NULL);
74 gNull = newtypenode("null", NULL);
75
76 gAny = newtypenode("any", NULL);
77 gNone = newtypenode("none", NULL);
78 gEmpty = newtypenode("empty", NULL);
79
80 curtab = &globals;
81 fno = 0;
82 strict = 0;
83 returnbug = 0;
84 fnhasrbannotation = 0;
85 rbannotated = 0;
86 haderrors = 0;
87 ignorederrors = 0;
88 islinebreak = 1;
89 inblock = 0;
90 isconstant = 0;
91 inconstant = 0;
92 infunction = 0;
93 fCurrent = 0;
94 showerrorlevel = malloc(ERRORLEVELNUM*sizeof(int));
95 for(i=0;i<ERRORLEVELNUM;i++)
96 showerrorlevel[i] = 1;
97 if (lookup(&functions, "ConvertRace") != NULL) {
98 printf("Major error!!\n");
99 exit(1);
100 }
73 yyerrorex(0, s);
101 74 } }
102 75
76 void put(struct hashtable *h, const char *name, void *val){
77 if( !ht_put(h, name, val) ){
78 char ebuf[1024];
79 snprintf(ebuf, 1024, "Symbol %s multiply defined", name);
80 yyerrorline(3, islinebreak ? lineno - 1 : lineno, ebuf);
81 }
82 }
83
84
103 85 #define min(a, b) (((a) < (b)) ? (a) : (b)) #define min(a, b) (((a) < (b)) ? (a) : (b))
104 86
105 87 int abs(int i){ int abs(int i){
 
... ... int abs(int i){
108 90 return i; return i;
109 91 } }
110 92
111 int editdistance(const char *s, const char *t, int cutoff){
93 static int editdistance(const char *s, const char *t, int cutoff){
112 94 if(!strcmp(s, t)) return 0; if(!strcmp(s, t)) return 0;
113 95
114 96 int a = strlen(s); int a = strlen(s);
 
... ... int editdistance(const char *s, const char *t, int cutoff){
116 98
117 99 if(a==0) return b; if(a==0) return b;
118 100 if(b==0) return a; if(b==0) return a;
119
101
120 102 if(abs(a-b) > cutoff){ if(abs(a-b) > cutoff){
121 103 return cutoff + 1; return cutoff + 1;
122 104 } }
123 105
124 106 int *v[3]; int *v[3];
125 int i;
126 for(i = 0; i != 3; i++)
127 v[i] = malloc(sizeof(int) * (b+1));
107 for(int i = 0; i != 3; i++) {
108 v[i] = malloc(sizeof(int) * (size_t)(b+1));
109 }
128 110
129 for(i = 0; i != b+1; i++){
111 for(int i = 0; i != b+1; i++){
130 112 v[0][i] = i; v[0][i] = i;
131 113 } }
132 114
133 115 int pcur; int pcur;
134 116 int ppcur; int ppcur;
135 117 int cur = 1; int cur = 1;
136 for(i = 0; i != a; i++, cur = (cur+1) % 3){
118 for(int i = 0; i != a; i++){
119 cur = (cur+1) % 3;
137 120 pcur = cur -1; pcur = cur -1;
138 121 if(pcur < 0) pcur += 3; if(pcur < 0) pcur += 3;
139 122 ppcur = pcur -1; ppcur = pcur -1;
140 123 if(ppcur < 0) ppcur += 3; if(ppcur < 0) ppcur += 3;
141 124
142 125 v[cur][0] = i + 1; v[cur][0] = i + 1;
143
126
144 127 int minDistance = INT_MAX; int minDistance = INT_MAX;
145
128
146 129 int j; int j;
147 130 for(j = 0; j != b; j++){ for(j = 0; j != b; j++){
148 131 int cost = (s[i] == t[j]) ? 0 : 1; int cost = (s[i] == t[j]) ? 0 : 1;
 
... ... int editdistance(const char *s, const char *t, int cutoff){
152 135 if(i > 0 && j > 0 && s[i] == t[j-1] && s[i-1] == t[j]){ if(i > 0 && j > 0 && s[i] == t[j-1] && s[i-1] == t[j]){
153 136 v[cur][j+1] = min(v[cur][j+1], v[ppcur][j-1] + cost); v[cur][j+1] = min(v[cur][j+1], v[ppcur][j-1] + cost);
154 137 } }
155
138
156 139 if(v[cur][j+1] < minDistance){ if(v[cur][j+1] < minDistance){
157 140 minDistance = v[cur][j+1]; minDistance = v[cur][j+1];
158 141 } }
159 142 } }
160
143
161 144 if(minDistance > cutoff){ if(minDistance > cutoff){
162 145 return cutoff + 1; return cutoff + 1;
163 146 } }
 
... ... int editdistance(const char *s, const char *t, int cutoff){
165 148 pcur = cur -1; pcur = cur -1;
166 149 if(pcur < 0) pcur += 3; if(pcur < 0) pcur += 3;
167 150 int d = v[pcur][b]; int d = v[pcur][b];
168 for(i = 0; i != 3; i++)
151 for(int i = 0; i != 3; i++)
169 152 free(v[i]); free(v[i]);
170 153 return d; return d;
171 154 } }
172 155
173 void getsuggestions(const char *name, char *buff, int buffsize, int nTables, ...){
174 int i;
156 void getsuggestions(const char *name, char *buff, size_t buffsize, int nTables, ...)
157 {
175 158 va_list ap; va_list ap;
176 159
177 160 int len = strlen(name); int len = strlen(name);
 
... ... void getsuggestions(const char *name, char *buff, int buffsize, int nTables, ...
179 162 int count = 0; int count = 0;
180 163
181 164 struct {int distance; const char *name;} suggestions[3]; struct {int distance; const char *name;} suggestions[3];
182 for(i = 0; i != 3; i++){
165 for(int i = 0; i != 3; i++){
183 166 suggestions[i].distance = INT_MAX; suggestions[i].distance = INT_MAX;
184 167 suggestions[i].name = NULL; suggestions[i].name = NULL;
185 168 } }
186 169
187 170 va_start(ap, nTables); va_start(ap, nTables);
188 for(i = 0; i != nTables; i++){
171
172 for(int i = 0; i != nTables; i++){
189 173 struct hashtable *ht = va_arg(ap, struct hashtable*); struct hashtable *ht = va_arg(ap, struct hashtable*);
190
191 size_t x;
192 for(x = 0; x != ht->size; x++){
174
175 for(size_t x = 0; x != ht->size; x++){
193 176 if(ht->bucket[x].name){ if(ht->bucket[x].name){
194 177 const struct typeandname *tan = ht->bucket[x].val; const struct typeandname *tan = ht->bucket[x].val;
195 178 if(typeeq(tan->ty, gAny)){ if(typeeq(tan->ty, gAny)){
196 179 continue; continue;
197 180 } }
198
181
199 182 int dist = editdistance(ht->bucket[x].name, name, cutoff); int dist = editdistance(ht->bucket[x].name, name, cutoff);
200 183 if(dist <= cutoff){ if(dist <= cutoff){
201 184 count++; count++;
202 int j;
203 for(j = 0; j != 3; j++){
185 for(int j = 0; j != 3; j++){
204 186 if(suggestions[j].distance > dist){ if(suggestions[j].distance > dist){
205 187 if(i == 0){ if(i == 0){
206 188 suggestions[2] = suggestions[1]; suggestions[2] = suggestions[1];
 
... ... void getsuggestions(const char *name, char *buff, int buffsize, int nTables, ...
214 196 break; break;
215 197 } }
216 198 } }
217
199
218 200 } }
219 201 } }
220 202 } }
221
203
222 204 } }
223 205 va_end(ap); va_end(ap);
224 206
 
... ... void getsuggestions(const char *name, char *buff, int buffsize, int nTables, ...
238 220
239 221 const struct typeandname *getVariable(const char *varname) const struct typeandname *getVariable(const char *varname)
240 222 { {
241 char ebuf[1024];
242 struct typeandname *result;
243 result = lookup(&locals, varname);
244 if (result) return result;
245 result = lookup(&params, varname);
246 if (result) return result;
247 result = lookup(&globals, varname);
248 if (result) return result;
249 snprintf(ebuf, 1024, "Undeclared variable %s", varname);
250 getsuggestions(varname, ebuf, 1024, 3, &locals, &params, &globals);
251 yyerrorline(2, islinebreak ? lineno - 1 : lineno, ebuf);
252 // Store it as unidentified variable
253 const struct typeandname *newtan = newtypeandname(gAny, varname);
254 put(curtab, varname, (void*)newtan);
255 if(infunction && !lookup(&initialized, varname)){
256 put(&initialized, varname, (void*)1);
257 }
258 return newtan;
223 char ebuf[1024];
224 struct typeandname *result;
225 result = ht_lookup(&locals, varname);
226 if (result) return result;
227 result = ht_lookup(&params, varname);
228 if (result) return result;
229 result = ht_lookup(&globals, varname);
230 if (result) return result;
231 snprintf(ebuf, 1024, "Undeclared variable %s", varname);
232 getsuggestions(varname, ebuf, 1024, 3, &locals, &params, &globals);
233 yyerrorline(2, islinebreak ? lineno - 1 : lineno, ebuf);
234 // Store it as unidentified variable
235 const struct typeandname *newtan = newtypeandname(gAny, varname);
236 put(curtab, varname, (void*)newtan);
237 if(infunction && !ht_lookup(&initialized, varname)){
238 put(&initialized, varname, (void*)1);
239 }
240 return newtan;
259 241 } }
260 242
261 243 void validateGlobalAssignment(const char *varname) { void validateGlobalAssignment(const char *varname) {
262 char ebuf[1024];
263 struct typeandname *result;
264 result = lookup(&globals, varname);
265 if (result) {
266 snprintf(ebuf, 1024, "Assignment to global variable %s in constant function", varname);
267 yyerrorline(2, lineno - 1, ebuf);
268 }
269 }
270
271 struct typeandname *newtypeandname(const struct typenode *ty, const char *name)
272 {
273 struct typeandname *tan = calloc(sizeof(struct typeandname), 1);
274 tan->ty = ty;
275 tan->name = strdup(name);
276 tan->next = NULL;
277 return tan;
278 }
279
280 struct typenode *newtypenode(const char *typename, const struct typenode *superclass)
281 {
282 struct typenode *result;
283 result = aligned_alloc(8, sizeof(struct typenode));
284 result->typename = strdup(typename);
285 result->superclass = superclass;
286 return result;
287 }
288
289 struct paramlist *newparamlist()
290 {
291 struct paramlist *tl = calloc(sizeof(struct paramlist), 1);
292 tl->head = NULL;
293 tl->tail = &tl->head;
294 return tl;
295 }
296
297 void addParam(struct paramlist *pl, struct typeandname *tan)
298 {
299 tan->next = *(pl->tail);
300 *(pl->tail) = tan;
301 }
302
303 struct funcdecl *newfuncdecl()
304 {
305 struct funcdecl *fd = calloc(sizeof(struct funcdecl), 1);
306 fd->name = NULL;
307 fd->p = NULL;
308 fd->ret = NULL;
309 return fd;
310 }
311
312 const struct typenode *getPrimitiveAncestor(const struct typenode *cur)
313 {
314 while (getTypePtr(cur)->superclass)
315 cur = getTypePtr(cur)->superclass;
316 return cur;
317 }
318
319 int isDerivedFrom(const struct typenode *cur, const struct typenode *base)
320 {
321 do {
322 if (typeeq(cur, base)) return 1;
323 cur = getTypePtr(cur)->superclass;
324 } while (getTypePtr(cur));
325 return 0;
326 }
327
328 void showtypenode(const struct typenode *td)
329 {
330 char *extends = "";
331 char ebuf[1024];
332 assert(getTypePtr(td));
333 assert(getTypePtr(td)->typename);
334
335 if (td->superclass) {
336 sprintf(ebuf, " extends %s", td->superclass->typename);
337 extends = ebuf;
338 }
339
340 printf("%s %s \n", getTypePtr(td)->typename, extends);
341 }
342
343 void showfuncdecl(struct funcdecl *fd)
344 {
345 struct typeandname *tan;
346 printf("%s takes ", fd->name);
347 if (fd->p->head == NULL)
348 printf("nothing ");
349 for (tan = fd->p->head; tan; tan = tan->next) {
350 showtypenode(tan->ty);
351 printf(" %s", tan->name);
352 if (tan->next)
353 printf(",");
354 printf(" ");
355 }
356 printf("returns ");
357 showtypenode(fd->ret);
358 printf("\n");
359 }
360
361
362 uint32_t hashfunc(const char *key) {
363 //murmur3_32
364 static const uint32_t c1 = 0xcc9e2d51;
365 static const uint32_t c2 = 0x1b873593;
366 static const uint32_t r1 = 15;
367 static const uint32_t r2 = 13;
368 static const uint32_t m = 5;
369 static const uint32_t n = 0xe6546b64;
370
371 uint32_t len = strlen(key);
372 uint32_t hash = 0;
373
374 const int nblocks = len / 4;
375 const uint32_t *blocks = (const uint32_t *) key;
376 int i;
377 for (i = 0; i < nblocks; i++) {
378 uint32_t k = blocks[i];
379 k *= c1;
380 k = (k << r1) | (k >> (32 - r1));
381 k *= c2;
382
383 hash ^= k;
384 hash = ((hash << r2) | (hash >> (32 - r2))) * m + n;
385 }
386
387 const uint8_t *tail = (const uint8_t *) (key + nblocks * 4);
388 uint32_t k1 = 0;
389
390 switch (len & 3) {
391 case 3:
392 k1 ^= tail[2] << 16;
393 case 2:
394 k1 ^= tail[1] << 8;
395 case 1:
396 k1 ^= tail[0];
397
398 k1 *= c1;
399 k1 = (k1 << r1) | (k1 >> (32 - r1));
400 k1 *= c2;
401 hash ^= k1;
402 }
403
404 hash ^= len;
405 hash ^= (hash >> 16);
406 hash *= 0x85ebca6b;
407 hash ^= (hash >> 13);
408 hash *= 0xc2b2ae35;
409 hash ^= (hash >> 16);
410
411 return hash;
244 char ebuf[1024];
245 struct typeandname *result;
246 result = ht_lookup(&globals, varname);
247 if (result) {
248 snprintf(ebuf, 1024, "Assignment to global variable %s in constant function", varname);
249 yyerrorline(2, lineno - 1, ebuf);
250 }
412 251 } }
413 252
414 void inittable(struct hashtable *h, int size){
415 h->count = 0;
416 h->size = size;
417 h->bucket = calloc(sizeof(struct hashnode), h->size);
418 }
419 253
420 void *lookup(struct hashtable *h, const char *name)
254 void checkParameters(const struct paramlist *func, const struct paramlist *inp)
421 255 { {
422 int start = hashfunc(name);
423 int idx = (start + 1) % h->size;
424 for(; idx != start; idx = (idx + 1) % h->size){
425 if(h->bucket[idx].name){
426 if(!strcmp(h->bucket[idx].name, name)){
427 return h->bucket[idx].val;
428 }
429 }else{
430 break;
431 }
432 }
433 return NULL;
434 }
435
436 void resize(struct hashtable *h){
437 struct hashtable new;
438 inittable(&new, h->size*2 +1);
439 size_t i;
440 for(i = 0; i != h->size; i++){
441 if(h->bucket[i].name){
442 put(&new, h->bucket[i].name, h->bucket[i].val);
256 const struct typeandname *fi = func->head;
257 const struct typeandname *pi = inp->head;
258 while(true) {
259 if (fi == NULL && pi == NULL)
260 return;
261 if (fi == NULL && pi != NULL) {
262 yyerrorex(3, "Too many arguments passed to function");
263 return;
443 264 } }
265 if (fi != NULL && pi == NULL) {
266 yyerrorex(3, "Not enough arguments passed to function");
267 return;
268 }
269 canconvert(pi->ty, fi->ty, 0);
270 pi = pi->next;
271 fi = fi->next;
444 272 } }
445 free(h->bucket);
446 h->bucket = new.bucket;
447 h->size = new.size;
448 h->count = new.count;
449 273 } }
450
451 void put(struct hashtable *h, const char *name, void *val)
274 const struct typenode *binop(const struct typenode *a, const struct typenode *b)
452 275 { {
453
454 if (lookup(h, name) != NULL) {
455 char ebuf[1024];
456 snprintf(ebuf, 1024, "Symbol %s multiply defined", name);
457 yyerrorline(3, islinebreak ? lineno - 1 : lineno, ebuf);
458 return;
459 }
460
461 int start = hashfunc(name);
462 int idx = (start + 1) % h->size;
463 for(; /*idx != start*/; idx = (idx + 1) % h->size){
464 if(!h->bucket[idx].name){
465 h->bucket[idx].name = name;
466 h->bucket[idx].val = val;
467 break;
276 a = getPrimitiveAncestor(a);
277 b = getPrimitiveAncestor(b);
278 if (typeeq(a, gInteger) && typeeq(b, gInteger))
279 return gInteger;
280 if (typeeq(a, gAny))
281 return b;
282 if (typeeq(b, gAny))
283 return a;
284 if ((!typeeq(a, gInteger) && !typeeq(a, gReal)) || (!typeeq(b, gInteger) && !typeeq(b, gReal))) {
285 yyerrorline(3, islinebreak ? lineno - 1 : lineno, "Bad types for binary operator");
468 286 } }
469 }
470 h->count++;
471 if(h->count*3/2 > h->size){
472 resize(h);
473 }
474 }
475
476 void clear(struct hashtable *h)
477 {
478 memset(h->bucket, 0, h->size*sizeof(struct hashnode));
479 h->count = 0;
287 return gReal;
480 288 } }
481 289
482 const struct typenode *binop(const struct typenode *a, const struct typenode *b)
290 const struct typenode *combinetype(const struct typenode *n1, const struct typenode *n2)
483 291 { {
484 a = getPrimitiveAncestor(a);
485 b = getPrimitiveAncestor(b);
486 if (typeeq(a, gInteger) && typeeq(b, gInteger))
487 return gInteger;
488 if (typeeq(a, gAny))
489 return b;
490 if (typeeq(b, gAny))
491 return a;
492 if ((!typeeq(a, gInteger) && !typeeq(a, gReal)) || (!typeeq(b, gInteger) && !typeeq(b, gReal))) {
493 yyerrorline(3, islinebreak ? lineno - 1 : lineno, "Bad types for binary operator");
494 }
495 return gReal;
292 uint8_t ret = getTypeTag(n1) & getTypeTag(n2);
293 if ((typeeq(n1, gNone)) || (typeeq(n2, gNone))) return mkretty(gNone, ret);
294 if (typeeq(n1, n2)) return mkretty(n1, ret);
295 if (typeeq(n1, gNull))
296 return mkretty(n2, ret);
297 if (typeeq(n2, gNull))
298 return mkretty(n1, ret);
299 n1 = getPrimitiveAncestor(n1);
300 n2 = getPrimitiveAncestor(n2);
301 if (typeeq(n1, n2)) return mkretty(n1, ret);
302 if (typeeq(n1, gNull))
303 return mkretty(n2, ret);
304 if (typeeq(n2, gNull))
305 return mkretty(n1, ret);
306 if ((typeeq(n1, gInteger)) && (typeeq(n2, gReal)))
307 return mkretty(gReal, ret);
308 if ((typeeq(n1, gReal)) && (typeeq(n2, gInteger)))
309 return mkretty(gInteger, ret);
310 return mkretty(gNone, ret);
496 311 } }
497 312
498 313 // this is used for reducing expressions in many places (if/exitwhen conditions, assignments etc.) // this is used for reducing expressions in many places (if/exitwhen conditions, assignments etc.)
499 314 int canconvert(const struct typenode *ufrom, const struct typenode *uto, const int linemod) int canconvert(const struct typenode *ufrom, const struct typenode *uto, const int linemod)
500 315 { {
501 const struct typenode *from = ufrom, *to = uto;
502 char ebuf[1024];
503 if (from == NULL || to == NULL)
504 return 0;
505 if (typeeq(from, gAny) || typeeq(to, gAny))
506 return 1;
507 if (isDerivedFrom(from, to))
508 return 1;
509 //if (isDerivedFrom(to, from))
510 // return 1; // blizzard bug allows downcasting erroneously, we don't support this though
511 if (getTypePtr(from)->typename == NULL || getTypePtr(to)->typename == NULL)
512 return 0;
513 if (typeeq(from, gNone) || typeeq(to, gNone))
316 const struct typenode *from = ufrom, *to = uto;
317 char ebuf[1024];
318 if (from == NULL || to == NULL)
319 return 0;
320 if (typeeq(from, gAny) || typeeq(to, gAny))
321 return 1;
322 if (isDerivedFrom(from, to))
323 return 1;
324 if (getTypePtr(from)->typename == NULL || getTypePtr(to)->typename == NULL)
325 return 0;
326 if (typeeq(from, gNone) || typeeq(to, gNone))
327 return 0;
328 from = getPrimitiveAncestor(from);
329 to = getPrimitiveAncestor(to);
330 if (typeeq(from, gNull) && !typeeq(to, gInteger) && !typeeq(to, gReal) && !typeeq(to, gBoolean))
331 return 1;
332 if (strict) {
333 if (typeeq(ufrom, gInteger) && (typeeq(to, gReal) || typeeq(to, gInteger)))
334 return 1;
335 if (typeeq(ufrom, to) && (typeeq(ufrom, gBoolean) || typeeq(ufrom, gString) || typeeq(ufrom, gReal) || typeeq(ufrom, gInteger) || typeeq(ufrom, gCode)))
336 return 1;
337 } else {
338 if (typeeq(from, gInteger) && (typeeq(to, gReal) || typeeq(to, gInteger)))
339 return 1;
340 if (typeeq(from, to) && (typeeq(from, gBoolean) || typeeq(from, gString) || typeeq(from, gReal) || typeeq(from, gInteger) || typeeq(from, gCode)))
341 return 1;
342 }
343
344 snprintf(ebuf, 1024, "Cannot convert %s to %s", ufrom->typename, uto->typename);
345 yyerrorline(3, lineno + linemod, ebuf);
514 346 return 0; return 0;
515 from = getPrimitiveAncestor(from);
516 to = getPrimitiveAncestor(to);
517 if (typeeq(from, gNull) && !typeeq(to, gInteger) && !typeeq(to, gReal) && !typeeq(to, gBoolean))
518 return 1;
519 if (strict) {
520 if (typeeq(ufrom, gInteger) && (typeeq(to, gReal) || typeeq(to, gInteger)))
521 return 1;
522 if (typeeq(ufrom, to) && (typeeq(ufrom, gBoolean) || typeeq(ufrom, gString) || typeeq(ufrom, gReal) || typeeq(ufrom, gInteger) || typeeq(ufrom, gCode)))
523 return 1;
524 } else {
525 if (typeeq(from, gInteger) && (typeeq(to, gReal) || typeeq(to, gInteger)))
526 return 1;
527 if (typeeq(from, to) && (typeeq(from, gBoolean) || typeeq(from, gString) || typeeq(from, gReal) || typeeq(from, gInteger) || typeeq(from, gCode)))
528 return 1;
529 }
530
531 snprintf(ebuf, 1024, "Cannot convert %s to %s", ufrom->typename, uto->typename);
532 yyerrorline(3, lineno + linemod, ebuf);
533 return 0;
534 347 } }
535 348
536 349 // this is used for return statements only // this is used for return statements only
537 350 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)
538 351 { {
539 const struct typenode *from = ufrom, *to = uto;
540 char ebuf[1024];
541 if(typeeq(from, NULL) || typeeq(to, NULL))
542 return; // garbage
543
544 if (typeeq(from, gAny) || typeeq(to, gAny))
545 return; // we don't care
546
547 if (isDerivedFrom(from, to))
548 return; // eg. from = unit, to = handle
549
550 //if (isDerivedFrom(to, from))
551 // return 1; // blizzard bug allows downcasting erroneously, we don't support this though
552 if (getTypePtr(from)->typename == NULL || getTypePtr(to)->typename == NULL)
553 return; // garbage
554
555 if (typeeq(from, gNone) || typeeq(to, gNone))
556 return; // garbage
557
558
559 from = getPrimitiveAncestor(from);
560 to = getPrimitiveAncestor(to);
561 if ((typeeq(to, gReal)) && (typeeq(from, gInteger))) {
562 // can't return integer when it expects a real (added 9.5.2005)
563 snprintf(ebuf, 1024, "Cannot convert returned value from %s to %s", getTypePtr(from)->typename, getTypePtr(to)->typename);
564 yyerrorline(1, lineno + linemod, ebuf);
565 return;
566 }
567
568 if ((typeeq(from, gNull)) && (!typeeq(to, gInteger)) && (!typeeq(to, gReal)) && (!typeeq(to, gBoolean)))
569 return; // can't return null when it expects integer, real or boolean (added 9.5.2005)
570
571 if (strict) {
572 if (isDerivedFrom(ufrom, uto))
573 return;
574 } else if (typeeq(ufrom, uto)){
575 return;
576 }
577
578 snprintf(ebuf, 1024, "Cannot convert returned value from %s to %s", getTypePtr(ufrom)->typename, getTypePtr(uto)->typename);
579 yyerrorline(1, lineno + linemod, ebuf);
580 return;
581 }
352 const struct typenode *from = ufrom, *to = uto;
353 char ebuf[1024];
354 if(typeeq(from, NULL) || typeeq(to, NULL))
355 return; // garbage
582 356
583 struct typenode* mkretty(const struct typenode *ty, int ret){
584 uintptr_t tagMask = (8-1);
585 uintptr_t pointerMask = ~tagMask;
586 uintptr_t ptr = (uintptr_t)ty;
587 ret = ret & tagMask;
588 return (struct typenode*)((ptr & pointerMask) | ret);
589 }
357 if (typeeq(from, gAny) || typeeq(to, gAny))
358 return; // we don't care
590 359
591 int getTypeTag(const struct typenode *ty){
592 uintptr_t tagMask = (8-1);
593 uintptr_t ptr = (uintptr_t)ty;
594 return (int)(ptr & tagMask);
595 }
360 if (isDerivedFrom(from, to))
361 return; // eg. from = unit, to = handle
596 362
597 struct typenode* getTypePtr(const struct typenode *ty){
598 uintptr_t tagMask = (8-1);
599 uintptr_t pointerMask = ~tagMask;
600 uintptr_t ptr = (uintptr_t)ty;
601 return (struct typenode*)(ptr & pointerMask);
602 }
363 if (getTypePtr(from)->typename == NULL || getTypePtr(to)->typename == NULL)
364 return; // garbage
603 365
604 int typeeq(const struct typenode *a, const struct typenode *b){
605 return getTypePtr(a) == getTypePtr(b);
606 }
366 if (typeeq(from, gNone) || typeeq(to, gNone))
367 return; // garbage
607 368
608 const struct typenode *combinetype(const struct typenode *n1, const struct typenode *n2) {
609 int ret = getTypeTag(n1) & getTypeTag(n2);
610 if ((typeeq(n1, gNone)) || (typeeq(n2, gNone))) return mkretty(gNone, ret);
611 if (typeeq(n1, n2)) return mkretty(n1, ret);
612 if (typeeq(n1, gNull))
613 return mkretty(n2, ret);
614 if (typeeq(n2, gNull))
615 return mkretty(n1, ret);
616 n1 = getPrimitiveAncestor(n1);
617 n2 = getPrimitiveAncestor(n2);
618 if (typeeq(n1, n2)) return mkretty(n1, ret);
619 if (typeeq(n1, gNull))
620 return mkretty(n2, ret);
621 if (typeeq(n2, gNull))
622 return mkretty(n1, ret);
623 if ((typeeq(n1, gInteger)) && (typeeq(n2, gReal)))
624 return mkretty(gReal, ret);
625 if ((typeeq(n1, gReal)) && (typeeq(n2, gInteger)))
626 return mkretty(gInteger, ret);
627 // printf("Cannot convert %s to %s", n1->typename, n2->typename);
628 return mkretty(gNone, ret);
629 }
630 369
631 void checkParameters(const struct paramlist *func, const struct paramlist *inp)
632 {
633 const struct typeandname *fi = func->head;
634 const struct typeandname *pi = inp->head;
635 for (;;) {
636 if (fi == NULL && pi == NULL)
637 return;
638 if (fi == NULL && pi != NULL) {
639 yyerrorex(3, "Too many arguments passed to function");
640 return;
370 from = getPrimitiveAncestor(from);
371 to = getPrimitiveAncestor(to);
372 if ((typeeq(to, gReal)) && (typeeq(from, gInteger))) {
373 // can't return integer when it expects a real (added 9.5.2005)
374 snprintf(ebuf, 1024, "Cannot convert returned value from %s to %s", getTypePtr(from)->typename, getTypePtr(to)->typename);
375 yyerrorline(1, lineno + linemod, ebuf);
376 return;
641 377 } }
642 if (fi != NULL && pi == NULL) {
643 yyerrorex(3, "Not enough arguments passed to function");
644 return;
378
379 if ((typeeq(from, gNull)) && (!typeeq(to, gInteger)) && (!typeeq(to, gReal)) && (!typeeq(to, gBoolean)))
380 return; // can't return null when it expects integer, real or boolean (added 9.5.2005)
381
382 if (strict) {
383 if (isDerivedFrom(ufrom, uto))
384 return;
385 } else if (typeeq(ufrom, uto)){
386 return;
645 387 } }
646 canconvert(pi->ty, fi->ty, 0);
647 pi = pi->next;
648 fi = fi->next;
649 }
388
389 snprintf(ebuf, 1024, "Cannot convert returned value from %s to %s", getTypePtr(ufrom)->typename, getTypePtr(uto)->typename);
390 yyerrorline(1, lineno + linemod, ebuf);
391 return;
650 392 } }
651 393
652 394 void isnumeric(const struct typenode *ty) void isnumeric(const struct typenode *ty)
653 395 { {
654 ty = getPrimitiveAncestor(ty);
655 if (!(ty == gInteger || ty == gReal || ty == gAny))
656 yyerrorline(3, islinebreak ? lineno - 1 : lineno, "Cannot be converted to numeric type");
396 ty = getPrimitiveAncestor(ty);
397 if (!(ty == gInteger || ty == gReal || ty == gAny))
398 yyerrorline(3, islinebreak ? lineno - 1 : lineno, "Cannot be converted to numeric type");
657 399 } }
658 400
659 void checkcomparisonsimple(const struct typenode *a) {
660 const struct typenode *pa;
661 pa = getPrimitiveAncestor(a);
662 if (typeeq(pa, gString) || typeeq(pa, gHandle) || typeeq(pa, gCode) || typeeq(pa, gBoolean)) {
663 yyerrorex(3, "Comparing the order/size of 2 variables only works on reals and integers");
664 return;
665 }
666 if (typeeq(pa, gNull))
667 yyerrorex(3, "Comparing null is not allowed");
401 void checkcomparisonsimple(const struct typenode *a)
402 {
403 const struct typenode *pa;
404 pa = getPrimitiveAncestor(a);
405 if (typeeq(pa, gString) || typeeq(pa, gHandle) || typeeq(pa, gCode) || typeeq(pa, gBoolean)) {
406 yyerrorex(3, "Comparing the order/size of 2 variables only works on reals and integers");
407 return;
408 }
409 if (typeeq(pa, gNull))
410 yyerrorex(3, "Comparing null is not allowed");
668 411 } }
669 412
670 413 void checkcomparison(const struct typenode *a, const struct typenode *b) void checkcomparison(const struct typenode *a, const struct typenode *b)
671 414 { {
672 const struct typenode *pa, *pb;
673 pa = getPrimitiveAncestor(a);
674 pb = getPrimitiveAncestor(b);
675 if (typeeq(pa, gString) || typeeq(pa, gHandle) || typeeq(pa, gCode) || typeeq(pa, gBoolean) || typeeq(pb, gString) || typeeq(pb, gCode) || typeeq(pb, gHandle) || typeeq(pb, gBoolean)) {
676 yyerrorex(3, "Comparing the order/size of 2 variables only works on reals and integers");
677 return;
678 }
679 if (typeeq(pa, gNull) && typeeq(pb, gNull))
680 yyerrorex(3, "Comparing null is not allowed");
415 const struct typenode *pa, *pb;
416 pa = getPrimitiveAncestor(a);
417 pb = getPrimitiveAncestor(b);
418 if (typeeq(pa, gString) || typeeq(pa, gHandle) || typeeq(pa, gCode) || typeeq(pa, gBoolean) || typeeq(pb, gString) || typeeq(pb, gCode) || typeeq(pb, gHandle) || typeeq(pb, gBoolean)) {
419 yyerrorex(3, "Comparing the order/size of 2 variables only works on reals and integers");
420 return;
421 }
422 if (typeeq(pa, gNull) && typeeq(pb, gNull))
423 yyerrorex(3, "Comparing null is not allowed");
681 424 } }
682 425
683 426 void checkeqtest(const struct typenode *a, const struct typenode *b) void checkeqtest(const struct typenode *a, const struct typenode *b)
684 427 { {
685 const struct typenode *pa, *pb;
686 pa = getPrimitiveAncestor(a);
687 pb = getPrimitiveAncestor(b);
688 if ((typeeq(pa, gInteger) || typeeq(pa, gReal)) && (typeeq(pb, gInteger) || typeeq(pb, gReal)))
689 return;
690 if (typeeq(pa, gNull) || typeeq(pb, gNull))
691 return;
692 if (!typeeq(pa, pb)) {
693 yyerrorex(3, "Comparing two variables of different primitive types (except real and integer) is not allowed");
694 return;
695 }
696 }
697
698 void dofile(FILE *fp, const char *name)
699 {
700 lineno = 1;
701 islinebreak = 1;
702 isconstant = 0;
703 inconstant = 0;
704 inblock = 0;
705 afterendglobals = 0;
706 int olderrs = haderrors;
707 yy_switch_to_buffer(yy_create_buffer(fp, BUFSIZE));
708 curfile = name;
709 while (yyparse())
710 ;
711 if (olderrs == haderrors){
712 printf("Parse successful: %8d lines: %s\n", lineno, curfile);
713 }else{
714 printf("%s failed with %d error%s\n", curfile, haderrors - olderrs,(haderrors == olderrs + 1) ? "" : "s");
715 }
716 totlines += lineno;
717 fno++;
428 const struct typenode *pa, *pb;
429 pa = getPrimitiveAncestor(a);
430 pb = getPrimitiveAncestor(b);
431 if ((typeeq(pa, gInteger) || typeeq(pa, gReal)) && (typeeq(pb, gInteger) || typeeq(pb, gReal)))
432 return;
433 if (typeeq(pa, gNull) || typeeq(pb, gNull))
434 return;
435 if (!typeeq(pa, pb)) {
436 yyerrorex(3, "Comparing two variables of different primitive types (except real and integer) is not allowed");
437 return;
438 }
718 439 } }
719 440
720 void printversion()
721 {
722 printf("Pjass version %s by Rudi Cilibrasi, modified by AIAndy, PitzerMike, Deaod and lep\n", VERSIONSTR);
723 }
724 441
725 void doparse(int argc, char **argv)
726 {
727 int i;
728 for (i = 1; i < argc; ++i) {
729 if (argv[i][0] == '-' && argv[i][1] == 0) {
730 dofile(stdin, "<stdin>");
731 didparse = 1;
732 continue;
733 }
734 if (strcmp(argv[i], "-h") == 0) {
735 printversion();
736 printf(
737 "To use this program, list the files you would like to parse in order.\n"
738 "If you would like to parse from standard input (the keyboard), then\n"
739 "use - as an argument. If you supply no arguments to pjass, it will\n"
740 "parse the console standard input by default.\n"
741 "To test this program, go into your Scripts directory, and type:\n"
742 "pjass common.j common.ai Blizzard.j\n"
743 "pjass accepts some options:\n"
744 "pjass -h Display this help\n"
745 "pjass -v Display version information and exit\n"
746 "pjass -e1 Ignores error level 1\n"
747 "pjass +e2 Undo Ignore of error level 2\n"
748 "pjass +s Enable strict downcast evaluation\n"
749 "pjass -s Disable strict downcast evaluation\n"
750 "pjass +rb Enable returnbug\n"
751 "pjass -rb Disable returnbug\n"
752 "pjass - Read from standard input (may appear in a list)\n"
753 );
754 exit(0);
755 continue;
756 }
757 if (strcmp(argv[i], "-v") == 0) {
758 printf("%s version %s\n", argv[0], VERSIONSTR);
759 exit(0);
760 continue;
761 }
762 if (strcmp(argv[i], "+s") == 0) {
763 strict = 1;
764 continue;
765 }
766 if (strcmp(argv[i], "-s") == 0) {
767 strict = 0;
768 continue;
769 }
770 if (strcmp(argv[i], "+rb") == 0) {
771 returnbug = 1;
772 continue;
773 }
774 if (strcmp(argv[i], "-rb") == 0) {
775 returnbug = 0;
776 continue;
777 }
778 if (argv[i][0] == '-' && argv[i][1] == 'e' && argv[i][2] >= '0' && argv[i][2] < ('0' + ERRORLEVELNUM)) {
779 showerrorlevel[argv[i][2]-'0'] = 0;
780 continue;
781 }
782 if (argv[i][0] == '+' && argv[i][1] == 'e' && argv[i][2] >= '0' && argv[i][2] < ('0' + ERRORLEVELNUM)) {
783 showerrorlevel[argv[i][2]-'0'] = 1;
784 continue;
785 }
786 FILE *fp;
787 fp = fopen(argv[i], "rb");
788 if (fp == NULL) {
789 printf("Error: Cannot open %s\n", argv[i]);
790 haderrors++;
791 continue;
792 }
793 dofile(fp, argv[i]);
794 didparse = 1;
795 fclose(fp);
796 }
797 if (argc == 1) {
798 didparse = 1;
799 dofile(stdin, "<stdin>");
800 }
801 }
File misc.h changed (mode: 100644) (index 3e41337..0e2c211)
4 4 // thanks to Jeff Pang for the handy documentation that this was based // thanks to Jeff Pang for the handy documentation that this was based
5 5 // on at http://jass.sourceforge.net // on at http://jass.sourceforge.net
6 6 // Released under the BSD license // Released under the BSD license
7
8 #ifndef MISC_H
9 #define MISC_H
10
7 11 #include <stdio.h> #include <stdio.h>
8 12 #include <limits.h> #include <limits.h>
9 13 #include <stdarg.h> #include <stdarg.h>
14 #include <stdint.h>
10 15
11 #define BUFSIZE (16384)
16 #include "hashtable.h"
17 #include "typeandname.h"
18 #include "paramlist.h"
19 #include "funcdecl.h"
12 20
13 struct typenode {
14 char *typename;
15 const struct typenode *superclass;
16 };
17
18 struct typeandname {
19 const struct typenode *ty;
20 const char *name;
21 int isarray, isconst, lineno, fn;
22 struct typeandname *next;
23 };
24
25 struct paramlist {
26 struct typeandname *head;
27 struct typeandname **tail;
28 };
29
30 struct funcdecl {
31 char *name;
32 int isconst;
33 struct paramlist *p;
34 const struct typenode *ret;
35 };
21 #define BUFSIZE (16384)
36 22
37 23 union node { union node {
38 24 char *str; char *str;
 
... ... union node {
43 29 struct typeandname *tan; struct typeandname *tan;
44 30 }; };
45 31
46 struct hashnode {
47 const char *name;
48 void *val;
32 enum errortype {
33 syntaxerror = 0,
34 semanticerror,
35 warning,
49 36 }; };
50 37
51 struct hashtable {
52 size_t size;
53 size_t count;
54 struct hashnode *bucket;
55 };
56 38
57 void yyerrorline (int errorlevel, int line, char *s);
58 void yyerrorex (int errorlevel, char *s);
59 void yyerror (char *s);
39 void yyerrorline (int errorlevel, int line, const char *s);
40 void yyerrorex (int errorlevel, const char *s);
41 void yyerror (const char *s);
60 42
61 void getsuggestions(const char*, char*, int, int, ...);
62 void *lookup(struct hashtable *h, const char *name);
63 43 void put(struct hashtable *h, const char *name, void *val); void put(struct hashtable *h, const char *name, void *val);
64 void clear(struct hashtable *h);
65 void init();
66 44
67 struct typenode *newtypenode(const char *typename, const struct typenode *superclass);
68 struct paramlist *newparamlist();
69 struct typeandname *newtypeandname(const struct typenode *ty, const char *name);
70 struct typeandname *newtypeandnamewithreturn(const struct typenode *ty, const char *name, int retbool);
71 const struct typenode *getPrimitiveAncestor(const struct typenode *cur);
72 int isDerivedFrom(const struct typenode *cur, const struct typenode *base);
73 void addParam(struct paramlist *tl, struct typeandname *tan);
74 struct funcdecl *newfuncdecl();
75 void showfuncdecl(struct funcdecl *fd);
45 void getsuggestions(const char*, char*, size_t, int, ...);
46
76 47 const struct typenode *binop(const struct typenode *a, const struct typenode *b); const struct typenode *binop(const struct typenode *a, const struct typenode *b);
77 int canconvert(const struct typenode *from, const struct typenode *to, const int linemod);
78 void canconvertreturn(const struct typenode *from, const struct typenode *to, const int linemod);
79 struct typenode* mkretty(const struct typenode *ty, int ret);
80 struct typenode* getTypePtr(const struct typenode *ty);
81 int getTypeTag(const struct typenode *ty);
82 int typeeq(const struct typenode*, const struct typenode*);
83 48 const struct typenode *combinetype(const struct typenode *n1, const struct typenode *n2); const struct typenode *combinetype(const struct typenode *n1, const struct typenode *n2);
84 49 void checkParameters(const struct paramlist *func, const struct paramlist *inp); void checkParameters(const struct paramlist *func, const struct paramlist *inp);
50 const struct typeandname *getVariable(const char *varname);
51 int canconvert(const struct typenode *ufrom, const struct typenode *uto, const int linemod);
52 void canconvertreturn(const struct typenode *ufrom, const struct typenode *uto, const int linemod);
53
85 54 void validateGlobalAssignment(const char *varname); void validateGlobalAssignment(const char *varname);
55
56 void isnumeric(const struct typenode *ty);
57 void checkcomparison(const struct typenode *a, const struct typenode *b);
86 58 void checkcomparisonsimple(const struct typenode *a); void checkcomparisonsimple(const struct typenode *a);
87
59 void checkeqtest(const struct typenode *a, const struct typenode *b);
60
88 61 extern int fno, lineno, totlines, islinebreak, isconstant, inblock, inconstant, infunction; extern int fno, lineno, totlines, islinebreak, isconstant, inblock, inconstant, infunction;
89 62 extern int haderrors; extern int haderrors;
90 63 extern int ignorederrors; extern int ignorederrors;
 
... ... extern int returnbug;
95 68 extern int fnhasrbannotation; extern int fnhasrbannotation;
96 69 extern int rbannotated; extern int rbannotated;
97 70 extern int afterendglobals; extern int afterendglobals;
71 extern int *showerrorlevel;
98 72 extern char *yytext; extern char *yytext;
99 73 extern const char *curfile; extern const char *curfile;
100 74 extern int yydebug; extern int yydebug;
 
... ... extern struct hashtable functions, globals, locals, params, types, initialized,
103 77 extern struct typenode *gInteger, *gReal, *gBoolean, *gString, *gCode, *gHandle, *gNothing, *gNull, *gAny, *gNone, *gEmpty; extern struct typenode *gInteger, *gReal, *gBoolean, *gString, *gCode, *gHandle, *gNothing, *gNull, *gAny, *gNone, *gEmpty;
104 78 extern struct funcdecl *fCurrent; extern struct funcdecl *fCurrent;
105 79 extern const struct typenode *retval; extern const struct typenode *retval;
106 const struct typeandname *getVariable(const char *varname);
107 void isnumeric(const struct typenode *ty);
108 void checkcomparison(const struct typenode *a, const struct typenode *b);
109 void checkeqtest(const struct typenode *a, const struct typenode *b);
110 void init();
111 void doparse(int argc, char **argv);
80
81 #endif
File paramlist.c added (mode: 100644) (index 0000000..92a4597)
1 #include <stdlib.h>
2
3 #include "paramlist.h"
4
5
6 struct paramlist *newparamlist()
7 {
8 struct paramlist *tl = calloc(sizeof(struct paramlist), 1);
9 tl->head = NULL;
10 tl->tail = &tl->head;
11 return tl;
12 }
13
14 void addParam(struct paramlist *pl, struct typeandname *tan)
15 {
16 tan->next = *(pl->tail);
17 *(pl->tail) = tan;
18 }
19
20
21
File paramlist.h added (mode: 100644) (index 0000000..bb25336)
1 #ifndef PARAMLIST_H
2 #define PARAMLIST_H
3
4 #include "typeandname.h"
5
6 struct paramlist {
7 struct typeandname *head;
8 struct typeandname **tail;
9 };
10
11 struct paramlist *newparamlist(void);
12
13 void addParam(struct paramlist *tl, struct typeandname *tan);
14
15 #endif
File token.l changed (mode: 100644) (index d2f9b79..fd5f044)
8 8 %{ %{
9 9 /* need this for the call to atof() below */ /* need this for the call to atof() below */
10 10
11 int rawcodelen;
12 int rawcodespecial;
13 int rawcodestartline;
11 static int rawcodelen;
12 static int rawcodestartline;
14 13
15 14 #include "grammar.tab.h" #include "grammar.tab.h"
16 15 #include "misc.h" #include "misc.h"
File typeandname.c added (mode: 100644) (index 0000000..6cb071e)
1 #include <string.h>
2 #include <stdlib.h>
3
4 #include "typeandname.h"
5
6 struct typeandname *newtypeandname(const struct typenode *ty, const char *name)
7 {
8 struct typeandname *tan = calloc(sizeof(struct typeandname), 1);
9 tan->ty = ty;
10 tan->name = strdup(name);
11 tan->next = NULL;
12 return tan;
13 }
14
15 struct typenode *newtypenode(const char *typename, const struct typenode *superclass)
16 {
17 struct typenode *result;
18 result = aligned_alloc(8, sizeof(struct typenode));
19 result->typename = strdup(typename);
20 result->superclass = superclass;
21 return result;
22 }
23
24
25
26 const struct typenode *getPrimitiveAncestor(const struct typenode *cur)
27 {
28 while (getTypePtr(cur)->superclass)
29 cur = getTypePtr(cur)->superclass;
30 return cur;
31 }
32
33 int isDerivedFrom(const struct typenode *cur, const struct typenode *base)
34 {
35 for(; getTypePtr(cur); cur = getTypePtr(cur)->superclass){
36 if(typeeq(cur, base)){
37 return 1;
38 }
39 }
40 return 0;
41 }
42
43 struct typenode* mkretty(const struct typenode *ty, uint8_t ret)
44 {
45 uintptr_t tagMask = (8-1);
46 uintptr_t pointerMask = ~tagMask;
47 uintptr_t ptr = (uintptr_t)ty;
48 ret = ret & tagMask;
49 return (struct typenode*)((ptr & pointerMask) | ret);
50 }
51
52 uint8_t getTypeTag(const struct typenode *ty)
53 {
54 uintptr_t tagMask = (8-1);
55 uintptr_t ptr = (uintptr_t)ty;
56 return (uint8_t)(ptr & tagMask);
57 }
58
59 struct typenode* getTypePtr(const struct typenode *ty)
60 {
61 uintptr_t tagMask = (8-1);
62 uintptr_t pointerMask = ~tagMask;
63 uintptr_t ptr = (uintptr_t)ty;
64 return (struct typenode*)(ptr & pointerMask);
65 }
66
67 int typeeq(const struct typenode *a, const struct typenode *b)
68 {
69 return getTypePtr(a) == getTypePtr(b);
70 }
71
File typeandname.h added (mode: 100644) (index 0000000..58e1d73)
1 #ifndef TYPEANDNAME_H
2 #define TYPEANDNAME_H
3
4 #include <stdint.h>
5
6 struct typenode {
7 char *typename;
8 const struct typenode *superclass;
9 };
10
11 struct typeandname {
12 const struct typenode *ty;
13 const char *name;
14 int isarray, isconst, lineno, fn;
15 struct typeandname *next;
16 };
17
18 struct typenode *newtypenode(const char *typename, const struct typenode *superclass);
19
20 struct typeandname *newtypeandname(const struct typenode *ty, const char *name);
21
22 const struct typenode *getPrimitiveAncestor(const struct typenode *cur);
23
24 int isDerivedFrom(const struct typenode *cur, const struct typenode *base);
25
26
27 struct typenode* mkretty(const struct typenode *ty, uint8_t ret);
28
29 struct typenode* getTypePtr(const struct typenode *ty);
30
31 uint8_t getTypeTag(const struct typenode *ty);
32
33 int typeeq(const struct typenode*, const struct typenode*);
34
35
36
37 #endif
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