Compare commits

...

1542 commits
0.1.9 ... main

Author SHA1 Message Date
Dale Weiler
297eab9e5e reset framevalue on includes like fteqcc 2021-07-09 14:05:01 -04:00
Dale Weiler
da63ad7e07 fix -fsort-operands 2021-07-09 14:04:28 -04:00
Dale Weiler
ddcae703e3 allow dots in frame names to compile hypnotic 2021-07-09 12:17:02 -04:00
Dale Weiler
6cf25c0ec6 allow comparing explicitly against nil 2021-07-07 23:11:17 -04:00
Dale Weiler
663723f00a fixed mixing of old and new framemacro syntax 2021-07-07 22:58:13 -04:00
Dale Weiler
1e8ce1733b fix bug 197, 198, and 199 properly 2021-04-06 14:47:35 -04:00
Dale Weiler
47475bb455 fix bug #188 2021-03-27 20:45:40 -04:00
Dale Weiler
71138cbe1a rewrite dead code elimination for conditionals 2021-03-27 20:32:24 -04:00
Dale Weiler
85c79d2f1c fclose when fopen actually succeeds 2021-03-26 19:02:27 -04:00
Dale Weiler
13bcb5c5b1 set m_op as well when doing a-(-b) => a+b peephole 2021-03-26 18:57:31 -04:00
Dale Weiler
465941f357 pass parent scope to parse_statement_or_block
previous behavior when parsing a statement where a block is typically expected would fail to associate the statement with the parent block it's in, resulting in variable declarations ending up in global scope.

this fixes #197
2021-03-02 10:46:05 -05:00
Dale Weiler
237722c0b2 fix crash when cleaning up functions related to [[accumulate]] 2020-10-27 19:40:30 -04:00
Dale Weiler
f971f89e1e new makefile 2020-04-17 13:28:27 -04:00
Wolfgang Bumiller
94c2936bfa tests: xor peephole optimization regression test
Signed-off-by: Wolfgang Bumiller <wry.git@bumiller.com>
2019-09-15 10:27:26 +02:00
Wolfgang Bumiller
2d4a054440 ir: fix generation of multi-op vinstrs
Do not assume that the destination is a temporary location,
as our peephole optimizer will break this. For example, the
following IR code (generated via from `x ^= gety()`):

    (0) binst6 <- BITXOR   x,      call5
    (0) x <- STORE_F       binst6

after peephole optimization becomes:

    (7) x <- BITXOR        x,      call5

Therefore we cannot assume that the output of the virtual
xor instruction can be utilized as a temporary value.

BITXOR becomes `(x | y) - (x & y)`, which would wrongly be
generated as:
    x = x | y;
    temp0 = x & y;
    x = x - temp0;

While this particular case can be fixed by using temp0 first
and then x, the cross-product case would not be so simple.

Signed-off-by: Wolfgang Bumiller <wry.git@bumiller.com>
Fixes #190
2019-09-15 10:23:47 +02:00
Wolfgang Bumiller
031f827da5 introduce another vinstr temp
Some vinstrs are currently broken when using peephole
optimization as they appear as writing to a temporary ssa
output before being stored into their real destination,
causing the store to be optimized out, but the generated
code relies on having the destination as another temporary
value available.

Let's just add a 2nd temp to be used in those cases.

Signed-off-by: Wolfgang Bumiller <wry.git@bumiller.com>
2019-09-15 10:12:40 +02:00
Dale Weiler
451873ae52
Merge pull request #187 from divVerent/patch-1
Fix printing of floating poing values in -dumpfin.
2019-02-04 09:20:23 -05:00
divVerent
9c81ff263a
Fix printing of floating poing values in -dumpfin.
%g is not lossless for single precision floats - %.9g is (other than distinguishing NaNs, who cares).
2019-02-04 06:14:58 -08:00
Dale Weiler
620bd76e76 fix __builtin_nan and add some missing builtins 2018-11-14 08:43:22 -05:00
Dale Weiler
2d99ce609d fix octals 2018-10-30 17:32:21 -04:00
Dale Weiler
0904a1ceb7 fixes for progs.src 2018-09-01 00:48:18 -04:00
Dale Weiler
c74fabffda Merge branch 'master' of github.com:graphitemaster/gmqcc 2018-05-09 21:19:39 -04:00
Dale Weiler
092067482f added -fdefault-eraseable which is the same as adding [[eraseable]] to all definitions
instead the opposite behavior can be controlled with [[noerase]] attribute
2018-05-09 21:18:37 -04:00
Dale Weiler
dac058107a
Delete .travis.yml 2018-05-05 15:44:21 -04:00
Dale Weiler
9a21c638fa error if a function is called from global scope opposed to crashing 2018-05-05 15:38:12 -04:00
Wolfgang Bumiller
97a74eb677 catch broken vector member access
These kinds of expressions currently cannot be handled
without pionter support in the qcvm without scanning the
ast from within ast_member::codegen for an assignments as
seen in the added test case.

This change makes code like that return a pointer type which
will cause an error that we did not get a vector or field
back. With pointer support this pointer could actually be
used instead.

So at least it shouldn't silently produce broken code
anymore.

Signed-off-by: Wolfgang Bumiller <wry.git@bumiller.com>
2018-01-14 10:58:29 +01:00
Wolfgang Bumiller
f84c8ea629 add variable search order test
Signed-off-by: Wolfgang Bumiller <wry.git@bumiller.com>
2018-01-14 09:33:05 +01:00
Wolfgang Bumiller
e920766b10 Make parser_find_local only actually search locals
Fixes #163
Signed-off-by: Wolfgang Bumiller <wry.git@bumiller.com>
2018-01-14 09:33:05 +01:00
Wolfgang Bumiller
e006aa8238 Revert "search for funciton param first before function locals, this fixes #163"
This reverts commit 3cf2c52fce.
2018-01-14 09:33:05 +01:00
Dale Weiler
73d3d7eec1 fix some UB 2017-12-01 13:55:19 -05:00
Dale Weiler
3cf2c52fce search for funciton param first before function locals, this fixes #163 2017-12-01 12:24:50 -05:00
Dale Weiler
1580c23556 Merge branch 'master' of github.com:graphitemaster/gmqcc 2017-11-26 17:48:13 -05:00
Dale Weiler
b14a02e735 don't generate storep for vector field unless it's an ent field 2017-11-26 17:47:27 -05:00
Dale Weiler
679e3771de
Merge pull request #177 from xonotic/terencehill/warning_removal
Get rid of a warning on Windows
2017-11-26 17:30:42 -05:00
Dale Weiler
d9127bf28a
Merge pull request #180 from xonotic/mem_leak_fix_on_failure_paths
two small memory leak fixes on failure paths
2017-11-26 17:30:30 -05:00
Dale Weiler
fa7dce495b fix writing of globaldefs for vector subcomponents so that FTE field remapping works 2017-11-26 17:26:00 -05:00
Dale Weiler
02b20dbd09 fix member binops on entity fields to generate STOREP, this fixes stuff like ent.vec.x += value. 2017-11-26 17:09:38 -05:00
Wolfgang Bumiller
6ad5f18ef1 cleanup: 'move of a temporary object prevents copy elision' 2017-07-23 10:11:31 +02:00
Wolfgang Bumiller
047ecd426f move more parser code to c++, fix crashes with gcc
we initialized the parser with malloc -> memset to zero ->
placement new. With gcc the latter caused the memset to be
optimized out, causing uninitialized value accesses.
2017-07-23 10:11:31 +02:00
Wolfgang Bumiller
fb3af2831b cleanup some silly more warnings 2017-07-23 10:11:31 +02:00
Wolfgang Bumiller
5a0d645ede cleanup: silence fallthrough warnings 2017-07-23 10:11:31 +02:00
terencehill
27c0886ffb Get rid of a warning on Windows 2017-06-23 16:21:22 +02:00
Wolfgang Bumiller
163c4b99a4 tests: add check for vector negation 2017-06-22 08:45:38 +02:00
Wolfgang Bumiller
eb2d478770 qcvm: add stov builtin #16 2017-06-22 08:45:18 +02:00
Wolfgang Bumiller
3f5305af58 ir: fix vector negation using the nil value
We cannot use OFS_NULL as it is only a single value and
overlaps with OFS_RETURN.
2017-06-22 08:44:36 +02:00
David Carlier
8538658e83 two small memory leak fixes on failure paths 2017-05-23 21:56:03 +01:00
Wolfgang Bumiller
8b2149e315 sanitize: shift 1u (unsigned) for flag bits 2017-02-14 19:24:04 +01:00
Wolfgang Bumiller
c285eb385d c++: exec.cpp 2017-02-11 11:43:58 +01:00
Wolfgang Bumiller
2dde6d903e c++: ir_function::m_params 2016-12-03 21:42:15 +01:00
Wolfgang Bumiller
4bf63bb379 c++: ir: function_allocator 2016-12-03 21:39:09 +01:00
Wolfgang Bumiller
95d232ca72 c++: ir_block::m_instr 2016-12-03 21:30:33 +01:00
Wolfgang Bumiller
90f190f5e1 c++: ir_block::m_exits 2016-12-03 20:34:42 +01:00
Wolfgang Bumiller
566c17a964 c++: ir_block::m_entries 2016-12-03 20:32:26 +01:00
Dale Weiler
a5636899f2 Cleaner way to set the mask for -Wunused-component 2016-11-24 19:54:17 +00:00
Dale Weiler
17c0812ae4 Just mark LOCAL_RETURN noref instead of checking for '#' in the name 2016-11-24 15:50:48 +00:00
Dale Weiler
3a7848d67c Remove parser m_uses in favor of {IR,AST}_FLAG_NOREF instead 2016-11-24 15:33:58 +00:00
Dale Weiler
def1a26b12 Add -Wunused-component like -Wunused-variable but warns about unused components of vector 2016-11-24 14:52:57 +00:00
Dale Weiler
eab20602b1 more intelligent handling of unused vector fields 2016-11-24 14:44:28 +00:00
Dale Weiler
69fa4f8dbd Fix #158 2016-11-24 14:08:38 +00:00
Dale Weiler
966991601c Fix #161 2016-11-24 13:41:26 +00:00
Dale Weiler
01f3447e5b Fix #171 2016-11-24 13:40:22 +00:00
Dale Weiler
9821b6a075 Fix fieldfuncs test and track unused variables through writes as well. 2016-11-19 12:19:00 +00:00
Dale Weiler
6938567c6c Don't generate unused warnings for unused constants 2016-11-19 11:46:32 +00:00
Wolfgang Bumiller
0b94d7583c fix access to fields of vector members
When ast_member encounters the result of an ast_entfield it
has to replace the ast_entfield's codegen as we cannot
evaluate the field access first.

We then perform the same action as ast_entfield but call
vectorMember on the field before issuing the load/address
instruction.

This effectively turns the codegen of the following ast
structure:
    member_of {
        field_of {
            entity,
            a_vector
        }
        memberid
    }
into the one of this structure:
    field_of {
        entity,
        member_of {
            a_vector
            memberid
        }
    }
2016-11-19 16:22:18 +01:00
Wolfgang Bumiller
4c48bae203 Revert "Fix ent.vec.{x,y,z} writes"
This reverts commit ad1cfcfeaa.
2016-11-19 16:22:13 +01:00
Dale Weiler
ad1cfcfeaa Fix ent.vec.{x,y,z} writes 2016-11-19 10:42:33 +00:00
Dale Weiler
eca4e2c309 Unused globals even if they have an initial value should produce unused diagnostic 2016-11-19 10:05:58 +00:00
Dale Weiler
167207e98c Warning 2016-05-23 16:47:40 -04:00
Wolfgang Bumiller
e06ad170de update .gitignore 2016-02-10 19:01:12 +01:00
Dale Weiler
3714a507c2 Merge pull request #172 from TimePath/cmake
Add CMakeLists.txt
2016-01-03 01:15:18 -05:00
TimePath
63c679ee81 Add CMakeLists.txt 2016-01-03 17:14:02 +11:00
Dale Weiler
be64736dd4 Fixes 2016-01-03 00:38:58 -05:00
Dale Weiler
f6bc9705d2 eh 2016-01-03 00:35:12 -05:00
Dale Weiler
5d8c18dcab Fix makefile 2016-01-03 00:34:29 -05:00
Dale Weiler
1a18ff5294 Merge branch 'master' into cleanup 2016-01-02 22:30:35 -05:00
Dale Weiler
3f4659b5d5 oops 2015-12-28 08:00:54 -05:00
Dale Weiler
6024e377ba Fix unary negation (-) 2015-12-28 07:58:54 -05:00
Wolfgang Bumiller
ee3c1e43c9 tempcommitting a whole bunch of to-c++ conversions 2015-05-02 09:48:24 +02:00
Wolfgang Bumiller
a9ac6987a6 remove a bunch of unnecessary c-casts to ast_expression* 2015-02-01 12:15:30 +01:00
Wolfgang Bumiller
fab640da4c Merge branch 'cleanup' of git://github.com/graphitemaster/gmqcc into cleanup 2015-02-01 12:13:59 +01:00
Wolfgang Bumiller
fd0cc40b9c fix std::string constructed from nullptr 2015-02-01 12:13:22 +01:00
Wolfgang Bumiller
6d4539814e ast_unary::make: safer double-negation optimization check 2015-02-01 12:13:05 +01:00
Wolfgang Bumiller
896d4c53a3 fix backward propagateSideEffect impl 2015-02-01 12:12:40 +01:00
Wolfgang Bumiller
d8e9b1b35d destructor call order is important here 2015-02-01 11:52:58 +01:00
Wolfgang Bumiller
66d908f39b ir_instr_delete_quick needs to clear _m_ops 2015-02-01 11:49:46 +01:00
Wolfgang Bumiller
45236a644f ast conversion mostly finished 2015-02-01 11:44:00 +01:00
Dale Weiler
fa21d85820 Same on the cleanup branch 2015-01-30 00:46:25 -05:00
Dale Weiler
e922403aa8 Don't allocate globals for constants that aren't read 2015-01-30 00:40:59 -05:00
Dale Weiler
ff37abb0c7 Constant folding for strings 2015-01-30 00:25:10 -05:00
Dale Weiler
90b5a6538a Merge branch 'cleanup' of github.com:graphitemaster/gmqcc into cleanup 2015-01-30 00:20:41 -05:00
Dale Weiler
866fc3e247 Constant folding for string comparisons too 2015-01-30 00:18:52 -05:00
Dale Weiler
41a76ab91d Fix for loops 2015-01-29 23:33:59 -05:00
Dale Weiler
b640049912 For now 2015-01-29 23:13:55 -05:00
Wolfgang Bumiller
9335bc2f4f BROKEN: more ast nodes converted 2015-01-29 20:29:34 +01:00
Wolfgang Bumiller
49f4fedecf add another test that we just didn't have anywhere else yet 2015-01-25 09:29:02 +01:00
Wolfgang Bumiller
6149f6a1d0 BROKEN: in the middle of converting ast nodes to c++ with constructors and methods 2015-01-25 09:24:26 +01:00
Wolfgang Bumiller
9d98805dfb a whole lotta 'm_'s 2015-01-24 12:25:46 +01:00
Wolfgang Bumiller
e7d1e701c4 why didn't gcc catch that... 2015-01-24 10:26:43 +01:00
Wolfgang Bumiller
5c64437189 fix for loops 2015-01-20 20:55:27 +01:00
Wolfgang Bumiller
5968e3faa0 for now just call the dtors like this 2015-01-20 20:33:07 +01:00
Wolfgang Bumiller
566e761546 more c++ migration for ast/ir/code; reached a working condition here 2015-01-20 20:25:56 +01:00
Wolfgang Bumiller
f09c6a5d63 temp committing major c++ification 2015-01-20 16:43:58 +01:00
Wolfgang Bumiller
794396df79 making ast nodes derive from ast_expression 2015-01-19 14:00:04 +01:00
Wolfgang Bumiller
380fb3d44f this can be a move 2015-01-19 13:46:30 +01:00
Wolfgang Bumiller
dedb3a49bd ast_expression: params -> type_params 2015-01-19 13:46:10 +01:00
Wolfgang Bumiller
9535805c02 renaming ast_function::vtype to function_type 2015-01-19 13:37:22 +01:00
Wolfgang Bumiller
44b0d7f658 ast_expression now derives from ast_node 2015-01-19 13:33:39 +01:00
Wolfgang Bumiller
1826971301 renaming some ast_node members before making ast_expression an ast_node to use the compiler to help find possible clashes 2015-01-19 13:32:26 +01:00
Dale Weiler
db9c37d18b Rewrite constant folder in C++ 2015-01-15 20:27:17 -05:00
Dale Weiler
7e0e041527 Forgot about this file 2015-01-15 18:12:54 -05:00
Dale Weiler
e2ba77a546 Rewrite intrinsic system in C++ 2015-01-15 18:11:41 -05:00
Dale Weiler
76278e8b97 s/NULL/nullptr/ 2015-01-15 15:18:33 -05:00
Dale Weiler
6e68526680 Use std::vector for static_names 2015-01-15 15:15:35 -05:00
Dale Weiler
0ecfe18f49 Cleanup 2015-01-15 15:11:30 -05:00
Dale Weiler
e8fbae4b3e Not needed 2015-01-15 15:10:02 -05:00
Dale Weiler
f38e6b48db Use std::vector for SYA 2015-01-15 15:08:50 -05:00
Dale Weiler
a1f13499f9 Use std::vector for break and continue ast blocks 2015-01-15 14:22:22 -05:00
Dale Weiler
539dc4a3dc Use std::vector for ast switch cases 2015-01-15 14:19:07 -05:00
Dale Weiler
2e037832d3 Use std::vector for ast blocks 2015-01-15 14:15:44 -05:00
Dale Weiler
987f765c20 std::vector for initlist 2015-01-15 14:07:26 -05:00
Dale Weiler
b345b4e21b Eliminate use of vec_ in intrin.cpp 2015-01-15 03:01:26 -05:00
Dale Weiler
9c31c53cc5 Eliminate use of vec_ in fold.c 2015-01-15 02:47:42 -05:00
Dale Weiler
fe95b28a35 More std::vector 2015-01-15 02:17:37 -05:00
Dale Weiler
317e0499f7 More std::vector 2015-01-15 01:57:40 -05:00
Dale Weiler
b5d8b44503 More std::vector 2015-01-15 01:35:56 -05:00
Dale Weiler
35a8c3c9af More std::vector migration 2015-01-15 01:22:21 -05:00
Dale Weiler
2e3b3569bf Stop using vec_* in testsuite code 2015-01-15 00:29:37 -05:00
Dale Weiler
878195bdec Use C++ naming for structures 2015-01-15 00:05:48 -05:00
Dale Weiler
aabefd1bfe Use C++ naming for structures 2015-01-14 23:56:52 -05:00
Dale Weiler
4de08db0e7 More std::vector migration 2015-01-14 23:45:00 -05:00
Dale Weiler
67a3c9b031 Initial movement to std::vector 2015-01-14 23:34:43 -05:00
Dale Weiler
d4deaa35ca Fast math is too fast for clang 2015-01-14 21:58:04 -05:00
Dale Weiler
51a7b8e6a7 Make travis update to newer compilers 2015-01-14 21:54:41 -05:00
Dale Weiler
65362d93aa .c -> .cpp 2015-01-14 21:48:47 -05:00
Dale Weiler
a7b45ea14d More cleanup 2015-01-13 21:46:52 -05:00
Dale Weiler
9d89a059aa More cleanup 2015-01-13 21:43:48 -05:00
Dale Weiler
dc510baf4f This is supposted in C99 2015-01-13 21:39:19 -05:00
Dale Weiler
b5ac2745d6 Remove license headers. The LICENSE file is sufficent 2015-01-13 21:38:40 -05:00
Dale Weiler
0a00807e57 More cleanup 2015-01-13 21:36:09 -05:00
Dale Weiler
ff526954b6 Minifi README 2015-01-13 21:30:23 -05:00
Dale Weiler
42b3640bc5 Remove these too 2015-01-13 21:29:09 -05:00
Dale Weiler
6caaedd269 Remove msvc project files and misc stuff 2015-01-13 21:28:26 -05:00
Dale Weiler
8b250457ab Remove hash.c 2015-01-13 21:27:36 -05:00
Dale Weiler
644a807731 Remove all the support stuff 2015-01-13 21:26:44 -05:00
Dale Weiler
724bca0eec Remove fs.c ansi.c and PORTING guide 2015-01-13 21:25:17 -05:00
Dale Weiler
2c421c3b71 Major cleanup of platform/fs stuff 2015-01-13 21:18:47 -05:00
Dale Weiler
5b9e0a62ab Add qcvm rule to makefile 2015-01-13 20:36:25 -05:00
Dale Weiler
d6bf906647 Update travis file 2015-01-13 20:30:28 -05:00
Dale Weiler
1ad849d939 Include dependencies in the makefile 2015-01-13 20:29:46 -05:00
Dale Weiler
044f8b396d Linker flags after objects 2015-01-13 20:27:45 -05:00
Dale Weiler
893f204b30 Remove stat_info calls 2015-01-13 20:25:44 -05:00
Dale Weiler
486b215706 Remove memory tracker 2015-01-13 20:25:01 -05:00
Dale Weiler
d8c09c200a Simpler hash function 2015-01-13 20:10:44 -05:00
Dale Weiler
e452c176b4 Remove MSVC support code. Simplified makefile 2015-01-13 20:07:17 -05:00
Dale Weiler
833f315a16 Remove gmpak 2015-01-13 19:55:49 -05:00
Dale Weiler
a77797d6a6 Remove spelling corrector 2015-01-13 19:48:57 -05:00
Dale Weiler
783b7b6594 Update license headers 2015-01-09 14:53:35 -05:00
Dale Weiler
114a1d3b14 Fix variable declarations in for-loop initializers 2015-01-08 23:42:46 -05:00
Dale Weiler
6fee3ec363 More comments 2015-01-06 20:39:20 -05:00
Dale Weiler
2b10d588e4 grammar 2015-01-06 20:33:31 -05:00
Dale Weiler
e3577912c8 Fix the soft float implementation. Comment it as well. 2015-01-06 20:30:17 -05:00
Dale Weiler
ac8c7d730a Merge branch 'cooking'
Conflicts:
	test.c
2014-12-10 02:43:42 -05:00
Dale Weiler
5d5b9a379a When storing to a vector member as part of an entity field we must use STOREP 2014-12-10 02:40:35 -05:00
Dale Weiler
8f7242d314 Implement support for #include MACRO and #include __LINE__ 2014-11-07 03:12:34 -05:00
Dale Weiler
103e549615 Don't emit whitespace when stringifying TOKEN_WHITE.
Other aspects of the preprocessor already skip whitespace leading up to a token. The only situation in which a TOKEN_WHITE can
exist as part of the token stream during stringification, is when the whitespace is trailing after a token. This is situation is
really only possible in the context of a macro argument. This behaviour is inconsistent.

Consider the following
FOO( space_before)
FOO(space_after )

The former will reduce to "space_before" since the preprocessor will skip whitespace leading up to the token `space_before', while
the latter will reduce to "space_after ".

The C preprocessor doesn't preserve whitespace, so we won't either. This doesn't break any existing code.
2014-11-07 02:01:17 -05:00
Dale Weiler
ab841b94f7 Allow negation to propagate inexactness in constant folder by using neg(x) = x*-1 2014-11-04 14:32:56 -05:00
Wolfgang Bumiller
624e6201e8 manpage/init: -fsplit-vector-parameters description 2014-10-18 14:39:14 +02:00
Wolfgang Bumiller
8b25e95553 we like to spell things properly - if this commit message contains a typo I don't catch before pushing then that's totally intentional 2014-10-18 14:27:16 +02:00
Wolfgang Bumiller
ddb0b7dd9d ir_builder_imm_float: add IR_FLAG_ERASEABLE 2014-10-18 14:25:28 +02:00
Wolfgang Bumiller
806850e408 ir_builder_imm_float: mark them as const, otherwise they end up getting saved 2014-10-18 13:53:15 +02:00
Wolfgang Bumiller
09109bb176 split-vectors test 2014-10-18 13:51:25 +02:00
Wolfgang Bumiller
3df51c5979 adding -fsplit-vector-parameters, todo: float-lookup should get optimized as commented 2014-10-18 13:49:13 +02:00
Wolfgang Bumiller
2a00b386ba renaming the length operator to _length and fixing the lexing of that operator, generic names for operators is really a bad idea 2014-10-18 13:47:23 +02:00
Dale Weiler
15b31e7dc5 Support text type escape sequences \b and \s. 2014-10-17 19:37:01 -04:00
Dale Weiler
fa7d44e0c7 Converting a literal to null pointer produces a warning 2014-10-16 22:55:16 -04:00
Dale Weiler
859e9fe3da Fix tests 2014-09-29 03:38:08 -04:00
Dale Weiler
de22dec56b Some fixes 2014-09-28 20:28:56 -04:00
Dale Weiler
641136fee3 Make it a function 2014-09-27 04:50:50 -04:00
Dale Weiler
b08195e2da Implemented length operator. This closes #130 2014-09-27 04:15:32 -04:00
Dale Weiler
31cd263e33 Implement ini [includes] area like Trac. This closes #65 2014-09-27 02:32:02 -04:00
Dale Weiler
a502a5453f Make that unsigned 2014-09-27 01:52:33 -04:00
Dale Weiler
2208136403 Implement support for indirect macro expansions in the preprocessor. This closes #36 2014-09-27 01:48:03 -04:00
Dale Weiler
faacfa018a silly clang warning is silly 2014-09-26 19:58:32 -04:00
Dale Weiler
1a8bb31d2a Fix hash strlen properly instead of blindly disabling it 2014-09-26 19:53:50 -04:00
Wolfgang Bumiller
459356a48d accidentally left those in 2014-09-26 15:32:14 +02:00
Wolfgang Bumiller
beaba494b5 For now I'll just disable this 2014-09-26 15:25:33 +02:00
Wolfgang Bumiller
3e576bd1f3 hopefully sanitize field creation logic a bit 2014-09-26 15:08:49 +02:00
Dale Weiler
25caf4b8e8 Fix 2014-08-11 20:59:34 -04:00
Dale Weiler
d5690074e1 Set name for is_varargs too. 2014-07-31 13:13:43 -04:00
Dale Weiler
823b053e60 Fix T...name 2014-07-31 12:37:26 -04:00
Dale Weiler
4c1c1bc051 Remove debug info from parse error. 2014-07-31 00:44:42 -04:00
Dale Weiler
bca1a7143d Merge branch 'cooking' of github.com:graphitemaster/gmqcc into cooking 2014-07-31 00:43:42 -04:00
Dale Weiler
161bbec262 Parameter omitting in fteqcc is disallowed. 2014-07-31 00:43:08 -04:00
Wolfgang Bumiller
3e43056f5f fixing wrong paths in the uninstall target 2014-06-15 11:05:16 +02:00
Dale Weiler
c33755b007 Handle encoding errors for platform_vasprintf 2014-05-28 21:51:29 -04:00
Dale Weiler
e7d81937ae Make it compile as C++ code. 2014-05-26 21:36:13 -04:00
Dale Weiler
53e9ed0d96 Merge branch 'arithmetic_exceptions' into cooking
Conflicts:
	doc/gmqcc.1
	gmqcc.ini.example
	opts.def
	parser.c
2014-05-25 03:01:47 -04:00
Dale Weiler
05b349c72f Merge branch 'cooking' of github.com:graphitemaster/gmqcc into cooking 2014-05-25 02:56:40 -04:00
Dale Weiler
463426ad47 Some fixes 2014-05-25 02:27:02 -04:00
Dale Weiler
655c2482c9 Fix vec3_cross. Added optimization to Makefile since we've been compiling gmqcc without it since forever. 2014-05-25 02:04:10 -04:00
Dale Weiler
0c85bac71b More work on vector arithmetic exceptions. 2014-05-25 02:00:41 -04:00
Dale Weiler
aed893b6b8 More work for arithmetic exception on vectors. 2014-05-24 23:21:20 -04:00
Dale Weiler
337d7ddbf4 soft float state defaults. 2014-05-24 22:40:14 -04:00
Dale Weiler
ff80bf1aa2 Only when arithmetic exceptions are enabled. 2014-05-24 22:13:47 -04:00
Dale Weiler
1497191e3c Perliminary work in arithmetic exception handling for vector operations in constant evaluator / folder. 2014-05-24 22:12:05 -04:00
Dale Weiler
3945f26d92 Put this back in global scope, we have a local scope test 2014-05-24 20:36:09 -04:00
Dale Weiler
4fa694fe82 Some CLZ for other toolchains. 2014-05-24 20:33:57 -04:00
Wolfgang Bumiller
edb38ce70e local compile-time const values are now created as globals, thus they're now subject to constant-folding 2014-05-24 19:13:49 +02:00
Wolfgang Bumiller
536138273f propagate the 'inexact' flag on when initializing a constant 2014-05-24 17:53:29 +02:00
Dale Weiler
68c2baa7c1 Mage inexact travel across constants. 2014-05-24 11:50:16 -04:00
Dale Weiler
05e20bcdda Some things. Fix testsuite as well. One test will fail (inexact). 2014-05-24 11:42:10 -04:00
Wolfgang Bumiller
f1ab19ba0b this should be NULL 2014-05-24 17:15:25 +02:00
Wolfgang Bumiller
b7b60e7468 Merge branch 'master' into cooking 2014-05-24 17:13:05 +02:00
Dale Weiler
bbeb2517c0 Arithmetic exception flag and a plethora of tests. 2014-05-24 10:38:02 -04:00
Dale Weiler
2917d39ef1 Don't forget the BSDmakefile too. 2014-05-24 10:04:14 -04:00
Dale Weiler
cc20d7e4e9 Disable stupid clang warning. 2014-05-24 10:02:58 -04:00
Dale Weiler
5dc7e62b19 Use flags instead. 2014-05-24 09:59:43 -04:00
Dale Weiler
6424ebaf98 Perliminary work on arithmetic exception handling in the constant evaluator. We can safely check for arithmetic underflow, overflow, divison by zero and inexactness now. Inexactness of expressions are propagated through the AST such that using an inexact value in a comparison will trigger a warning with -Winexact-compares. 2014-05-24 09:53:38 -04:00
Dale Weiler
7024ebfe7f Merge branch 'master' into cooking 2014-05-13 23:22:25 -04:00
Dale Weiler
a371c4ee27 On platforms that the byte order check fails on the runtime test is concluded instead. It still needs these swap functions at compile time since the runtime test has to run. This fixes a FTBFS on BE selected ARMs. 2014-05-09 02:39:25 -04:00
Wolfgang Bumiller
ba0ac97372 add tests for INSTR_STATE and -femulate-state 2014-04-08 14:35:11 +02:00
Wolfgang Bumiller
8dafdfc5e2 use INSTR_STATE by default, add -femulate-state to switch to emulation, and -state-fps=NUM to set its emulation FPS 2014-04-08 14:34:55 +02:00
Wolfgang Bumiller
0d8b0d419c implement INSTR_STATE in the qcvm 2014-04-08 14:34:26 +02:00
Dale Weiler
0d1a740bc7 Fix style 2014-04-08 05:06:16 -04:00
Dale Weiler
0db41f4279 Only increment the buffer location for macro output whitespace stripping if the situation is actually stripable, otherwise macros like #define foo(X) bar(#X), with foo(test) will expand to bartest) instead of bar(test). This should fix Xonotic builds. 2014-04-08 04:02:23 -04:00
Dale Weiler
15d1277158 Added memory protection to prevent mismatching of mem_d or vec_free on pointers which are otherwise unknown to be allocated memory or allocated vectors. Also fixed the preprocessor to only strip on ' ' and '\t' around macros. 2014-04-08 03:26:08 -04:00
Wolfgang Bumiller
2b7b2ea455 fix a silly macro issue 2014-04-07 14:28:11 +02:00
Wolfgang Bumiller
e8133893a0 Merge remote-tracking branch 'origin/master' into cooking 2014-04-07 14:23:35 +02:00
Dale Weiler
f1650c42d9 Match C's preprocessor semantics for token pasting with '##'. 2014-04-07 06:00:04 -04:00
Dale Weiler
606d7ac110 Eliminate debug log 2014-04-05 05:16:36 -04:00
Dale Weiler
90533079c8 Rework distro package build system. 2014-04-05 05:16:15 -04:00
Dale Weiler
fe14d1b056 Order 2014-04-05 02:53:03 -04:00
Dale Weiler
8250124c51 Consistency 2014-04-05 02:52:01 -04:00
Dale Weiler
8c0a280a3e Fixed Windows builds. Now we also build Win64 packages. 2014-04-05 02:50:07 -04:00
Dale Weiler
9e5d02dab0 Less parens 2014-03-17 10:24:48 -04:00
Dale Weiler
827826b9f9 Remove the qcint cast. 2014-03-17 10:23:13 -04:00
Dale Weiler
763e85b3ae Use powf instead of pow. 2014-03-17 09:43:17 -04:00
Dale Weiler
b21e967581 Fix left/right shift constant fold. 2014-03-17 09:41:53 -04:00
Dale Weiler
06e2cb2b1b Add qc_pow. 2014-03-17 09:39:59 -04:00
Wolfgang Bumiller
581c48e337 Merge pull request #142 from CurrentResident/big_endian_testsuite
Big endian testsuite
2014-02-23 12:31:01 +01:00
Jim Thoenen
56edc3db9c White space tweak 2014-02-22 22:21:29 -06:00
Jim Thoenen
52adc2113f Tweak for coding convention 2014-02-22 21:22:41 -06:00
Jim Thoenen
69b89dc6ac Allow testsuite to pass on big endian
Move the progs header and body byteswapping into util functions and
call those functions when either reading or writing the progs.
2014-02-10 20:31:54 -06:00
Wolfgang Bumiller
f7e074d88f Merge branch 'master' into cooking 2014-02-08 10:33:50 +01:00
Dale Weiler
7ffda37513 s/atanhf/atanh/ 2014-02-08 02:50:06 -05:00
Wolfgang Bumiller
24763aad65 moving the length multiplication for 64 bit types from util_endianswap into util_swap64; renaming length parameter to count 2014-02-02 11:04:18 +01:00
Dale Weiler
360389638b Merge pull request #141 from CurrentResident/big_endian_swap_fix
Big endian swap fix
2014-02-02 02:00:15 -08:00
Jim Thoenen
2ddb5ad50d Update per IRC peer review feedback
Restore the swap function's original name, remove convenience function,
use %u in log message, whitespace tweak.
2014-02-02 02:32:50 -06:00
Jim Thoenen
3070c03fc0 Oops, scale int64 count into int32 count for swapper. 2014-02-02 01:52:50 -06:00
Jim Thoenen
1bf9ebabcc Big-endian: Byteswap only the field contents when writing progs.dat
The previous code swapped not just the fields' contents themselves, but
also field positions within several of the structs, resulting in a
non-working progs.dat when compiled on big endian (ppc in my case).
Swapping on a field-by-field basis now.

Also:
* Addresses weird swap size requests (30+ bytes in one case)

* Take a guess at the right way to log a weird swap request before dying

* Fix swap array length scaling

* Rename the main swap function to reflect its native->little-endian
  purpose.  Figued that was okay because progs.dat is required to be
  always little-endian...

* Add a non-array version of the swap function for convenience
2014-02-02 00:57:02 -06:00
Wolfgang Bumiller
9cc4fe1ed2 Merge branch 'master' into cooking 2014-01-26 12:38:00 +01:00
Wolfgang Bumiller
fee2986907 Merge pull request #140 from Sicness/gmqcc.1-hyphen
Fix hyphen-used-as-minus-sign in gmqcc.1
2014-01-26 03:37:33 -08:00
Anton Balashov
669a055594 Fix hyphen-used-as-minus-sign in gmqcc.1
I: gmqcc: hyphen-used-as-minus-sign usr/share/man/man1/gmqcc.1.gz:338
N:
N:    This manual page seems to contain a hyphen where a minus sign was
N:    intended. By default, "-" chars are interpreted as hyphens (U+2010) by
N:    groff, not as minus signs (U+002D). Since options to programs use
minus
N:    signs (U+002D), this means for example in UTF-8 locales that you
cannot
N:    cut and paste options, nor search for them easily. The Debian
groff
N:    package currently forces "-" to be interpreted as a minus sign due
to
N:    the number of manual pages with this problem, but this is a
N:    Debian-specific modification and hopefully eventually can be
removed.
N:
N:    "-" must be escaped ("\-") to be interpreted as minus. If you
really
N:    intend a hyphen (normally you don't), write it as "\(hy" to
emphasise
N:    that fact. See groff(7) and especially groff_char(7) for details,
and
N:    also the thread starting with
N:
http://lists.debian.org/debian-devel/2003/debian-devel-200303/msg01481.html
N:
N:    If you use some tool that converts your documentation to groff
format,
N:    this tag may indicate a bug in the tool. Some tools convert dashes
of
N:    any kind to hyphens. The safe way of converting dashes is to
convert
N:    them to "\-".
N:
N:    Because this error can occur very often, Lintian shows only the
first 10
N:    occurrences for each man page and give the number of suppressed
N:    occurrences. If you want to see all warnings, run Lintian with the
N:    -d/--debug option.
N:
N:    Refer to /usr/share/doc/groff-base/README.Debian and the
groff_char(7)
N:    manual page for details.
N:
N:    Severity: wishlist, Certainty: possible")"
2014-01-26 12:14:18 +04:00
Dale Weiler
24f9313952 Screw clang 2014-01-07 13:13:25 -05:00
Dale Weiler
a140b749ff Fix lshift/rshift for runtime and const-fold consistency. 2014-01-07 12:58:53 -05:00
Wolfgang Bumiller
0f506e768b sometimes I hate travis 2014-01-07 15:04:29 +01:00
Wolfgang Bumiller
792c1afd95 Do not create coverage calls on array accessors. 2014-01-07 15:01:52 +01:00
Wolfgang Bumiller
4ff68e07e8 Adding coverage support:
The -coverage option causes all values have AST_FLAG_BLOCK_COVERAGE
set by default.
The coverage attribute can be used to control coverage:
It takes an optional list of coverage types, currently only "block"
and "none" is recognized.
[[coverage]] defaults to [[coverage(block)]].
Use [[coverage(none)]] or [[coverage()]] to disable.
2014-01-07 14:36:00 +01:00
Dale Weiler
5a160b0e88 Happy new year redux! 2014-01-01 06:25:00 -05:00
Dale Weiler
a934e0fe4b Happy new year! 2014-01-01 06:24:16 -05:00
Wolfgang Bumiller
b6b4a87cbf That's not how it should fail :P 2014-01-01 12:21:00 +01:00
Wolfgang Bumiller
acdc559d1f improved test of last attribute 2014-01-01 12:18:54 +01:00
Wolfgang Bumiller
5319caaaea definite -> last keyword; testcase updated too 2014-01-01 12:16:19 +01:00
Dale Weiler
0b6637cc67 Cleanup some code duplication. This whole parser ugh I just want to rm -rf all of it. Time for GMQCC2. 2014-01-01 05:32:24 -05:00
Dale Weiler
1e30c2b81d Remove final attribute and bareword. [[definite]] is now old [[final]]. There is no bareword definite either. 2014-01-01 05:12:21 -05:00
Dale Weiler
26ab792f9c More cleanup 2013-12-15 01:45:36 -05:00
Dale Weiler
7e88247ed5 hash cleanups. 2013-12-15 01:37:24 -05:00
Dale Weiler
f24bdced10 Remove SSE hash, t's just too much effort to maintain. 2013-12-14 17:30:51 -05:00
Dale Weiler
31e13e6e64 Fix some stuff 2013-12-14 15:07:04 -05:00
Dale Weiler
103bca7284 Partially fix that. 2013-12-14 14:57:10 -05:00
Dale Weiler
d43a270142 typo 2013-12-14 06:02:39 -05:00
Dale Weiler
4c5a0ff662 Do not include this function unless !defined(__SSE__) 2013-12-14 01:34:33 -05:00
Dale Weiler
4d4851e179 Faster hashing reaching 16 GB/s on Phenom II X4. 2013-12-14 01:23:39 -05:00
Dale Weiler
58cd326d85 Only optimize (a - (-b)) into (a + b) when the unary operand is a negation. This fixes (a - (!b)) being turned into (a + b). 2013-12-08 19:01:44 -05:00
Wolfgang Bumiller
50f905b821 adding 'final' 2013-12-06 22:41:15 +01:00
Dale Weiler
072bff44e6 Bitshifting operators <<, >>, and compound assignment versions now work in non-constant expressions 2013-12-03 17:40:15 -05:00
Dale Weiler
af53c0cb83 Mask out the math constant precedence stuff unless -fftepp-mathdefs 2013-12-01 10:52:42 -05:00
Dale Weiler
6a44b72db3 Mask ftepp math constants with a compiler flag 2013-12-01 10:45:43 -05:00
Dale Weiler
b20e2a9d34 User supplied math constants take precedence 2013-12-01 10:30:24 -05:00
Dale Weiler
11ecc6cb0b Ignore emitting implicit math constants in the preprocessor if they exist. 2013-12-01 10:26:36 -05:00
Dale Weiler
2024b3bd71 Merge branch 'master' into cooking 2013-11-30 13:14:04 -05:00
Dale Weiler
78b615fce5 Merge pull request #139 from ignatenkobrain/update_fedora
fedora: Update .spec and INSTALL
2013-11-30 10:13:26 -08:00
Dale Weiler
892746056e Merge pull request #138 from ignatenkobrain/fix_authors
s/brian/brain/ ;)
2013-11-30 10:13:19 -08:00
Dale Weiler
d14c757076 Merge pull request #137 from ignatenkobrain/fix_build_big_endian
fix build on big endian arches
2013-11-30 10:13:12 -08:00
Igor Gnatenko
320784b20d fedora: Update .spec and INSTALL
Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
2013-11-30 12:35:07 +04:00
Igor Gnatenko
7b7d012255 s/brian/brain/ ;)
Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
2013-11-30 12:31:21 +04:00
Igor Gnatenko
a20127b063 fix build on big endian arches
Signed-off-by: Dan Horák <dan@danny.cz>
Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
2013-11-30 12:28:59 +04:00
Dale Weiler
9b92cb0897 Simplify 2013-11-29 13:50:06 -05:00
Dale Weiler
43e9885a08 Fix fold_op_cmp 2013-11-29 13:48:03 -05:00
Dale Weiler
ac7e1a557d Fixes 2013-11-29 13:36:35 -05:00
Dale Weiler
ea801acdb8 oops 2013-11-29 13:18:50 -05:00
Dale Weiler
4583cb8280 cleanup 2013-11-29 13:13:39 -05:00
Dale Weiler
cb97b7f672 Cleanup lexer old cruft 2013-11-29 07:15:49 -05:00
Dale Weiler
1d347eaf66 Handle byte order mark for unicode. (0xEFBBBF) 2013-11-29 07:03:55 -05:00
Wolfgang Bumiller
c3cc6f184e static variables now don't get re-initialized in functions; cannot be initialized with non-constants anymore; and a counter has been added so you can use the same name in a different scope for another static variable again. 2013-11-28 12:04:01 +01:00
Dale Weiler
bf127088ca Make log use the slightly improved algorithm for small values. 2013-11-25 14:08:05 -05:00
Dale Weiler
9749ec350a Reorder intrinsics table 2013-11-25 13:44:00 -05:00
Dale Weiler
e5fc8fdded out isn't used 2013-11-25 13:42:17 -05:00
Dale Weiler
2d0f0a3607 Never mind 2013-11-25 13:32:02 -05:00
Dale Weiler
25e86c04eb Only g++ is this retarded 2013-11-25 13:30:45 -05:00
Dale Weiler
f19d32b29b Another one 2013-11-25 13:26:24 -05:00
Dale Weiler
dc48af195d Pregenerate 2.0 for const folder since it's used often 2013-11-25 13:25:29 -05:00
Dale Weiler
33c0c83d59 Implemented __builtin_ln, __builtin_log, __builtin_log10, __builtin_log2 and __builtin_logb. This algorithm is nuts. 2013-11-25 13:21:27 -05:00
Dale Weiler
02c6076bfd Fix 2013-11-25 11:29:36 -05:00
Dale Weiler
3209aaa996 Implement __builtin_nan, __builtin_inf and __builtin_epsilon to generate machine nan, inf and epsilon values (at runtime). 2013-11-25 11:26:16 -05:00
Dale Weiler
8a26ed7664 Fix CRC16 2013-11-25 02:11:45 -05:00
Dale Weiler
50d1bfe783 Fix 2013-11-23 21:17:35 -05:00
Dale Weiler
63c0917d24 More compiler intrinsics for math functions 2013-11-23 21:14:13 -05:00
Dale Weiler
87a43777ab strength reduct (a - (-b)) into (a + b) 2013-11-23 13:13:21 -05:00
Dale Weiler
23904bad52 Better exp algorithm from divVerent 2013-11-23 12:45:22 -05:00
Dale Weiler
52cda620b2 Fix comments 2013-11-23 11:15:28 -05:00
Dale Weiler
1c33bcfceb Fixed pow 2013-11-23 11:14:42 -05:00
Dale Weiler
db182819ae Guard against nullfunc 2013-11-23 10:58:03 -05:00
Dale Weiler
ab2a4f1318 Some math constants 2013-11-23 10:31:51 -05:00
Dale Weiler
80adfebd23 Implement isinf intrinsic 2013-11-23 10:16:48 -05:00
Dale Weiler
aee68d80ea Cull back on the TODO 2013-11-23 08:02:56 -05:00
Dale Weiler
457a1b9690 Undefine macros after using them 2013-11-23 07:47:16 -05:00
Dale Weiler
943cb2ca64 Mark restrict on input too 2013-11-23 07:45:45 -05:00
Dale Weiler
556a84a46f Mark const for better generated code 2013-11-23 07:44:34 -05:00
Dale Weiler
b52cf4d47e Add comment abotu CRC16 2013-11-23 07:42:38 -05:00
Dale Weiler
e2bfaf8109 Implemented exp2 intrinsic 2013-11-23 07:37:26 -05:00
Dale Weiler
c68a5c29e1 Simplify 2013-11-23 07:27:09 -05:00
Dale Weiler
11f79bb1a6 Use '#' in nullfun identifier to prevent it from being used in code 2013-11-23 07:25:24 -05:00
Dale Weiler
54f331a64a Fix intrinsics for self-inclusion of other intrinsics. 2013-11-23 07:21:12 -05:00
Dale Weiler
74b58c5bb8 Cleaner handling since intrin_func deals with alias 2013-11-23 07:02:45 -05:00
Dale Weiler
292c8150b4 Resolve undefined functions to compiler builtins if they exist. 2013-11-23 06:57:40 -05:00
Dale Weiler
b1fd85b711 Merge branch 'cooking' of github.com:graphitemaster/gmqcc into cooking 2013-11-23 06:41:24 -05:00
Dale Weiler
d9572e3e30 Fixed pow/exp using fast approximation until the fractional part is hit. Once fractional is reached a binary search is used to get close to the value. 2013-11-23 06:40:27 -05:00
Wolfgang Bumiller
0860b7a68b crc16 slice-by-8 table generator code included for reference 2013-11-23 11:58:20 +01:00
Wolfgang Bumiller
759fca6921 slice-by-8 crc16 2013-11-23 11:50:30 +01:00
Dale Weiler
3b6e7d0ce1 indent 2013-11-23 03:54:11 -05:00
Dale Weiler
ae9d3d42cf A better mod implementation 2013-11-23 03:53:07 -05:00
Dale Weiler
29f2cc302b Add reference tool 2013-11-23 03:10:09 -05:00
Dale Weiler
7011a2ef2c Faster CRC16 algorithm based on the Slicing-by-8 algorithm, by Michael E. Kounavis and Frank L. Berry from Intel Corp. 2013-11-23 01:00:32 -05:00
Wolfgang Bumiller
ec03b55d1a now it parses and has the desired precedence 2013-11-16 14:34:24 +01:00
Wolfgang Bumiller
9131644412 ** precedence was wrong 2013-11-16 14:26:46 +01:00
Wolfgang Bumiller
49bb172a09 folder: change ~ for floats too 2013-11-14 11:41:11 +01:00
Dale Weiler
73c4015046 Fix unary minus on vector 2013-11-13 08:57:14 -05:00
Dale Weiler
1900262df4 Use a branch instead of math on enum types 2013-11-13 04:57:18 -05:00
Wolfgang Bumiller
f43106017f bit more concise 2013-11-12 16:28:11 +01:00
Wolfgang Bumiller
eb4486a7ac working fold_op_cmp implementation 2013-11-12 16:15:02 +01:00
Wolfgang Bumiller
1d5229ee8c vec3_not: be consistent with compile-time behavior here 2013-11-12 16:05:54 +01:00
Wolfgang Bumiller
eee7d0aac1 vec3_pbool: or, not and 2013-11-12 15:56:04 +01:00
Wolfgang Bumiller
de12a24bc9 folder: fix -fperl-logic 2013-11-12 14:39:25 +01:00
Wolfgang Bumiller
6ea88c9a3f subtracting != adding 2013-11-12 14:31:11 +01:00
Wolfgang Bumiller
de14d514f3 fix 0-x being turned into x 2013-11-06 16:57:04 +01:00
Wolfgang Bumiller
99de3cf4f5 regular procedure... bumping PKGBUILDs, GMQCC_VERSION macros, adding back GMQCC_VERSION_TYPE_DEVEL 2013-10-31 22:17:53 +01:00
Wolfgang Bumiller
7f2b2061e6 0.3.5 commit 2013-10-31 22:13:42 +01:00
Dale Weiler
1d745fd1f9 Merge branch 'cooking' 2013-10-31 08:22:54 -04:00
Wolfgang Bumiller
7a29f65683 Nothing in there requires unistd.h 2013-10-28 11:37:08 +01:00
Wolfgang Bumiller
1ca36b7e49 Revert "oh my god, make it stop >.<"
This reverts commit a120209567.
2013-10-27 20:11:41 +01:00
Wolfgang Bumiller
a120209567 oh my god, make it stop >.< 2013-10-27 19:19:11 +01:00
Wolfgang Bumiller
b1016c7f48 fold_binary now used instead of ast_binary_new, which calls fold_superfluous 2013-10-25 13:40:31 +02:00
Dale Weiler
91c894d4da Disable it on master too since Xonotic compiles are failing. 2013-10-24 11:56:23 -04:00
Wolfgang Bumiller
065a870e7a build again 2013-10-23 14:04:20 +02:00
Wolfgang Bumiller
b87eb89853 This is not allowed 2013-10-23 14:01:56 +02:00
Dale Weiler
c90807dec6 Some correctly-sized type flags for the AST and IR, this culls back memory usage a little. 2013-10-19 23:39:37 -04:00
Dale Weiler
0695ad1659 Merge branch 'cooking' of github.com:graphitemaster/gmqcc into cooking 2013-10-19 02:53:46 -04:00
Dale Weiler
b5b9559d6f Make preprocessor predefs use their own context opposed to the lexer context. 2013-10-19 02:52:47 -04:00
Wolfgang Bumiller
3988aae73e type and argument parsing improved to handle the field/vararg ambiguity; tests added 2013-10-18 16:28:28 +02:00
Dale Weiler
0f6c44d671 We're doing it this way. 2013-10-18 05:37:26 -04:00
Wolfgang Bumiller
8d5e719026 replacing the current [[accumulate]] implementation: shorter and simpler, and also supports non-void return types 2013-10-18 11:26:41 +02:00
Dale Weiler
0cfc275f82 Fix 2013-10-17 20:35:56 -04:00
Dale Weiler
c210340081 Undo fix and actually use a macro in the accumulation test .. just incase. 2013-10-17 20:34:16 -04:00
Dale Weiler
c675ba8086 Does this fix it? 2013-10-17 20:25:02 -04:00
Dale Weiler
9f54610fbd Implement support for octal constants, this closes #97. 2013-10-17 05:17:30 -04:00
Dale Weiler
02a1d9f4a1 Fix 'declaration does not declare anything' regression i.e this closes #132. 2013-10-17 05:06:09 -04:00
Dale Weiler
97217b55d1 Ignore generating a return instruction in accumulated functions, eventually we'll have a way to merge these into one function but for now the RETURN is a waste. 2013-10-17 04:45:24 -04:00
Dale Weiler
dd33f4e498 Update deps 2013-10-17 04:27:34 -04:00
Dale Weiler
f8949e17c8 Cleaner traces 2013-10-17 04:23:53 -04:00
Dale Weiler
d6f020fd6a Fix memory dump console printing alignment and also trace expressions for allocations. 2013-10-17 04:21:25 -04:00
Dale Weiler
05ac126d6f Use "##" to ensure the names of the accumulated functions are striped by the IR. 2013-10-17 03:47:26 -04:00
Dale Weiler
cfea900afd Update changes 2013-10-17 03:44:33 -04:00
Dale Weiler
8a9c4edce8 Add a test for function accumulation attribute 2013-10-17 03:43:05 -04:00
Dale Weiler
4da820ef61 Enforce void type on accumulatable functions. 2013-10-17 03:39:14 -04:00
Dale Weiler
2c975bb344 Implemented [[accumulate]] attribute. This will hopefully be used by Xonotic to replace it's ACCUMULATE_FUNCTION stuff. 2013-10-17 03:21:30 -04:00
Dale Weiler
1b14c49815 Use .dat extension on generated binaries in testsuite to prevent them from being sourced as task template files. This will fix the async builds on travis.ci 2013-10-17 00:18:07 -04:00
Dale Weiler
8699053887 Fix handling on intrinsic folding, this closes #118. 2013-10-17 00:14:42 -04:00
Dale Weiler
003bb9dfb4 Prevent aliasing functions through forward declared prototypes. This closes #125 2013-10-16 23:37:39 -04:00
Dale Weiler
0f479f3e88 Another one 2013-10-16 21:47:12 -04:00
Dale Weiler
c63bebd7d8 float and double shouldn't be used here, this is what qcfloat_t is for. This fixes the memcmp bug in the folder. 2013-10-16 21:32:31 -04:00
Dale Weiler
b147602d78 Fix option string allocated/non allocated storage. 2013-10-16 20:14:49 -04:00
Dale Weiler
f53502c9ca Make it valid C++ code, such that it can compile as C++ code. 2013-10-16 19:54:21 -04:00
Dale Weiler
50d165e173 Some intrinsic code cleanup. The args check is handled anyways in the parser. We use a generated array alongside to prevent generating the intrinsic multiple times instead of using static storage. Other various cleanups as well. 2013-10-16 00:04:39 -04:00
Dale Weiler
eca82511c6 divVerent suggestion to use memcmp here 2013-10-14 22:40:36 -04:00
Dale Weiler
6d8d7ee923 Make divVerent happy about handling divison by zero/inf/nan and negitive versions. This code now assumes IEEE 754. 2013-10-14 22:31:37 -04:00
Dale Weiler
c8413a9a04 Clang is so anal 2013-10-14 21:03:24 -04:00
Dale Weiler
8e8b3608fb Cleanups 2013-10-14 20:58:36 -04:00
Dale Weiler
65a2b83abd Cleanup for builds 2013-10-14 02:17:45 -04:00
Wolfgang Bumiller
19331ee385 who let the cat out? 2013-10-11 15:53:59 +02:00
Dale Weiler
ef51b30387 Fix windows builds, add strip target for makefiles, update distro build makefiles to use it for release builds. 2013-10-11 09:51:08 -04:00
Dale Weiler
f008cc257d Some cleanups 2013-10-11 09:32:46 -04:00
Dale Weiler
ccb46d7e3b Update README 2013-10-11 08:14:37 -04:00
Wolfgang Bumiller
42a9784804 Merge branch 'cooking' of git://github.com/graphitemaster/gmqcc into cooking 2013-10-11 14:11:40 +02:00
Wolfgang Bumiller
82afdb1e2c Merge branch 'cooking' of git://github.com/graphitemaster/gmqcc into cooking 2013-10-11 14:10:57 +02:00
Wolfgang Bumiller
62ac7e9966 first part of parsing TOKEN_DOTS as part of a type when needed; allows declarations like: ...float x; 2013-10-11 14:10:47 +02:00
Dale Weiler
6da151eba1 Update dependencies 2013-10-11 08:10:32 -04:00
Dale Weiler
856949a5f9 I need to test this code on msvc now. 2013-10-11 08:08:36 -04:00
Dale Weiler
d8b3faa871 Fix that (newer clang will fail on it) 2013-10-11 08:06:10 -04:00
Dale Weiler
92c0d6157c Merge branch 'cleanup' into cooking 2013-10-11 08:04:02 -04:00
Dale Weiler
fa14550d38 Last piece of documentation for platform.h 2013-10-11 08:02:28 -04:00
Dale Weiler
604c9d25bf More documentation for platform.h 2013-10-11 07:40:31 -04:00
Dale Weiler
4d0bf1607a Some documentation 2013-10-11 07:16:48 -04:00
Dale Weiler
63fdab8422 Some more cleanup 2013-10-11 06:36:05 -04:00
Dale Weiler
87d9371a5c Refactor some util/platform usage and extend file system file interface to accept its own flags and EOF 2013-10-11 06:12:56 -04:00
Wolfgang Bumiller
3d5fedcf39 distro/archlinux/this/Makefile: TARCOMP variable contains the compression flag, rather than using -J in the makerule but provide the .xz extension in a variable 2013-10-11 11:17:03 +02:00
Wolfgang Bumiller
637651f4e1 distro/archlinux/this/Makefile: tar -> bsdtar 2013-10-11 11:14:46 +02:00
Dale Weiler
e9bde1e4e4 Add back the correct directory handling for msvc 2013-10-11 05:09:55 -04:00
Dale Weiler
34c18ab860 Make it compile with mingw32 again 2013-10-11 04:58:49 -04:00
Dale Weiler
dab528acda Add a porting guide 2013-10-11 04:55:26 -04:00
Dale Weiler
e8955f17ea More cleanups, gmqcc.h doesn't need to include stdio.h now! 2013-10-11 04:06:52 -04:00
Dale Weiler
033cf7c7d3 More cleanups 2013-10-11 03:59:25 -04:00
Dale Weiler
5138a25420 More cleanup 2013-10-11 03:21:44 -04:00
Dale Weiler
12a864abf5 Some more platform / compiler specific code refactoring. 2013-10-11 03:02:38 -04:00
Dale Weiler
151606e255 Initial platform / compiler specific code refactoring. 2013-10-11 02:39:30 -04:00
Dale Weiler
14ef6a1c42 This can actually be much smaller, 204 bytes! 2013-10-11 00:22:27 -04:00
Dale Weiler
9dabb68d7f More typos 2013-10-10 22:12:03 -04:00
Dale Weiler
f73f2f1ba9 typo 2013-10-10 22:11:03 -04:00
Dale Weiler
e263506b3f Document what the utf8 table actually is 2013-10-10 22:10:36 -04:00
Dale Weiler
3e362e872c Wrong operand order it's 0xf4u-0xc2u i.e 0x32. 2013-10-10 22:03:13 -04:00
Dale Weiler
f83cc1b91d Less flexible more economical utf8 decoder. 2013-10-10 21:44:40 -04:00
Dale Weiler
6bd6379c87 Don't echo it 2013-10-05 23:39:05 -04:00
Dale Weiler
a02e44100e Fix some things: get all the Quake mods to compile again (I broke binary expressions .. oops) Fix the check-proj script, using $? for status was invalid because of pipes. The ir now properly considers negation virtual instruction to be operations (as it should). 2013-10-05 23:36:48 -04:00
Dale Weiler
99e3ae9773 Update CHANGES files 2013-10-05 22:34:55 -04:00
Dale Weiler
300fb9905b Fix fold_superfluous 2013-10-04 07:10:58 -04:00
Dale Weiler
ffdd6df828 Only when peephole optimization is on 2013-10-04 07:02:06 -04:00
Dale Weiler
2cf5046d38 Handle proper expression type assignment 2013-10-04 06:53:09 -04:00
Dale Weiler
cc69370575 Another peephole optimization which removes superfluous expressions such as (A + 0), (A - 0), (A * 1) and (A / 1). 2013-10-04 06:46:54 -04:00
Dale Weiler
263fcfbc2f Refactor intrinsic stuff 2013-10-02 13:00:34 -04:00
Dale Weiler
2ebf571129 Update documentation 2013-09-30 16:03:22 -04:00
Dale Weiler
90824c2093 Add seperate warning flag for directive in macro. 2013-09-30 15:59:36 -04:00
Dale Weiler
8f359f3849 Warn when preprocessor directive is found inside a macro body. 2013-09-30 15:57:01 -04:00
Dale Weiler
08891068c8 Merge branch 'cooking' of github.com:graphitemaster/gmqcc into cooking 2013-09-30 14:33:57 -04:00
Dale Weiler
b6f08e7fb1 Fix negation type for VINSTR_NEG_V. Source operand for optimization instead of the expression (to handle double negation elision properly.) 2013-09-30 14:32:21 -04:00
Wolfgang Bumiller
fa14ca93d2 Merge branch 'master' into cooking 2013-09-30 15:02:03 +02:00
Wolfgang Bumiller
dfbd093348 Merge pull request #134 from Sicness/hyphen
Fixed hyphen-used-as-minus-sign in gmqcc.1
2013-09-30 06:01:22 -07:00
Anton Balashov
e928cabfb2 Fixed hyphen-used-as-minus-sign in gmqcc.1
Accortding to lintian report:
I: gmqcc: hyphen-used-as-minus-sign usr/share/man/man1/gmqcc.1.gz:156
N:
N:    This manual page seems to contain a hyphen where a minus sign was
N:    intended. By default, "-" chars are interpreted as hyphens (U+2010) by
N:    groff, not as minus signs (U+002D). Since options to programs use minus
N:    signs (U+002D), this means for example in UTF-8 locales that you cannot
N:    cut and paste options, nor search for them easily. The Debian groff
N:    package currently forces "-" to be interpreted as a minus sign due to
N:    the number of manual pages with this problem, but this is a
N:    Debian-specific modification and hopefully eventually can be removed.
N:
N:    "-" must be escaped ("\-") to be interpreted as minus. If you really
N:    intend a hyphen (normally you don't), write it as "\(hy" to emphasise
N:    that fact. See groff(7) and especially groff_char(7) for details, and
N:    also the thread starting with
N:    http://lists.debian.org/debian-devel/2003/debian-devel-200303/msg01481.html
N:
N:    If you use some tool that converts your documentation to groff format,
N:    this tag may indicate a bug in the tool. Some tools convert dashes of
N:    any kind to hyphens. The safe way of converting dashes is to convert
N:    them to "\-".
N:
N:    Because this error can occur very often, Lintian shows only the first 10
N:    occurrences for each man page and give the number of suppressed
N:    occurrences. If you want to see all warnings, run Lintian with the
N:    -d/--debug option.
N:
N:    Refer to /usr/share/doc/groff-base/README.Debian and the groff_char(7)
N:    manual page for details.
N:
N:    Severity: wishlist, Certainty: possible
N:
N:    Check: manpages, Type: binary
N:
I: gmqcc: hyphen-used-as-minus-sign usr/share/man/man1/gmqcc.1.gz:354
I: gmqcc: hyphen-used-as-minus-sign usr/share/man/man1/gmqcc.1.gz:676
2013-09-30 16:43:57 +04:00
Dale Weiler
03b56bd41f Handle double negation case specially. Update TODO 2013-09-30 05:12:28 -04:00
Dale Weiler
7249c2ec18 Simplify parse stage for unary - operator. 2013-09-29 22:08:09 -04:00
Dale Weiler
353455e1ad Remove pointless thinking comment, fix builds for clang. 2013-09-29 22:06:26 -04:00
Dale Weiler
b10de1b240 Make unary - operator act as an ast_unary node. This allows for consistency (no sense in making unary use binstore nodes, it doesn't make much sense). It also allows for the peephole optimization on unary chains that cancel each other to take place; i.e code like "-(-a)" simplifies to "a", thus eliminating instructions. 2013-09-29 22:01:46 -04:00
Dale Weiler
3c931ecbf1 Eh, only if peephole optimizations are turned on. 2013-09-28 06:41:40 -04:00
Dale Weiler
c6056d441b Less casts. 2013-09-28 06:36:00 -04:00
Dale Weiler
7c25af973c It was much easier in the AST, really. 2013-09-28 06:33:15 -04:00
Dale Weiler
81df8fa139 Remove the rest of it. 2013-09-28 06:10:02 -04:00
Dale Weiler
8a294683bb Remove it, maybe it can be done in the AST instead. 2013-09-28 06:09:24 -04:00
Dale Weiler
c4e92df106 Eh. 2013-09-28 05:36:09 -04:00
Dale Weiler
2b3663e18d Optimize for superfluous cases of NOT, i.e !!!!x can be simplified to !!x. 2013-09-28 05:34:53 -04:00
Dale Weiler
0d1f20fea3 Move it over 2013-09-28 03:41:18 -04:00
Igor Gnatenko
95b7056427 Optimizng compile flags
Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
2013-09-28 03:37:58 -04:00
Igor Gnatenko
c8a1b6563e Update to 0.3.0 (improved new package: gmqpak)
Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
2013-09-28 03:37:58 -04:00
Igor Gnatenko
48211572e5 Initial release
Add spec and patch

Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
2013-09-28 03:37:58 -04:00
Dale Weiler
d61c5d3b16 Fix alias type check 2013-09-26 08:09:55 -04:00
Dale Weiler
15b0555546 Implement constant folding on ternary operations via fold_cond. 2013-09-26 06:51:49 -04:00
Dale Weiler
cf2352893f Consistency 2013-09-25 16:19:33 -04:00
Dale Weiler
894e1976e3 Cheap quick hack for ignoring #pragma to EOL 2013-09-25 15:35:18 -04:00
Wolfgang Bumiller
904c45060b remove -printf option from find; remove the misplaced 'local's 2013-09-25 11:16:15 +02:00
Wolfgang Bumiller
87fcf8d8e8 there's no pushd/popd in my sh 2013-09-25 11:14:59 +02:00
Dale Weiler
d2405a9ad8 Some grammar 2013-09-25 04:24:09 -04:00
Dale Weiler
d664b9f607 Fix some stuff for xonotic and make check-proj actually use the options line correctly. 2013-09-25 04:23:06 -04:00
Dale Weiler
13ef558fff Add export utility for Nexuiz, now check-proj handles it. 2013-09-25 04:03:37 -04:00
Dale Weiler
3968dc84fd Got Xonotic stuff for check-proj to function. 2013-09-25 03:52:48 -04:00
Dale Weiler
330111d5fc Fix the xonotic export script for check-proj.sh 2013-09-24 07:53:51 -04:00
Dale Weiler
fac4e411bf Merge branch 'cooking' of github.com:graphitemaster/gmqcc into cooking 2013-09-24 07:32:23 -04:00
Dale Weiler
73eca0848c Fix QuakeWorld compilation by treating assignment to constants as a warning when -std=qcc. 2013-09-24 07:31:53 -04:00
Dale Weiler
37a4265e06 Update .travis.yml 2013-09-22 08:43:47 -04:00
Dale Weiler
69efb404bf Update .travis.yml 2013-09-22 08:43:24 -04:00
Wolfgang Bumiller
99422d0cf4 this is still there twice... 2013-09-19 21:05:40 +02:00
Wolfgang Bumiller
8d2a6ca419 moving the QCVM_EXECUTOR ifdef in conout.c - these are used in the executor 2013-09-19 21:05:39 +02:00
Dale Weiler
f25fff1e3d Remove debug printfs 2013-09-18 19:18:10 -04:00
Dale Weiler
e18849fa42 Generate (non_const_float * (1.0 / constant_float)) for (non_const_float / constant_float) expressions. 2013-09-18 19:15:24 -04:00
Wolfgang Bumiller
5a47dd5e62 since we don't bail on some of the warnings right away, (that is, with -Werror), also check the compile_errors count in main rather than just the return values 2013-09-18 16:20:25 +02:00
Wolfgang Bumiller
b6da3613ac making irwarning warn on an unused result 2013-09-18 16:20:24 +02:00
Dale Weiler
241637a980 Don't need that, each directory already has its own progs.src 2013-09-12 17:18:47 -04:00
Dale Weiler
9726d80e05 Output the dat name for xonotic export tool (first line of prog.src) 2013-09-12 17:08:40 -04:00
Dale Weiler
94e477e466 Added -progsrc commandline switch to specify progs.src files of different names. Cleaned up xonotic export script, fixed check-doc on linux systems by disabling mandoc check. 2013-09-12 17:06:20 -04:00
Dale Weiler
5bb245a33a Added xonotic_export.sh utility that when run from a xonotic-data.pk3dir will eliminate redundant files and create prog.src files for csprogs, progs(server) and menu. This tool will be used for check-proj.sh for exporting xonotic changes to our server. 2013-09-12 15:06:36 -04:00
Dale Weiler
6a235dc25f Support options for check-proj now 2013-09-11 17:09:03 -04:00
Dale Weiler
207d391fcd Allow running from root of gmqcc repo as well. 2013-09-11 16:50:33 -04:00
Dale Weiler
f44c127fbd Proper gmqcc sourcing for check-proj 2013-09-11 16:48:01 -04:00
Dale Weiler
c52ad67a7c Test for gmqcc in check-proj 2013-09-11 16:38:18 -04:00
Wolfgang Bumiller
35f9aef729 fix: declaring locals with the name of a parameter now treats the parameter as the local's prototype to avoid it being double-freed later 2013-09-11 11:25:44 +02:00
Dale Weiler
46fa12cb26 Merge branch 'cooking' of github.com:graphitemaster/gmqcc into cooking 2013-09-10 19:16:14 -04:00
Dale Weiler
8ddd126378 Added check-proj misc tool that downloads various QuakeC projects and tries to compile them with gmqcc, sort of like an additional test. 2013-09-10 19:15:28 -04:00
Wolfgang Bumiller
ce07e8fe28 distro/archbsd/this - as we don't depend on glibc there, just libc; also changed DESTDIR in archlinux/this/Makefile so it can be easily changed from the bsd Makefile 2013-09-09 12:18:30 +02:00
Wolfgang Bumiller
7af8c70bf9 distro/archlinux/this: generate the .MTREE file 2013-09-09 12:08:57 +02:00
Wolfgang Bumiller
3f151321f6 qcvm: exit on error 2013-09-08 21:31:56 +02:00
Dale Weiler
c2cf41baf9 Merge branch 'master' into cooking 2013-09-08 13:05:20 -04:00
Dale Weiler
9908209f58 Fix dependincies 2013-09-08 13:04:07 -04:00
Dale Weiler
6800d15872 Always print the char the lexer fails on for a token. 2013-08-31 16:52:46 -04:00
Dale Weiler
b2c8f3ebc5 Vector cross product virtual instruction, now >< operator works for non-constant vectors. Thanks divVerent for the help. 2013-08-31 14:49:06 -04:00
Dale Weiler
64661f54ea Implemented >< (vector cross product operator). Currently support for constants only. 2013-08-31 13:41:25 -04:00
Dale Weiler
69252071ba Prevent divide by zero for / and % operations in constant folding (previously caused compiler SIGFPE), instead "inf" is generated for both cases. This closes #124 2013-08-31 12:57:24 -04:00
Dale Weiler
9032e78349 There is no bug since the testsuite uses -o for preprocessed output (thus the printf never gets involved) if the testsuite read the preprocessor output from stdout than things would be wrong, since however it isn't there is no bug. 2013-08-31 09:53:19 -04:00
Wolfgang Bumiller
702a7664de Don't allow a stale 'some_type;' declaration without an actual variable name; Same for typedef; closes #119 2013-08-31 11:35:12 +02:00
Wolfgang Bumiller
2ff9adecb2 this one can be reached - make it a little more helpful 2013-08-31 10:55:03 +02:00
Wolfgang Bumiller
4600f1d7ff more thorough check for whether an ast node starts a new label; closes #121 2013-08-31 10:48:24 +02:00
Wolfgang Bumiller
79219ae201 factor check for assignment-to-constant into a function; improve its error output; closes #122 2013-08-31 10:39:31 +02:00
Wolfgang Bumiller
87b9fca732 fix unhelpful error message; fixes #123 2013-08-31 10:19:10 +02:00
Dale Weiler
98cb23ca63 Logic elsewhere handles this (no need to duplicate) 2013-08-30 07:23:15 -04:00
Dale Weiler
a50635bcd7 intrinsic folding cleanups (and improvements.) 2013-08-30 07:12:16 -04:00
Dale Weiler
76c37d9cc0 Rid of util_debug 2013-08-30 06:49:24 -04:00
Dale Weiler
c8b4eac618 Make -fshort-logic -funtyped-nil -fvariadic-args default for -std=gmqcc 2013-08-29 07:56:22 -04:00
Dale Weiler
f8af7adcd7 Remove &~= operator from gmqccs operator table, only fteqcc supports it. 2013-08-29 07:19:19 -04:00
Dale Weiler
dd289ed0e1 Merge branch 'cooking' of github.com:graphitemaster/gmqcc into cooking 2013-08-29 07:08:03 -04:00
Dale Weiler
3ed200d08a Some changes changes 2013-08-29 07:07:43 -04:00
Wolfgang Bumiller
ff6d55aafc this should allow for better detection of precedence issues 2013-08-29 10:22:48 +02:00
Wolfgang Bumiller
fa468e0673 also warn about mixing logical and/or operations without parenthesis 2013-08-29 08:26:17 +02:00
Wolfgang Bumiller
f140c39063 warn when mixing different bitops without parenthesis around them 2013-08-29 08:18:06 +02:00
Dale Weiler
51ef277e21 Fix folding logic for conditions. 2013-08-29 00:18:48 -04:00
Dale Weiler
a7c1f6f021 Implement [[eraseable]] attribute. When used with a function it instructs the AST (which than transfers logic to the IR) that the function (or variable) is potentially unused (verified by checking the read count). This than propogates through the IR and prevents the IR from generating both the definition and global/function. The intrinsics system uses this as well to prevent intrinsic functions from being generated unless they're used. 2013-08-29 00:05:37 -04:00
Dale Weiler
ceb79f1897 Fix build on clang 2013-08-28 13:01:46 -04:00
Dale Weiler
3b4a5667ea Constant fold intrinsics if their arguments are constant. TODO: reference count intrinsics such that they're not generated unless they're used, currently when an intrinsic can be folded-away it's marked for generation and makes it to the final output binary even though it isn't used. 2013-08-28 12:46:22 -04:00
Dale Weiler
bbe4927a20 Implemented a __builtin_fabs intrinsic. 2013-08-28 11:28:27 -04:00
Dale Weiler
ee428b9081 Fix fold-dce for if(0) 2013-08-28 10:39:48 -04:00
Wolfgang Bumiller
40bcec5044 Add missing -width to .Bl in doc/gmqpak.1 2013-08-28 14:40:23 +02:00
Wolfgang Bumiller
a80aa89e09 Fix bad use of .D1 in doc/qcvm.1 2013-08-28 14:38:51 +02:00
Wolfgang Bumiller
660a22d647 misc/check-doc.sh: run mandoc -Tlint -Wall on the manpages 2013-08-28 14:33:09 +02:00
Wolfgang Bumiller
494c30a239 allow initializing shadowed locals outside of -std=gmqcc - in this case it becomes a regular assignment to the old declaration which is consistent with fteqcc 2013-08-28 14:20:33 +02:00
Dale Weiler
71e7db63aa Cleanups 2013-08-28 03:45:40 -04:00
Dale Weiler
8aaa268423 Handle return status from compiler, this fixes false positivies in the testsuite when the compiler segfaults and the testsuite still reports succeeded, now it won't hopefully. 2013-08-28 03:40:35 -04:00
Dale Weiler
a75746d610 Don't ignore empty newlines when match in the testsuite, instead only ignore when procedure type is -pp (i.e preprocessing). 2013-08-28 03:34:05 -04:00
Dale Weiler
045bd4dbda Some style fixes for tests 2013-08-27 06:41:03 -04:00
Dale Weiler
28cd3a3f8f Forgot this one 2013-08-27 06:39:51 -04:00
Dale Weiler
f21216ecad A test for that xor stuff (the same one I used to cause the bug to manifest in the first place). 2013-08-27 06:35:58 -04:00
Rudolf Polzer
abfe98ce8a Fix XOR maths for overlapping inputs by setting the lifetimes correctly.
Signed-off-by: Rudolf Polzer <divverent@xonotic.org>
2013-08-27 12:27:20 +02:00
Wolfgang Bumiller
988b4b4960 ast_binary->right_first and an execution order check 2013-08-27 10:42:13 +02:00
Dale Weiler
4937fa51c0 Merge divVerent/ftypeless-stores, but rid of the macro abuse. 2013-08-27 04:28:22 -04:00
Dale Weiler
1b3d515777 Merge branch 'cooking' of github.com:graphitemaster/gmqcc into cooking 2013-08-27 04:28:11 -04:00
Wolfgang Bumiller
b26f53125d error on uninitialized arrays of unspecified size; otherwise it errors about a size overflow 2013-08-27 10:19:05 +02:00
Wolfgang Bumiller
844e84fc16 bail out when encountering an invalid array size in the ast as it's likely to cause breakage when trying to generate them anyway 2013-08-27 10:09:31 +02:00
Dale Weiler
581d0dfc15 Merge branch 'divVerent/ftypeless-stores' of git://git.xonotic.org/xonotic/gmqcc into cooking 2013-08-27 04:07:17 -04:00
Wolfgang Bumiller
147a6df629 fix testcase workarounds 2013-08-27 10:00:24 +02:00
Dale Weiler
b3c1b46925 And there she goes, them space swallowing whores. 2013-08-27 03:57:09 -04:00
Rudolf Polzer
f4f805f4c9 New options: -ftypeless-stores and -fsort-operands
These flags reduce entropy, but not size, of the generated assembly
code. This helps compressability of the files.

Additionally, -ftypeless-stores might SLIGHTLY improve engine
performance due to less instructions being used (so branch prediction
might work better). Probably cannot be measured though.

Signed-off-by: Rudolf Polzer <divverent@xonotic.org>
2013-08-27 09:55:00 +02:00
Dale Weiler
fc57fa4064 Add support for columns to LNOF files. 2013-08-26 14:14:33 -04:00
Dale Weiler
0e077c6e42 Fix testsuite for when a process crashes (do not consider it a success) 2013-08-26 13:10:38 -04:00
Dale Weiler
a1f1ec6d65 Fix testsuite 2013-08-26 13:05:54 -04:00
Wolfgang Bumiller
ba94df47f0 reset the column counter on a newline 2013-08-26 18:53:09 +02:00
Dale Weiler
454234ef5f Merge branch 'divVerent/submit/vector-bitops' of git://git.xonotic.org/xonotic/gmqcc into cooking 2013-08-26 12:36:17 -04:00
Rudolf Polzer
e50b7a2719 Support vector bitor/bitand/bitxor.
Signed-off-by: Rudolf Polzer <divverent@xonotic.org>
2013-08-26 18:32:28 +02:00
Wolfgang Bumiller
5958687795 error when trying to pass a TYPE_NOEXPR value to ir_instr_op 2013-08-26 10:23:20 +02:00
Wolfgang Bumiller
69cecb74df ir_builder now has a vinstr_temp array, a bunch of temps (currently 1) which can be used for virtual instruction translation 2013-08-26 10:23:03 +02:00
Dale Weiler
95138b1e5b Some typos 2013-08-21 23:28:49 -04:00
Dale Weiler
efa571043b Make makes output consistent with BSD makes output for make 2013-08-21 09:49:26 -04:00
Wolfgang Bumiller
4990434db7 archlinux PKGBUILDs: don't use install's -D switch - now they should work for both ArchLinux and ArchBSD 2013-08-21 10:45:28 +02:00
Dale Weiler
bbab8969d1 Generate PDF documentation from man pages for windows releases. 2013-08-21 04:29:33 +00:00
Dale Weiler
834e8d0d7d Mark the beginning of the next release, master is now stable. 2013-08-19 23:31:57 +00:00
Dale Weiler
a7fdbbe35b Fix that 2013-08-19 23:18:03 +00:00
Dale Weiler
6a4e175f86 Slackware support to website generation. 2013-08-19 23:15:41 +00:00
Dale Weiler
a93a28230d Merge pull request #117 from matthiaskrgr/master_PKGBUILD
Master pkgbuild
2013-08-19 16:06:03 -07:00
Matthias Krüger
701363347f Merge remote-tracking branch 'upstream/master' into master_PKGBUILD 2013-08-20 00:06:01 +02:00
Matthias Krüger
a1a9438319 PKGBUILD: release: update 2013-08-20 00:04:55 +02:00
Matthias Krüger
491a706610 PKGBUILD: git: update 2013-08-19 23:50:10 +02:00
Dale Weiler
963e93e8e8 This should be the tag 2013-08-19 21:38:18 +00:00
Dale Weiler
c13285092c Mark release, ready to tag it and bag it. 2013-08-19 21:34:49 +00:00
Dale Weiler
ccd8f1acc6 Added style + indent rule, fixed some indenting as well 2013-08-19 02:16:16 +00:00
Dale Weiler
a31eacf1bd Newline rule 2013-08-19 00:59:41 +00:00
Dale Weiler
e15046d66c Please the Samual 2013-08-18 23:44:23 +00:00
Dale Weiler
78a3c5d571 Fix that rule 2013-08-17 23:50:21 +00:00
Dale Weiler
e6809acf63 Added whitespace fix rule to include.mk 2013-08-17 23:49:47 +00:00
Dale Weiler
c64005966f Remove some trailing whitespace 2013-08-17 23:43:41 +00:00
Dale Weiler
2a79339735 Remove that idiom, and use GMQCC_ARRAY_COUNT. 2013-08-17 23:39:06 +00:00
Dale Weiler
dd512ec36a Forgot about this one 2013-08-17 22:19:40 +00:00
Dale Weiler
e7dab06f82 They don't go there, fuck you grep. 2013-08-17 22:17:14 +00:00
Dale Weiler
94139513db Cleanups and update CHANGES 2013-08-17 22:16:40 +00:00
Dale Weiler
7108c61bec Fix the build 2013-08-16 09:09:56 +00:00
Dale Weiler
772dbfae26 Make it compile in visual studio again, without warnings. 2013-08-16 09:03:36 +00:00
Dale Weiler
b30c3ff8d4 Update documentation 2013-08-16 08:16:03 +00:00
Dale Weiler
d5d38e94ef Some testing for valgrind in the makefile 2013-08-16 07:33:57 +00:00
Dale Weiler
89893f9a24 Valgrind integration for our memory allocator. 2013-08-16 07:22:01 +00:00
Dale Weiler
079ed491a9 Update the ini example, holy hell we have more options than I imagined. 2013-08-16 04:22:53 +00:00
Dale Weiler
a622d5163b Rework some build stuff for better output and to enable strict prototypes 2013-08-16 03:28:02 +00:00
Dale Weiler
7df42c95d2 Make our allocator slightly faster with branch hinting. 2013-08-15 06:09:28 +00:00
Dale Weiler
91c7209146 Track constant folds in opts_optimization list .. this could be handled better I assume. 2013-08-15 03:45:50 +00:00
Dale Weiler
ade8626df7 Perform some strict aliasing all over this biatch. We ain't trippin on code that breaks it. 2013-08-14 10:16:04 +00:00
Wolfgang Bumiller
3ece4a964f remove the 'opts' global from test.c and exec.c as opts.c defines it and is linked into both the testsuite and qcvm 2013-08-14 12:09:26 +02:00
Dale Weiler
586a70ea1d Handle some more errors 2013-08-14 07:41:09 +00:00
Dale Weiler
bee14a6df7 Some bug fixes 2013-08-14 07:19:49 +00:00
Dale Weiler
0a5353532b Remove my MT impl for PRNG, it's full of buffer overflows that I don't want to fix. Just fallback to using srand/rand 2013-08-14 06:22:32 +00:00
Dale Weiler
1201f06a55 Remove vec_upload 2013-08-14 06:19:48 +00:00
Dale Weiler
f82097b6b8 Update deps 2013-08-14 06:12:43 +00:00
Dale Weiler
73d9aa29c4 Made intrinsics seperate from the parser. 2013-08-14 06:02:15 +00:00
Dale Weiler
85ee52128c Fix 2013-08-14 04:27:11 +00:00
Dale Weiler
a68f0fcb35 Cleanups 2013-08-14 04:24:06 +00:00
Dale Weiler
5e54db46c4 Some statistics as Samual wanted. 2013-08-14 04:08:00 +00:00
Dale Weiler
b654594adb Disable statistics that are irrelevant to QuakeC coders 2013-08-14 03:24:00 +00:00
Dale Weiler
b10a2d1fd5 Remove the attempt at ast_intrinsic node 2013-08-14 03:05:14 +00:00
Dale Weiler
216330a7e2 Some intrinsic cleanups 2013-08-14 03:03:49 +00:00
Dale Weiler
90e2e5a4ad Some typos 2013-08-14 02:07:12 +00:00
Dale Weiler
7669a99c7f increment the optimization counter for DCE'd folds, also enable -O3 for compilation. 2013-08-01 14:24:10 +00:00
Dale Weiler
69c4dce477 Testsuite now returns the correct value on test failures (also prints how many tests failed .. if any fail) 2013-08-01 07:20:02 +00:00
Dale Weiler
db69d14995 Disable the macros to keep clang happy (just uncomment them for when more constant folding optimizations need them) 2013-08-01 07:12:21 +00:00
Dale Weiler
6f749d61b1 Added -Oconst-fold-dce (dead code elimination optimization for when constant expressions form the basis of the dead code, i.e if else with constant expression). Fixed deps and added documentation. Cleaned up folds for ir_value (can now use the same macros as the ast_value ones). 2013-08-01 07:07:59 +00:00
Dale Weiler
24fc2e5146 Fix that typecast 2013-07-31 19:36:09 +00:00
Dale Weiler
10b75fd8b9 Move const-branch-elision into fold.c 2013-07-31 19:34:38 +00:00
Dale Weiler
3e24b5a74b Remove debugging aid and left over cruft. 2013-07-31 18:54:38 +00:00
Dale Weiler
960cb7034a The problem was so subtle 2013-07-31 18:53:00 +00:00
Dale Weiler
3fa74da2b5 Fixes 2013-07-31 17:24:32 +00:00
Dale Weiler
5f2b7e3d57 fixed vector ops constant folding. 2013-07-31 17:05:43 +00:00
Dale Weiler
d0ee56f25f more fixes 2013-07-31 16:31:45 +00:00
Dale Weiler
1538e69f93 Fixes 2013-07-31 15:56:56 +00:00
Dale Weiler
fa5ad1212e Operator constant folding rewrite almost complete, just need to track down why two tests are failing. 2013-07-31 15:49:45 +00:00
Dale Weiler
86adb94d7d folding for lteqgt (less than equal to or greater than) operator a.k.a <=> which maps values to -1,0,1 depending on the result (think of the result as a troolan) .. it's a perl thing :P 2013-07-31 12:59:34 +00:00
Dale Weiler
9ed62eee58 Feed clang demon 2013-07-31 12:17:52 +00:00
Dale Weiler
c3da9b237b && and || op folding 2013-07-31 12:11:03 +00:00
Dale Weiler
b0460de935 Fold for div op 2013-07-31 11:48:43 +00:00
Dale Weiler
8dd125c8f3 Added constant folding support for '*' .. Clever ascii trick prevail :D 2013-07-31 10:40:17 +00:00
Dale Weiler
5e38c800f6 Some cleanups and more support for constant folding. 2013-07-31 09:56:45 +00:00
Dale Weiler
920dbaf1e0 Work in progress constant-folding rewrite. 2013-07-31 09:04:19 +00:00
Dale Weiler
d8b931fbcf Experimental/Initial try at in-ast constant folding. (for TYPE_FLOAT currently .. since comparisions on UTF8 strings need to be worked out yet ..) 2013-07-30 18:06:42 +00:00
Dale Weiler
2c975fe48f I'm in a state of confusion as to why constant folding was never done on comparisions, now it is ;) 2013-07-30 17:27:54 +00:00
Dale Weiler
d6ca5673dc Use the _t consistency naming scheme. Also various cleanups. 2013-07-30 16:00:51 +00:00
Dale Weiler
a9ab865add Move some things around 2013-07-30 15:32:24 +00:00
Dale Weiler
c8c25ef6f7 Some cleanups and smaller binaries! 2013-07-28 00:23:15 +00:00
Dale Weiler
6c0c7aac0f cherry-pick diagnostics testsuite into cooking. We can now create compiler diagnostic tests, i.e if the compiler errors on syntax, we can match the error messages. 2013-07-28 00:02:48 +00:00
Dale Weiler
9e2b17e715 Merge pull request #116 from ignatenkobrain/cooking
Add instruction for Fedora and other RPM distros
2013-07-27 11:29:14 -07:00
Igor Gnatenko
ab79dbd22a add instruction
Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
2013-07-27 22:24:43 +04:00
Igor Gnatenko
23af0c0209 add updated spec and rename it
Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
2013-07-27 22:09:39 +04:00
Igor Gnatenko
bee93f28b3 not needed yet
Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
2013-07-27 22:08:43 +04:00
Dale Weiler
d684e99d86 Clear out for now. 2013-07-27 17:57:29 +00:00
Dale Weiler
557ad9da1a Make COMPILER_QCC default to please the stuborn Quake community. 2013-07-27 17:56:46 +00:00
Dale Weiler
ec0aaa72a3 Some typos 2013-07-27 16:39:17 +00:00
Dale Weiler
ce7a9d5a3d Not to be included 2013-07-27 16:35:15 +00:00
Dale Weiler
0291726c09 Fedora spec files (0.2.9 and 0.3.0) + INSTALL documentation, thanks Igor Gnatenko. 2013-07-27 16:33:33 +00:00
Dale Weiler
c7679722fb Please the whitespace gods 2013-07-27 11:48:55 +00:00
Dale Weiler
8db9724c5d Revert "Smaller memory footprint, 4/8 bytes vs 12/24 for individual token lex_ctx's. Use to be a 'shallow' copy of the details in lex_file, now it's a pointer to the contents in lex_file."
This reverts commit cddf70f46b.
2013-07-26 16:17:41 +00:00
Dale Weiler
cddf70f46b Smaller memory footprint, 4/8 bytes vs 12/24 for individual token lex_ctx's. Use to be a 'shallow' copy of the details in lex_file, now it's a pointer to the contents in lex_file. 2013-07-26 16:09:26 +00:00
Dale Weiler
4a3794ea2b Track strdup memory too 2013-07-26 14:57:21 +00:00
Dale Weiler
44d5481828 There was too many 16-sized buckets when compiling xonotic, increase the size: this is cheaper on memory and slightly faster. 2013-07-26 14:50:37 +00:00
Dale Weiler
629fe05083 Fix the ctype replacements to work with macro arguments that have side-effect, with exception to isspace which *might* need to become a function. 2013-07-26 12:28:02 +00:00
Dale Weiler
d411d60685 Eeasy fix for that 2013-07-21 22:07:22 +00:00
Dale Weiler
2bfea938b3 One last one 2013-07-21 22:00:07 +00:00
Dale Weiler
96ec279663 Another one 2013-07-21 21:56:03 +00:00
Dale Weiler
697ad9d3a7 Technically GCC was wrong here, since opts_ini_parse is guranteed to change error. 2013-07-21 21:51:34 +00:00
Dale Weiler
764b9abaf4 Cleanups 2013-07-19 11:43:22 +00:00
Dale Weiler
84ad8ec37a Update gmqcc.ini.example 2013-07-04 15:24:55 -04:00
Wolfgang Bumiller
17318af62f fix typo 2013-07-01 10:37:51 +02:00
Wolfgang Bumiller
b39a748984 actually no :) 2013-06-22 20:31:50 +02:00
Dale Weiler
b534aca263 Fix a case of the uninitialized blues 2013-06-22 02:25:19 +00:00
Dale Weiler
adc9e7bf22 Fix some more bugs (coverity you're a life saver) 2013-06-22 02:05:04 +00:00
Dale Weiler
560b45dd16 Buffer overflow! 2013-06-22 01:58:20 +00:00
Dale Weiler
bbffdde2dc Fix some bugs and a memleak in the testsuite. 2013-06-22 01:56:22 +00:00
Dale Weiler
063c50fce4 More bug fixes and dead code elimination 2013-06-22 01:23:59 +00:00
Dale Weiler
5429b6f189 Fix out of bound access 2013-06-22 01:16:24 +00:00
Dale Weiler
d39fb653aa Fix some more bugs, and use dup2 because dup leaks on some implementations. 2013-06-22 01:14:13 +00:00
Dale Weiler
e08f00bfcd Update clean rules in makefiles to remove coverity stuff 2013-06-22 00:16:44 +00:00
Dale Weiler
edf59e4f73 Fixed possible bug in VM. Added coverity rules to makefiles. 2013-06-22 00:15:25 +00:00
Dale Weiler
52e7394418 Fix uninitialized data 2013-06-22 00:00:17 +00:00
Dale Weiler
a982d4e524 Fix a sizeof bug 2013-06-21 23:55:47 +00:00
Dale Weiler
458cfcb48c I'm assuming this is a bug since all other read tests compare with itself's ir_value, and only this one doesn't. Otherwise why would you need to load to an ir_value for vec? 2013-06-21 23:54:09 +00:00
Dale Weiler
5bdf0aff81 Catch that one too 2013-06-21 23:51:49 +00:00
Dale Weiler
1929b129ee Improper use of a possible negative value. 2013-06-21 23:49:08 +00:00
Dale Weiler
ce23e95d0b Remove a ton of dead code and document the one really insane case. 2013-06-21 23:40:51 +00:00
Dale Weiler
684112474b cppcheck had the right idea, but the wrong scope on this one. 2013-06-21 23:29:50 +00:00
Dale Weiler
fe296de42f Fix more bugs (mostly possible NULL pointer dereferences) 2013-06-21 23:26:49 +00:00
Dale Weiler
996d998ebb Fix possible NULL pointer dereference 2013-06-21 23:21:12 +00:00
Dale Weiler
125d039e3d Fix some bugs 2013-06-21 23:16:00 +00:00
Dale Weiler
6db2e69f9a Oh my god microsoft you suck 2013-06-20 11:20:56 +00:00
Dale Weiler
82fd7fcf68 Move code generator into ir_builder for earlier free. It's also a much more cleaner design than load parser->code for all ast/ir operations. We also have a proper chain'd design now (so making this a library will be easier). 2013-06-20 10:52:58 +00:00
Dale Weiler
a2c3388e49 Fix some comments 2013-06-18 07:31:09 +00:00
Dale Weiler
944ec75687 Retarded clang warning is retarded. 2013-06-18 07:26:07 +00:00
Dale Weiler
3b8b76328c Holy mexicans 15% better hashing == 5% faster compiles. 2013-06-18 07:22:03 +00:00
Dale Weiler
e6c1d66c35 Merge branch 'master' into cooking
Conflicts:
	opts.def
2013-06-17 20:14:26 +00:00
Dale Weiler
51eb94f251 Enable it for gmqcc and fteqcc modes. 2013-06-17 20:13:21 +00:00
Dale Weiler
7e76b42f11 Merge branch 'master' of github.com:graphitemaster/gmqcc 2013-06-17 20:12:02 +00:00
Dale Weiler
23cb7f4e09 Fix some bugs 2013-06-17 20:11:37 +00:00
Dale Weiler
a04c0d2aa2 make source a dependency for the c.o rule 2013-06-16 08:35:58 +00:00
Dale Weiler
ad8d76b212 Fixed 2013-06-16 08:24:13 +00:00
Dale Weiler
de8974d03e Use includes for makefile consistency. Added make depend rule for BSDmakefile. 2013-06-16 08:21:23 +00:00
Wolfgang Bumiller
f8db5a7c6d reclassify_token should only deal with tokens < TOKEN_START... should fix #113 2013-06-16 09:56:21 +02:00
Wolfgang Bumiller
e6bb7697f9 reclassify_token should only deal with tokens < TOKEN_START... should fix #113 2013-06-16 09:53:11 +02:00
Dale Weiler
a3e1342bdb Update 2013-06-16 07:51:55 +00:00
Dale Weiler
ba85107a85 Better scheme 2013-06-16 07:48:41 +00:00
Dale Weiler
0e392f91d2 A new batch of fresh hot dependencies for both 2013-06-16 07:23:51 +00:00
Dale Weiler
685925398c Dependency consistency 2013-06-16 07:22:37 +00:00
Dale Weiler
ec6de55d3c Update some things 2013-06-16 07:21:40 +00:00
Dale Weiler
00d1d237bc Update install file 2013-06-16 07:16:44 +00:00
Dale Weiler
6de7c45618 A Makefile for BSD make. 2013-06-16 07:08:07 +00:00
Dale Weiler
004832f6ec Make it compile with g++ again 2013-06-16 05:59:41 +00:00
Dale Weiler
82e92811e4 Uhh forgot to save file 2013-06-16 03:46:07 +00:00
Dale Weiler
9a6316221c Fix memleak 2013-06-16 03:45:06 +00:00
Dale Weiler
2d654ddcff Update 2013-06-16 02:48:31 +00:00
Dale Weiler
5d2b57394e Add the good old xor swap trick to the xor test, yes it works :P 2013-06-16 02:24:10 +00:00
Dale Weiler
17ae2dbe4d Make ^ legal for vector ^ vector, and vector ^ float (read the huge comment that explains why and what this does). Currently only works for constants (don't know how to do expression for multiple vector components yet). 2013-06-16 02:17:29 +00:00
Dale Weiler
a27b7ee6a5 Make them tests work now 2013-06-15 11:05:25 +00:00
Dale Weiler
5694c77d16 I added it for a reason, because I was smart. I forgot about it because of life :( 2013-06-15 11:04:08 +00:00
Dale Weiler
0c58509417 This is easier 2013-06-15 09:53:12 +00:00
Dale Weiler
202fc67f93 Correct order 2013-06-15 09:52:22 +00:00
Dale Weiler
b9cf1f1262 Fix bug 2013-06-15 09:50:02 +00:00
Dale Weiler
a8fddbb7d3 Implemented bitwise xor operator. 2013-06-15 09:48:40 +00:00
Dale Weiler
04406b191f Less terse, it confuses people. 2013-06-15 08:56:34 +00:00
Wolfgang Bumiller
290d065a79 again with the comments... 2013-06-15 09:49:15 +02:00
Wolfgang Bumiller
3fab06941a fix a call typecheck issue 2013-06-15 09:46:44 +02:00
Wolfgang Bumiller
f78d653b1e manpage update 2013-06-15 09:46:44 +02:00
Wolfgang Bumiller
179da9241c working on vararg piping: detecting several error cases, adding -Wunsafe-types and -funsafe-varargs 2013-06-15 09:46:44 +02:00
Dale Weiler
7115176c0e Strlen idiot 2013-06-15 07:42:01 +00:00
Dale Weiler
fee7794789 Limit corrections on strings to <= 16 bytes. Otherwise memory usage spikes instantly on errors, and causes Windows DEP to kill gmqcc. 2013-06-15 07:40:42 +00:00
Dale Weiler
5012616cb0 Limit corrections on strings to <= 16 bytes. Otherwise memory usage spikes instantly on errors, and causes Windows DEP to kill gmqcc. 2013-06-15 07:39:36 +00:00
Dale Weiler
90a016c6e0 Fix a possible issue 2013-06-15 05:28:38 +00:00
Dale Weiler
6617684a8d Some fixes 2013-06-15 02:25:19 +00:00
Dale Weiler
8afd373e4f Fixed whitespace 2013-06-14 21:36:16 +00:00
Dale Weiler
3e75750ad6 What the fuck are we talking about? 2013-06-14 21:26:33 +00:00
Dale Weiler
17fd017d6f Revert "Actually works now"
This reverts commit daa1487aef.
2013-06-13 22:23:07 +00:00
Dale Weiler
daa1487aef Actually works now 2013-06-13 22:20:17 +00:00
Wolfgang Bumiller
f023b7097f fix pedantic compile issue 2013-06-12 16:04:40 +02:00
Wolfgang Bumiller
2c59385633 fixing double-free in initialzied string arrays, using them in the testcase 2013-06-12 15:53:07 +02:00
Wolfgang Bumiller
b30368f026 array testcase for previous commit 2013-06-12 15:47:59 +02:00
Wolfgang Bumiller
8ce331b563 allow array size to be inferred from the initializer 2013-06-12 15:47:11 +02:00
Wolfgang Bumiller
dc91918c1f error about too many elements in initializer; added test for initialized arrays: arrays2.tmpl/qc 2013-06-12 14:41:38 +02:00
Wolfgang Bumiller
633d2ba8a4 make the ast use the initlist 2013-06-12 14:36:59 +02:00
Wolfgang Bumiller
bc4a66e9f7 setting initializing values 2013-06-12 14:32:34 +02:00
Wolfgang Bumiller
7a36a8bdd8 parsing array initializers 2013-06-12 14:32:12 +02:00
Wolfgang Bumiller
d631c517b6 forgot to add that one 2013-06-12 13:56:40 +02:00
Dale Weiler
b773702a47 Fix builds 2013-06-09 00:11:52 +00:00
Dale Weiler
0eab97283f Merge branch 'cooking'
Conflicts:
	.gitignore
2013-06-06 06:20:58 +00:00
Dale Weiler
ad92a5f27d Fix indexing 2013-06-06 06:20:11 +00:00
Dale Weiler
144672fada Strict prototyping 2013-06-06 02:51:13 +00:00
Dale Weiler
4f02d4b556 Update 2013-06-04 18:38:16 +00:00
Wolfgang Bumiller
923e0187bd Merge branch 'cooking' of git://github.com/graphitemaster/gmqcc into cooking 2013-06-04 20:36:58 +02:00
Wolfgang Bumiller
52d39b7260 slackware pkg build files 2013-06-04 20:32:06 +02:00
Dale Weiler
81b27ea84a Consistency 2013-06-04 18:07:18 +00:00
Dale Weiler
0d52f1ae7c Update changelog 2013-06-04 18:02:02 +00:00
Dale Weiler
0f98f0fd4a Some typos. 2013-06-04 17:44:45 +00:00
Dale Weiler
af80d9956b Gentoo ebuilds 2013-06-04 17:43:20 +00:00
Dale Weiler
e29b4d35b3 Add license header 2013-06-04 02:53:44 +00:00
Dale Weiler
77cf1f8685 Doh 2013-06-04 02:49:49 +00:00
Dale Weiler
11179a2a71 Major header reworking, this respects the namespaces properly. Makes object dependency more obvious, allows for better make caches, and prevents misuse of library features, i.e use con_* instead of printf. 2013-06-04 02:47:07 +00:00
Wolfgang Bumiller
b2348e1de0 remove the ast tree earlier - saves over 3% peak memory usage 2013-06-02 12:35:53 +02:00
Dale Weiler
06cccbb646 Fix a divide by zero error 2013-06-02 09:50:39 +00:00
Dale Weiler
c1a9ce3404 Fix output 2013-06-02 08:52:30 +00:00
Dale Weiler
c569e87bd0 Fix two bugs 2013-06-02 08:49:16 +00:00
Dale Weiler
100eaf9137 Merge pull request #112 from matthiaskrgr/master
mmmeeerging eeeet
2013-06-02 01:38:47 -07:00
Dale Weiler
ee42d2a570 Some cleanups 2013-06-02 08:37:22 +00:00
Dale Weiler
564cac859a Fix the peak 2013-06-02 08:28:56 +00:00
Matthias Krüger
69b55ccc03 gitignore: add gmqcc, gmqpak, qmcvm, testsuite, pak. 2013-06-02 10:26:27 +02:00
Dale Weiler
7ea67748fa Holy whoops 2013-06-02 08:25:00 +00:00
Dale Weiler
9af3c502da Major utility rewrite for compiler memory utilization statistics. Cleanups everywhere, no more NOTRACK stuff, all allocates are tracked. Major identifier cleanups as well. 2013-06-02 08:21:06 +00:00
Dale Weiler
ec7bf4767a Some static 2013-06-02 05:32:37 +00:00
Dale Weiler
1ce8d2ea6e Hashtable statistics too 2013-06-02 05:09:28 +00:00
Dale Weiler
f884bd2217 Track hashtables too 2013-06-02 04:45:04 +00:00
Dale Weiler
79a7aa70b9 Track strdups too in the statistics 2013-06-02 04:38:20 +00:00
Dale Weiler
c8daf483f3 This was an experiment that snuk it's way inside that commit. 2013-06-02 04:32:20 +00:00
Dale Weiler
166b79720c Vector tracing, step two in determining how to lower memory usage. 2013-06-02 04:29:53 +00:00
Dale Weiler
121e080697 Guart statistics by option. 2013-06-02 00:07:54 +00:00
Dale Weiler
280dfdd3f8 Add statistics for vector usage to the output. Step one in lowering memory usage. ONE FUCKING MILLION VECTORS for XONOTIC.. 2013-06-02 00:03:27 +00:00
Wolfgang Bumiller
d85e86141c fix a leak on a parse-error 2013-06-01 23:36:05 +02:00
Dale Weiler
655822ec1a Doh 2013-06-01 20:20:25 +00:00
Dale Weiler
062180e9a8 Fix some possible memleaks. 2013-06-01 20:18:53 +00:00
Wolfgang Bumiller
9f2b9e1b46 Merge branch 'master' into cooking 2013-06-01 20:12:27 +02:00
Wolfgang Bumiller
ff63e5bd73 fix the INCLUDE_DEF flag getting applied regardless of dotranslate... 2013-06-01 20:12:14 +02:00
Wolfgang Bumiller
1dce501b70 Merge branch 'master' into cooking 2013-06-01 18:16:56 +02:00
Wolfgang Bumiller
ed585f8c04 fix: dotranslate now sets AST_FLAG_INCLUDE_DEF to not get removed by -Ostrip-constant-names 2013-06-01 18:16:50 +02:00
Dale Weiler
b0a0769534 Merge branch 'cooking' of github.com:graphitemaster/gmqcc into cooking 2013-05-30 19:36:37 +00:00
Dale Weiler
0b6269f607 column printing for warnings and errors now 2013-05-30 19:36:01 +00:00
Wolfgang Bumiller
ba781c53ef now a bare 'return;' is not required anymore if return has been assigned anywhere 2013-05-29 17:08:03 +02:00
Wolfgang Bumiller
a76702cb36 make sure missing return values still warn 2013-05-29 17:01:26 +02:00
Wolfgang Bumiller
5aba29006b return assignment factorial test 2013-05-29 16:58:18 +02:00
Wolfgang Bumiller
9167de1631 fixing that comment... 2013-05-29 16:56:39 +02:00
Wolfgang Bumiller
afdc0c9dc8 assignable return value now lives in ast_function, as globals can get overwritten randomly; removed parser_find_retval; updated parse_return 2013-05-29 16:51:59 +02:00
Dale Weiler
db6ca6c5f8 Make static 2013-05-29 11:32:42 +00:00
Dale Weiler
fd5506b376 Update test template. 2013-05-29 11:30:26 +00:00
Dale Weiler
1b71caa1fe Update man page 2013-05-29 11:29:52 +00:00
Dale Weiler
6d6a2efada Experimental support for implicit return assignments. This closes #107. To enable return assignment support use -freturn-assignments. This allows you to do the following in QC code. T name() { return = expr_eval_T; return; /* returns expr_eval_T */ }. It allows for concise code and to rid locals in functions. It also saves a tremendous amount of space since only types of certian globals need to be allocated for returns. 2013-05-29 11:13:42 +00:00
Dale Weiler
2923b718e1 Merge branch 'union-replacement' into cooking
Conflicts:
	ast.c
2013-05-29 03:43:49 +00:00
Dale Weiler
e3f4ae3038 Add back that splint flag 2013-05-29 03:39:38 +00:00
Dale Weiler
d45956f55e Fix that memory leak that I spent hours trying to find months ago and didn't succeed at. 2013-05-29 03:35:51 +00:00
Dale Weiler
f892b32335 Major export cleanup. Anything that was exported but wasn't used outside where it was implemented has been turned into static, and their exports have been removed. This actually makes the compiler compile slightly faster. 2013-05-29 03:29:04 +00:00
Dale Weiler
df8b486c98 Prevent negitive numbers from being used as the left operand of shift operator. 2013-05-29 02:37:45 +00:00
Dale Weiler
e02ebfe486 Result of shift operation on signed integers is bad. 2013-05-29 02:24:12 +00:00
Dale Weiler
f281de7a3c Cleanups and fixes 2013-05-29 02:16:50 +00:00
Wolfgang Bumiller
d70b571769 killing the union types 2013-05-11 22:34:01 +02:00
Wolfgang Bumiller
ef6e2bd583 first step to getting rid of those unions we don't use anyway 2013-05-11 22:05:30 +02:00
Wolfgang Bumiller
a0fa90ddd5 less confusing 2013-05-07 20:35:20 +02:00
Wolfgang Bumiller
802005f571 be more strict here 2013-05-07 20:13:19 +02:00
Wolfgang Bumiller
4d0a5af475 removing this dead code_init call 2013-05-07 19:59:06 +02:00
Wolfgang Bumiller
c5225b2fa1 fixing a few leaks - code_write doesn't delete the code object anymore, code_cleanup has to be called 2013-05-07 19:56:41 +02:00
Wolfgang Bumiller
8c8ae71d65 changing a few ast_delete to ast_unref in places where the to-be-deleted maybe coming from some other place 2013-05-07 19:39:10 +02:00
Wolfgang Bumiller
3e7cd8a98b Merge pull request #111 from matthiaskrgr/cooking_stuff
.gitignore: add binarys
2013-05-05 04:12:14 -07:00
Matthias Krüger
9823b294df .gitignore: add binarys 2013-05-05 12:53:58 +02:00
Dale Weiler
c07c78c666 Escape strings in executor for -printdefs 2013-05-02 19:18:59 +00:00
Dale Weiler
79a5ed0482 Implemented support for having codegen (and lno files) be wrote out to memory, this essentially allows us to embed the compiler in applications now. 2013-04-28 04:29:20 +00:00
Dale Weiler
721b581376 Fix deps (remove duplicates with clever make tricks) 2013-04-28 03:50:22 +00:00
Dale Weiler
3d115760a0 Merge branch 'cooking' of github.com:graphitemaster/gmqcc into cooking 2013-04-28 03:42:04 +00:00
Dale Weiler
a8e2a47da8 Less general name for PAK utility, added install targets for PAK utility, added manpag for PAK utility, this closes #108 2013-04-28 03:41:03 +00:00
Wolfgang Bumiller
f6792c3a05 Merge branch 'master' into cooking 2013-04-27 19:05:06 +02:00
Wolfgang Bumiller
bc4749d95a Merge pull request #109 from matthiaskrgr/PKGBUILD_master
PKGBUILD: archlinux: fix build by applying a patch (4c4aa5534c) on 0.2.9 package.
Accepting this with a patch in order for it to keep the 0.2.9 version info.
2013-04-27 10:04:43 -07:00
Matthias Krüger
90eed12e97 PKGBUILD: archlinux: fix build by applying a patch (4c4aa5534c) on 0.2.9 package. 2013-04-27 18:45:26 +02:00
Wolfgang Bumiller
2058ce69a4 Merge branch 'master' into cooking 2013-04-27 17:52:54 +02:00
Wolfgang Bumiller
4c4aa5534c dup is marked as warn-unused-result 2013-04-27 17:51:51 +02:00
Dale Weiler
dc6a7436ee Expression has undefined behavior (left operand modifies code->globals->used, used by right operand): (code->globals)[(((vector_t*)((void *)code->globals)) - 1)->used++] = (code_genstring(code, global->constval.vstring)) Code has unspecified behavior. Order of evaluation of function parameters or subexpressions is not defined, so if a value is used and modified in different places not separated by a sequence point constraining evaluation order, then the result of the expression is unspecified. 2013-04-27 15:20:01 +00:00
Wolfgang Bumiller
35120caf80 debian Makefile had the same flaw as archlinux/this... fixing 2013-04-27 17:00:27 +02:00
Wolfgang Bumiller
9ace0811ce Merge branch 'master' into cooking 2013-04-27 16:55:28 +02:00
Wolfgang Bumiller
d4b0e1f588 updating archbsd and archlinux release/PKGBUILD files 2013-04-27 16:54:53 +02:00
Wolfgang Bumiller
18cf3641b1 Merge branch 'master' into cooking 2013-04-27 16:33:55 +02:00
Wolfgang Bumiller
01ead27dd9 Update CHANGES file 2013-04-27 16:33:47 +02:00
Wolfgang Bumiller
b8e536d409 Starting point of 0.3.0 2013-04-27 16:30:35 +02:00
Wolfgang Bumiller
219508e478 this should be tagged 0.2.9 2013-04-27 16:30:03 +02:00
Wolfgang Bumiller
75ceab8f51 fix distro/ Makefiles 2013-04-26 17:56:08 +02:00
Wolfgang Bumiller
5007fd7f71 don't overwrite ldflags/libs env vars 2013-04-26 17:44:44 +02:00
Dale Weiler
50ff9e4fd0 Fix OSX compiles 2013-04-26 15:43:13 +00:00
Wolfgang Bumiller
7e0d6bdd87 don't overwrite ldflags/libs env vars 2013-04-26 17:33:56 +02:00
Wolfgang Bumiller
9f8bee4bf1 ast_value now has an initializer list array, still unused but it's there for later 2013-04-26 10:47:55 +02:00
Wolfgang Bumiller
b3e9ef3ad9 an = before an { is also always required when the declared variable is not a function; adding because of planned array initializers 2013-04-26 10:31:38 +02:00
Dale Weiler
1077eb2061 Add expressions for builtins test 2013-04-25 17:39:05 +00:00
Wolfgang Bumiller
d4f8e4a0dd solve it, not hide it 2013-04-25 19:18:50 +02:00
Wolfgang Bumiller
35692c0b57 Revert "Just fucking initialize everything"
This reverts commit aed2b1031c.
2013-04-25 19:18:11 +02:00
Wolfgang Bumiller
b9fb29d740 manpage and ini update 2013-04-25 19:17:58 +02:00
Dale Weiler
aed2b1031c Just fucking initialize everything 2013-04-25 17:11:15 +00:00
Dale Weiler
68ca2c4962 Pushing the -fexpressions-for-builtins stuff and the modff for catching fractional-part builtin numbers. 2013-04-25 17:08:02 +00:00
Wolfgang Bumiller
ce73074d51 this allows builtin numbers to be constant expressions, not just constants 2013-04-25 18:47:54 +02:00
Wolfgang Bumiller
c3f4b7153b change the value of TOKEN_EOF 2013-04-25 17:39:12 +02:00
Dale Weiler
2eddc464d5 Less extern 2013-04-25 12:22:34 +00:00
Dale Weiler
3d8e8cd80d cleaner 2013-04-25 12:08:43 +00:00
Dale Weiler
9fee84f250 less globals 2013-04-25 12:08:13 +00:00
Dale Weiler
785ab7c072 No more globals for codegen 2013-04-25 09:35:30 +00:00
Wolfgang Bumiller
73070395eb these can be const now 2013-04-25 09:55:58 +02:00
Dale Weiler
c6f2c8fc3d That is also not needed anymore 2013-04-25 03:37:40 +00:00
Dale Weiler
2a3376cb52 not needed for arm anymore 2013-04-25 03:36:57 +00:00
Dale Weiler
10dd7aacfe Apply some static where it belongs 2013-04-25 03:34:42 +00:00
Dale Weiler
1b5504fb9e Fix alignment issues (can remove a clang warning, and also makes our code more portable!) 2013-04-25 03:17:52 +00:00
Dale Weiler
bfbb60bbed Use the LIBS properly 2013-04-25 03:11:50 +00:00
Wolfgang Bumiller
3a4aba0b31 Grrrr 2013-04-24 17:47:42 +02:00
Wolfgang Bumiller
1a915c7bf7 manpage: document and explain __FUNC__ and __NULL__ 2013-04-24 17:42:48 +02:00
Wolfgang Bumiller
66305c676a Allow string concatenation in the parser as well, for now only for immediate strings and __FUNC__, maybe later -fpermissive or somethign could allow it on const-delcared string variables 2013-04-24 17:27:04 +02:00
Dale Weiler
8ffdfbfd97 A nicer way of doing this 2013-04-24 14:08:58 +00:00
Dale Weiler
5d88216f38 remove irrelevant comment 2013-04-24 14:06:43 +00:00
Dale Weiler
19c57c03cc free the memory for asprintf 2013-04-24 14:05:09 +00:00
Dale Weiler
a0f6b00a15 Shitty testsuite support for windows the hacky way because there exists no sane simple way of redirecting pipes without a heafty chunk of code. 2013-04-24 14:04:00 +00:00
Wolfgang Bumiller
1e9d3e43cb test for the simple __FUNC__ case 2013-04-24 11:22:29 +02:00
Wolfgang Bumiller
dcd65f18f8 recognize the simple case of __FUNC__ in the parser 2013-04-24 11:21:10 +02:00
Dale Weiler
8bee9a6819 fix the intrinsic fail 2013-04-24 09:18:24 +00:00
Dale Weiler
6284cc673d typo 2013-04-24 04:50:07 +00:00
Dale Weiler
b3fc77efd6 Implemented __TIME_STAMP__ predef, expands to a timestamp of when the __FILE__ was last modified, returned in the format: "Www Mmm dd hh:mm:ss yyyy", where Www is the weekday, Mmm the month (in letter), dd the day of the month, hh:mm:ss the time, and yyyy the year. 2013-04-24 04:48:05 +00:00
Dale Weiler
35988b6191 Make ftepps __NULL__ translate to gmqccs untyped nil keyword (this isn't correct behaviour of the __NULL__ constant, but it works) 2013-04-24 04:17:17 +00:00
Dale Weiler
dc8523c650 Merge branch 'master' into cooking 2013-04-24 01:46:53 +00:00
Dale Weiler
489ad486bc Get it compiling in visual studio again. 2013-04-24 01:43:53 +00:00
Dale Weiler
10738da2fb Make it compile as C++ code too 2013-04-23 22:50:47 +00:00
Wolfgang Bumiller
17996dee50 fix noreturn testcase descriptions... those were mixed up 2013-04-23 17:07:19 +02:00
Wolfgang Bumiller
f6d554874b initialize the vector member array so that 'cleanup' won't delete uninitialized pointers 2013-04-23 16:54:05 +02:00
Wolfgang Bumiller
3d9a06591a Makefile: be more conformant: at link-time use LDFLAGS, not CFLAGS, also use CPPFLAGS prepended to CFLAGS at compile-commands, append optional LIBS at link-time after everything else 2013-04-23 16:49:43 +02:00
Wolfgang Bumiller
d6f6241872 misc/check-doc.sh 2013-04-22 12:22:24 +02:00
Dale Weiler
c86e778c76 Website target to distro makefile for updating gh-pages 2013-04-22 06:14:26 +00:00
Dale Weiler
217833dff7 Add download.c (used for generating the download.html for the website (for releases)) based on magic. use gcc download.c -o gen; gen ../../; git checkout gh-pages; git add download.html; git push origin gh-pages; to apply website changes. 2013-04-22 05:43:38 +00:00
Dale Weiler
1759388e3f Merge branch 'master' into cooking 2013-04-22 00:11:31 +00:00
Dale Weiler
9a1894f587 Proper install names (preserve the .exe for win32 builds) 2013-04-22 00:05:44 +00:00
Dale Weiler
a879fc28a3 Merge pull request #105 from matthiaskrgr/icon
Icon
2013-04-21 07:22:11 -07:00
Matthias Krüger
cc3b8dcfd6 make: gource: display gmqcc icon in video. 2013-04-21 14:08:23 +02:00
Matthias Krüger
53aac525d9 add gmqcc icon found on ohloh. 2013-04-21 14:07:06 +02:00
Dale Weiler
f8fc40c306 Merge branch 'master' of github.com:graphitemaster/gmqcc 2013-04-21 11:46:05 +00:00
Dale Weiler
0f7634876f Some stuff for building win32 packages via mingw32 2013-04-21 11:45:41 +00:00
Dale Weiler
ef565adaa5 Merge pull request #104 from matthiaskrgr/PKGBUILD_master
PKGBUILD: archlinux: git: install syntax files to respective dirs.
2013-04-21 04:14:06 -07:00
Matthias Krüger
f9ed308aa8 PKGBUILD: archlinux: git: install syntax files to respective dirs. 2013-04-21 13:05:45 +02:00
Wolfgang Bumiller
685fa54daf Merge branch 'master' into cooking 2013-04-21 12:37:06 +02:00
Dale Weiler
160e7cf7ee Remove trailing whitespace 2013-04-21 10:24:55 +00:00
Wolfgang Bumiller
934ff4a5eb Merge branch 'master' into cooking 2013-04-21 12:24:12 +02:00
Wolfgang Bumiller
2343e13c45 updating the manpage 2013-04-21 12:23:54 +02:00
Dale Weiler
8c08897749 Fixes 2013-04-21 10:13:51 +00:00
Dale Weiler
462c06d56b Merge branch 'cooking' 2013-04-21 10:09:08 +00:00
Dale Weiler
317559e5a5 Update CHANGES 2013-04-21 10:08:04 +00:00
Dale Weiler
4a1eb7f948 update README to reflect syntax highlighting stuff. 2013-04-21 09:44:08 +00:00
Dale Weiler
f3c04d0f37 Add jedit syntax highlighting support, thanks to LordHavoc (made some changes to reflect gmqcc syntax more) 2013-04-21 08:13:39 +00:00
Dale Weiler
3cecd5d066 This is suppoted now 2013-04-21 07:30:32 +00:00
Dale Weiler
7def17eed5 Add syntax configuration file for gtksourceview (this allows QC code syntax highlighting for GNOMEs default text view in nautilus, gedit, and sandy + other gtksouceview based editors). 2013-04-21 07:27:59 +00:00
Dale Weiler
c362826dc6 typo 2013-04-21 07:07:07 +00:00
Dale Weiler
0661002257 update README for syntax highlighting stuff 2013-04-21 07:06:37 +00:00
Dale Weiler
96c0fa983d A more realistic preprocessor concatenation test. 2013-04-21 06:52:22 +00:00
Dale Weiler
6009e2b3ea Undo that fail 2013-04-21 06:46:54 +00:00
Dale Weiler
07e335fdb8 Better output on failure 2013-04-21 06:46:39 +00:00
Dale Weiler
e27eebe0f9 More preprocessor testsuite support and our first preprocessor test! 2013-04-21 06:36:52 +00:00
Dale Weiler
c53fa31a0a More preprocessor testing support for the testsuite. 2013-04-21 06:23:40 +00:00
Dale Weiler
79282bfee0 Initial preprocessor procedure option for testsuite implemented. 2013-04-21 06:20:17 +00:00
Dale Weiler
ea0e2c47d5 We don't need to specify "-should fail" because we print the type now (this also makes the description colum shorter) 2013-04-21 06:13:25 +00:00
Dale Weiler
57d2876021 I did it, I did it, I did it, horray!, Thanks Dora .. I mean Hirato. 2013-04-21 06:09:20 +00:00
Dale Weiler
485866552d Some work in progress preprocessing test work 2013-04-21 05:50:21 +00:00
Dale Weiler
b47e3ebccf Remove hashset 2013-04-21 04:56:41 +00:00
Wolfgang Bumiller
46752af74b parser_const_string now uses hashtables; hashtables may want to dup an empty string without it becoming NULL - also replacing ir_strdup with the new util_ one 2013-04-17 18:23:30 +02:00
Wolfgang Bumiller
8f2a22b8c3 fix warnings to allow compiling with -O3 2013-04-17 17:58:08 +02:00
Dale Weiler
dc7e18ec73 Some inline never hurt anyone .. actually, C made a bad decision in it's design, everything should've always been implicitly inline, since most code back in the day was small, if you had large bodies, there should've been an 'outline' keyword for that instead :P 2013-04-17 11:02:42 +00:00
Dale Weiler
0b0b6423ba Use hashtable for macro definitions in the preprocessor, this speeds up the search for them, and the removal of them making it O(1) instead of O(n). This also makes my 30 second xonotic compiles take only 13 seconds 2013-04-17 10:51:33 +00:00
Wolfgang Bumiller
4d394494b6 don't call ftepp_finish on a freed ftepp struct 2013-04-17 11:36:45 +02:00
Dale Weiler
d7be99c9dd More perliminary reworking for threading 2013-04-17 06:30:09 +00:00
Dale Weiler
21c6079b7a Fix compile for windows. 2013-04-17 04:27:00 +00:00
Dale Weiler
1f0a1b8140 Perliminary parser reworking, required for the proposed multithreading. 2013-04-17 00:52:52 +00:00
Dale Weiler
b82efcf0ce Fix typo in kate syntax highlighting installation documentation. 2013-04-16 20:27:01 +00:00
Dale Weiler
a61c9c6d89 Added syntax highlighting configuration files (with documentation on how to install them) for nano, kate and geany. 2013-04-16 20:24:33 +00:00
Wolfgang Bumiller
992c6fbfb8 lex_try_pragma: free the buffers 2013-04-16 14:14:15 +02:00
Dale Weiler
1c51fb80eb Fix memdump printing 2013-04-16 09:13:22 +00:00
Dale Weiler
f2b21158d8 Rewrote memory tracking, now prints highest water mark (most used memory at a given time during compile). Changes all byte representation to MB representation. Added ability to print the contents of the leaked memory to the console when -debug is on (infact the lost messages only print during -debug), -memchk simply reports the memory info at the end (it is also printed when -debug). You can set the memory dump columns with -memdumpcols=# where # is the number of columns you want (default is 16) 2013-04-15 20:54:53 +00:00
Wolfgang Bumiller
1a9c82483c fix macro parameters 2013-04-15 21:07:44 +02:00
Wolfgang Bumiller
1f667c4b35 ast_expression_delete: delete varparam if it is set - fixes another leak 2013-04-15 21:05:59 +02:00
Wolfgang Bumiller
d5e90a17f9 fix memleak in ast_local_codegen 2013-04-15 20:56:48 +02:00
Wolfgang Bumiller
1caf1b3ebe util_strdup: don't use util_memory_a with -DNOTRACK 2013-04-15 20:53:53 +02:00
Dale Weiler
c2b5a95961 GCC specific stuff compile flags. 2013-04-15 06:23:13 +00:00
Dale Weiler
ef528d6710 Added tracing to strdup for allocations, fixed some memleaks, this isn't pretty (trying to track down some weird memory leak issues) 2013-04-14 23:51:16 +00:00
Dale Weiler
18fad16a7d cleanups 2013-04-14 01:41:13 +00:00
Dale Weiler
7ba7fd5968 Fet rid of explicit file stream flushes, streams are flushed on exit, which we can always gurantee. 2013-04-14 01:32:29 +00:00
Dale Weiler
752409417f Remove one more external function 2013-04-14 01:29:50 +00:00
Dale Weiler
4591b3a4fa More flattening. I don't know why I turned off buffering, that makes output to console even slower due to all the flushes, which actually slows down compilation. 2013-04-14 01:26:40 +00:00
Dale Weiler
eb2a74f7e7 Flatten more external functions 2013-04-14 01:25:11 +00:00
Dale Weiler
a25bd052d7 More function flatening 2013-04-14 01:16:35 +00:00
Dale Weiler
ccc2eb3298 More function flatening 2013-04-14 01:14:14 +00:00
Dale Weiler
3e7340c52c More external function flatening (less external symbols) 2013-04-14 01:07:39 +00:00
Dale Weiler
3f546df677 Revert that trans stuff 2013-04-14 01:03:22 +00:00
Dale Weiler
48d6375817 flatten the use of strcpy, 90% of the cases we already knew the length of the string either at compile-time, or already within the scope we where, thus letting us use strncpy, which can be further optimized (unrolled if static) 2013-04-14 01:00:25 +00:00
Dale Weiler
3f40fcb965 Fix possible buffer overflows. 2013-04-13 18:17:15 +00:00
Dale Weiler
95172861f5 Fix possible bug 2013-04-13 18:04:07 +00:00
Dale Weiler
c62d88cb57 Merge branch 'cooking' of github.com:graphitemaster/gmqcc into cooking 2013-04-13 18:01:41 +00:00
Dale Weiler
c74889f648 Fix some memory leaks. 2013-04-13 18:01:26 +00:00
Wolfgang Bumiller
cb0169a784 Merge pull request #103 from matthiaskrgr/cooking
fix arch pkgbuilds
2013-04-13 03:50:57 -07:00
Matthias Krüger
7b3bbf05b9 gitignore: ignore pkg.tar.xz packages in distro/arch{linux/bsd} 2013-04-13 11:23:10 +02:00
Matthias Krüger
f5ba2e825f PKGBUILD: release: fix sha1sum, minor cleanup 2013-04-13 11:19:48 +02:00
Matthias Krüger
5bb10260b3 PKGBUILD: git: fix for pacman 4.1.0 2013-04-12 22:08:10 +02:00
Matthias Krüger
47ebf7c84c .gitignore: add /pak 2013-04-12 21:51:55 +02:00
Dale Weiler
c6bd5e6a2b Update specification.tex 2013-04-08 00:05:55 -03:00
Wolfgang Bumiller
a6ac90215b we changed the prefix... there too 2013-04-02 23:40:26 +02:00
Wolfgang Bumiller
c01ad2bfcf we changed the prefix... 2013-04-02 23:39:42 +02:00
Dale Weiler
50e8618b64 Merge pull request #102 from matthiaskrgr/cooking
gource stuff
2013-03-27 13:15:00 -07:00
matthiaskrgr
54c89e485a make: gource flags: add
--key
    --camera-mode overview
    --highlight-all-users
    --file-idle-time 0
    --hide progress,mouse
    --stop-at-end
    --max-files 99999999999
    --max-file-lag 0.000001
    --bloom-multiplier 1.3
2013-03-27 20:05:43 +01:00
matthiaskrgr
8e122d78be Makefile: split up 'make gource' into 'make gource' (render only) and 'make gource-record' (record using ffmpeg) 2013-03-27 19:50:39 +01:00
Dale Weiler
58a04a04e5 Make variable for flexibility 2013-03-21 06:17:50 +00:00
Dale Weiler
6900e50289 Uploadability from package building using dropbox API (all inside a makefile with magics) 2013-03-21 06:01:34 +00:00
Dale Weiler
c42a853e0b Some protection for cross arch package building 2013-03-21 04:47:46 +00:00
Dale Weiler
1b02a5204a Cross architecture stuff for distro build scripts. If you have an x86_64 capable system with a compiler and make (the OS doesn't even matter), simply changing to "distro" directory and typing "make" is sufficent to make archlinux i686/x86_64, and debian i686/x86_64 packages. 2013-03-21 02:02:41 +00:00
Dale Weiler
66b5cf29ba While we're at it, fix that one too. 2013-03-15 22:56:45 +00:00
Dale Weiler
6a0f9d3cb2 *sigh* 2013-03-15 22:56:09 +00:00
Dale Weiler
11255058cf SPACES PEOPLE 2013-03-15 22:53:00 +00:00
Dale Weiler
dfca3743f9 Added gource rule to makefile 2013-03-15 22:51:40 +00:00
Dale Weiler
a798859a7a Added isnan compiler builtin, documented what each compiler builtin does as well. 2013-03-09 09:20:54 +00:00
Dale Weiler
d4785ad6e3 fix comment 2013-03-09 08:59:12 +00:00
Dale Weiler
965f8b9041 Uh wrong file. 2013-03-09 08:57:37 +00:00
Dale Weiler
cbeac3e5f2 Implemented smart intrinsic / builtin system. When you use trivial math functions like "pow", if they don't exist as a builtin, the compiler will implement its own versions, likewise, if a compiler builtin depends on a function that exists, it will use it, likewise if it doesn't it will implement it. If you explicitally use __builtin_ (prefixed) versions, the compiler again will select the best option it can, be it a combination of both builtins and compiler builtins, all compiler builtins, OR, all builtins (most performant). 2013-03-09 08:53:39 +00:00
Dale Weiler
9bb586fb5a Add floor to tests defs.qh 2013-03-09 05:46:08 +00:00
Dale Weiler
d8d78f61a7 Implemented "reverse" enum attribute, e.g enum : reverse { A, B, C, D } -> A,B,C,D = 3,2,1,0 2013-03-09 05:07:14 +00:00
Dale Weiler
73c085a461 Fix operator precedence, closes #101 2013-03-09 04:25:02 +00:00
Dale Weiler
662612d66f Better diagnostic when "floor" cannot be found. 2013-03-08 09:23:35 +00:00
Dale Weiler
f19adcd1b3 Implemented __builtin_mod, and % operator. Added floor builtin to the standalone executor. Mod works so long as the compiler can find a suitable definition of "float floor(float)", otherwise it prints a diagnostic and gives up (original id1 Quake had floor so we can depend on it). 2013-03-08 09:17:54 +00:00
Dale Weiler
b971ddec3a Implemented concept of enumeration attributes (can be further extended, but currently only "flag" is implemented as an attribute). An enumeration with a flag attribute will act as a "flagged enumeration", one that automatically handles exponentiation of the constants defined inside it, i.e enum : flag { A, B, C }, A,B,C will equal 2, 4, 8. 2013-03-08 08:01:45 +00:00
Dale Weiler
479f3b9343 Implemented __builtin_exp 2013-03-08 03:46:25 +00:00
Dale Weiler
12340a6bd0 Actually generate an ast_call for __builtin_pow for the ** operator, otherwise the operator yeilds a ast_function, making "a ** b" not work, but since it's a function, allows **(a, b). Also added tests for exponentiation operator. 2013-03-07 23:05:40 +00:00
Dale Weiler
0367a6175d Add some ice 2013-03-07 22:52:03 +00:00
Dale Weiler
db229b6f94 Make ** RIGHT associative 2013-03-07 22:14:04 +00:00
Dale Weiler
bd54fe03b9 Get rid of the bullshit log stuff 2013-03-07 22:09:14 +00:00
Dale Weiler
f2380a2faa They see me roll 'n, casting, so far they just think I'm implicit casting dirty, implicity casting dirty .. 2013-03-07 21:38:46 +00:00
Dale Weiler
d3c7b6fb39 Implement exponentiation operator ** as well as __builtin_pow (used for exponentiation operator). Use of exponentiation operator with constants results in const folded (precomputed at compile time exponentiation), otherwise runtime exponentiation with some clever loops (slow!). 2013-03-07 21:31:19 +00:00
Dale Weiler
f59d557dce Update specification.tex 2013-03-07 10:21:29 -05:00
Dale Weiler
bedfee1fae Update specification.tex 2013-03-07 10:19:00 -05:00
Dale Weiler
bdbfc85243 Update specification.tex 2013-03-07 09:39:41 -05:00
Dale Weiler
2146e018f1 Update specification.tex 2013-03-07 00:39:26 -05:00
Wolfgang Bumiller
a32f59b256 hopefully fix an off-by-1 vararg copy issue 2013-02-26 16:39:28 +01:00
Dale Weiler
9f06e0e017 Print the number for the test itself in the test-suite. The log10 can be improved. 2013-02-25 10:01:36 +00:00
Dale Weiler
b1d1aabbdd Remove debug printf 2013-02-25 08:52:56 +00:00
Dale Weiler
aebab8b68a Push definitions when -O0 2013-02-25 08:52:17 +00:00
Wolfgang Bumiller
d27c06ea7f Merge branch 'master' into cooking 2013-02-20 23:08:58 +01:00
Wolfgang Bumiller
80184b0d80 fix: don't mess up multiline macros in files ending with \r\n 2013-02-20 23:08:50 +01:00
Wolfgang Bumiller
aa27249b88 update to .gitignore 2013-02-13 10:55:32 +01:00
Wolfgang Bumiller
3593a1b6b8 Merge branch 'master' into cooking 2013-02-12 14:31:27 +01:00
Dale Weiler
3b923a0183 fix 2013-02-11 18:02:42 +00:00
Dale Weiler
3b630ec5dc Less duplication 2013-02-11 17:51:23 +00:00
Dale Weiler
c7e3e3e306 Fix fucking mingw32 shit. 2013-02-11 17:49:17 +00:00
Wolfgang Bumiller
1dfd375738 include: guard the actual inclusion with ftepp->output_on so that include inside #if 0 doesn't happen 2013-02-11 12:13:27 +01:00
Wolfgang Bumiller
3e3b8993aa Lifetime analysis: Don't go through the blocks as a graph, instead, go through only the list.
The difference in code is rather small, but it's much faster.
2013-02-11 11:39:44 +01:00
Dale Weiler
0b154d69e7 BOOM 2013-02-10 13:59:24 +00:00
Dale Weiler
c8959a2452 BOOM 2013-02-10 13:57:22 +00:00
Dale Weiler
b5ead871ef Consider cppchecks (performance) warnings. 2013-02-10 13:47:50 +00:00
Dale Weiler
5acde18ef1 Sigh 2013-02-10 02:09:12 +00:00
Dale Weiler
b0c6dc5ab2 Fix mem leak. 2013-02-10 02:08:17 +00:00
Dale Weiler
e4554892b0 Oops 2013-02-08 19:07:12 +00:00
Dale Weiler
e4075916f0 depend rule for $(OBJ_P) PAK utility. 2013-02-08 16:45:05 +00:00
Dale Weiler
fb8fb9f0f7 These includes are not required 2013-02-08 16:43:31 +00:00
Dale Weiler
ac8f510dac Added $(PAK) to Makefile for clean rule. 2013-02-08 16:42:43 +00:00
Dale Weiler
02230ca992 endian swap on FOURCC for "PACK" on BE systems. 2013-02-08 16:40:47 +00:00
Dale Weiler
533b2144c5 Fix some memleaks. 2013-02-08 16:39:14 +00:00
Dale Weiler
eabb92f7b4 A command line interface for the PAK utility, made it a seperate build target too. 2013-02-08 16:32:15 +00:00
Dale Weiler
a568d43487 Implemented __VA_COUNT__ 2013-02-08 12:30:17 +00:00
Dale Weiler
945aba6e10 Make it compile as C++ code AGAIN 2013-02-08 12:20:48 +00:00
Dale Weiler
09a1a37554 Actually add fs.c 2013-02-08 12:08:24 +00:00
Dale Weiler
8d59d7029d Cleanup cargocult directory and file specific things, to fs.c (renamed file.c which also contains directory handling stuff). Also cleaned up some stuff, and added proper end comments to conditional inclusion stuff. 2013-02-08 12:06:59 +00:00
Dale Weiler
ece64dc779 fix build issue 2013-02-07 20:10:01 +00:00
Dale Weiler
aef60b7ec1 Add directory support for extract_all 2013-02-07 20:08:50 +00:00
Dale Weiler
8ecfc51799 Cleanups and fixes to the PAK utility, can now extract/insert, tested and functional for the most part. 2013-02-07 17:21:15 +00:00
Dale Weiler
1fa9fbb94b Fixes to the PAK utility. 2013-02-07 17:07:29 +00:00
Dale Weiler
86df8c8a78 Work in progress PAK extractor/insterter. 2013-02-07 16:22:47 +00:00
Dale Weiler
d1f4b108a0 Update makefile 2013-02-06 10:54:14 +00:00
Dale Weiler
ecd9e3be97 Make the testsuite C++ compatible. 2013-02-06 10:52:09 +00:00
Dale Weiler
eb0e3c2898 Make it compile as C++ code again. 2013-02-06 10:36:27 +00:00
Wolfgang Bumiller
9bc774dcd3 find aliases in parser_find_global instead of parser_sya_operand 2013-02-06 10:55:06 +01:00
Dale Weiler
cb1a6a6a6b Store the ast nodes for aliases 2013-02-06 09:44:23 +00:00
Dale Weiler
1e60bafcdc Aliases to aliases is a bad idea, revert. Added better tests to show unused aliases 2013-02-06 09:28:42 +00:00
Dale Weiler
21e890602d Fix alias bug. Implemented support for aliases of vectors (x, y, z components). Also made aliases corrector resident (e.g alias to vector foo, named bop, indexing bol_x [instead of bop_x] will result in a correction suggestion of bop_x now). 2013-02-06 09:09:47 +00:00
Dale Weiler
6fc141733f Support for aliases to aliases too. 2013-02-06 08:43:11 +00:00
Dale Weiler
060bc0be10 Some sanity checks for aliases (undeclared variable checks, and incompatible types in alias checks.) 2013-02-06 05:51:05 +00:00
Dale Weiler
3dc8e9bb9c add todo 2013-02-06 05:38:34 +00:00
Dale Weiler
e464cc1ea6 Implemented generalized attribute aliases. You can now alias functions, locals, or globals with [[alias("old_name")]] type new_name; 2013-02-06 05:30:09 +00:00
Dale Weiler
52ffc6db10 Merge branch 'cooking' of github.com:graphitemaster/gmqcc into cooking 2013-02-05 17:16:09 +00:00
Dale Weiler
9cff2f7b8a perl ops -> pops 2013-02-05 17:15:28 +00:00
Dale Weiler
b3e87c3280 ast referencing 2013-02-05 17:14:56 +00:00
Wolfgang Bumiller
4b5afe3456 ast_array_index_codegen: never regenerate code 2013-02-05 17:54:14 +01:00
Dale Weiler
e2c424d607 Merge branch 'cooking' of github.com:graphitemaster/gmqcc into cooking 2013-02-05 16:35:12 +00:00
Dale Weiler
8e87082e1d Merge branch 'cooking' of github.com:graphitemaster/gmqcc into cooking
Conflicts:
	parser.c
2013-02-05 16:34:55 +00:00
Wolfgang Bumiller
72106b0982 removing some left-over alloc checks 2013-02-05 17:34:40 +01:00
Dale Weiler
fed0f8b6b4 Work in progress <=> operator. 2013-02-05 16:34:03 +00:00
Wolfgang Bumiller
f860759758 fixing that comment 2013-02-05 17:24:02 +01:00
Wolfgang Bumiller
15141897ae insert an error when an operator doesn't get found - note the comment... 2013-02-05 17:17:38 +01:00
Dale Weiler
31ce4c2afa Better handling of multiple body functions. 2013-02-05 03:28:20 +00:00
Dale Weiler
8e1cd4b1df Update doc/specification.tex 2013-02-04 11:13:11 -05:00
Dale Weiler
442adee298 Update doc/specification.tex 2013-02-04 06:22:28 -05:00
Dale Weiler
e11a17b408 Update doc/specification.tex 2013-02-04 02:48:36 -05:00
Dale Weiler
e7aa24bd28 Work in progress specification LaTeX document for "The GMQCC QuakeC Programming Language" 2013-02-04 07:18:39 +00:00
Wolfgang Bumiller
06ff6eb054 get that message back in 2013-02-04 00:28:35 +01:00
Wolfgang Bumiller
ce8b595ff2 Yes, that's what you are SUPPOSED to do in this case: ERROR, not default to crap 2013-02-04 00:20:41 +01:00
Wolfgang Bumiller
46892daa3a Reverting this awful unmaintainable mess of option description system 2013-02-04 00:19:56 +01:00
Wolfgang Bumiller
e662efae61 fix: rotate_entfield_array_index_nodes deleting the old array caused expressions to be deleted recursively 2013-02-03 23:38:06 +01:00
Wolfgang Bumiller
530dbd85b2 properly mask #message, #warning, #error by ftepp->output_on 2013-02-03 23:23:50 +01:00
Wolfgang Bumiller
0d1b40c9c1 Adding a WIP style sheet for mandoc html output 2013-02-03 19:38:42 +01:00
Wolfgang Bumiller
c41ef65cc9 Merge branch 'master' into cooking 2013-02-03 19:01:30 +01:00
Wolfgang Bumiller
95dd0fcd9f Add -fdarkplaces-string-table-bug to the default flags 2013-02-03 19:01:27 +01:00
Dale Weiler
2b51b35634 Fix this target for archlinux 2013-02-02 09:02:03 +00:00
Dale Weiler
ddb0be6c0a Merge pull request #96 from matthiaskrgr/cooking_PKGBUILD
PKGBUILDs: rename "arch" to "archlinux", move archbsd PKGBUILDs into own...
2013-02-02 00:58:57 -08:00
matthiaskrgr
2e07a7b2c1 PKGBUILDs: rename "arch" to "archlinux", move archbsd PKGBUILDs into own "archbsd" parent directory. 2013-02-02 09:54:31 +01:00
Dale Weiler
7b96b0bd6d s/%d/%s/ 2013-02-02 01:04:26 +00:00
Dale Weiler
319783e873 Better printing of token errors. 2013-02-02 01:03:39 +00:00
Dale Weiler
4c0a836ca6 typo 2013-02-02 00:59:19 +00:00
Dale Weiler
d45853f5fe Update authors file 2013-02-02 00:58:15 +00:00
Dale Weiler
9bf8f9c505 Add bitnot test for testsuite. 2013-02-02 00:12:46 +00:00
Dale Weiler
ccdfd4c65a oops 2013-02-01 23:12:48 +00:00
Dale Weiler
394f1deade Merge branch 'cooking' of github.com:graphitemaster/gmqcc into cooking 2013-02-01 23:11:26 +00:00
Dale Weiler
a3559548a8 Fix ~ unary operator (can now const-fold). Also things like b &= ~1 work now. We also cache ast_value of float (-1) for -1-x (which is how ~ is implemented). 2013-02-01 23:10:23 +00:00
Wolfgang Bumiller
c34f5d20ed Merge branch 'cooking' of git://github.com/graphitemaster/gmqcc into cooking 2013-02-01 19:12:45 +01:00
Dale Weiler
03b933bc7a Work in progress ~ operator implemented as -1-x. 2013-02-01 12:56:01 +00:00
Dale Weiler
bf6eb9432e Fix memleak and assignment for cached lengths in corrector 2013-02-01 06:22:29 +00:00
Wolfgang Bumiller
ea15abada5 manpage: removed -Wpreprocessor 2013-01-31 22:23:29 +01:00
Wolfgang Bumiller
622c55f254 converted qcvm.1 to mdoc 2013-01-31 22:15:01 +01:00
Dale Weiler
d7a47eb5f9 Ignore most memory comparisions by validating the lengths are the same first. Becomes O(log(n)) from O(n) for correct_exists. 2013-01-30 23:32:15 +00:00
Dale Weiler
a6ecc3cbc4 Cache lengths in corrector. This speeds up the corrector a little. 2013-01-30 23:22:03 +00:00
Dale Weiler
a1fac66587 Added definition file for test-suite, used by default by the test system. To override the defs globally, use -defs=file from the command line for the test-suite. To override the defs per-file, use F: -no-defs flag in the test template file. 2013-01-30 08:04:56 +00:00
Dale Weiler
9fffb3441c Older clang had -Wmissing-variable-declarations, which causes a heap of warnings, we disable it, because it's a stupid warning. However, because it's unsupported in newer clang, disabling it causes a warning, so we need to -Wno-unknown-warning-option. *sigh* 2013-01-30 06:52:36 +00:00
Dale Weiler
5f9f6c11b8 Get it compiling with C++ compilers again. 2013-01-30 06:49:50 +00:00
Dale Weiler
1916a6e339 Slightly larger code, but strategic inline for corrector stuff. Makes it a little faster on my RPi (unnoticable on my desktop though). 2013-01-30 06:36:00 +00:00
Dale Weiler
b9f46f4ef7 Not an assembler instruction, but virtual instruction used by the IR. 2013-01-30 06:31:24 +00:00
Dale Weiler
18c317a787 Empty string, not "<null>" 2013-01-30 06:28:02 +00:00
Dale Weiler
8c6f4c3fc3 Cleanups 2013-01-30 06:27:06 +00:00
Dale Weiler
835659ac48 Don't ignore return result from test_perform. 2013-01-30 06:17:57 +00:00
Dale Weiler
44c87bedfc It is used, gcc is a liar. 2013-01-30 06:14:35 +00:00
Dale Weiler
98fd5cd429 Some cleanups and what not. 2013-01-30 06:13:11 +00:00
Dale Weiler
ebd6a1ae95 Document the options in the opts.def file 2013-01-30 06:04:34 +00:00
Dale Weiler
9f5f2b6d74 Fix pragma parsing that I broke. 2013-01-30 05:51:28 +00:00
Dale Weiler
e12d492d67 Removing #error/#warning/#message from parser, and making it part of preprocessor as directives again. 2013-01-30 05:49:08 +00:00
Dale Weiler
36c5722273 Rename 2013-01-30 05:35:07 +00:00
Dale Weiler
d201cfe6b4 Work in progress options cleanup. 2013-01-30 05:24:30 +00:00
Dale Weiler
6c4c373089 Print off the documentation when -[f/W/O]help, also fixed some of the descriptions for flags. 2013-01-30 04:22:13 +00:00
Dale Weiler
480b2fc7b6 Added documentation to all options inside the binary itself. These will be used later for "man/nroff -man"-like documentation on OSs that lack "man" and the concept of system wide documentation. Also it will be nice to add -Wsome_warning help (to get some help about a specific warning/error, etc). 2013-01-30 02:56:58 +00:00
Dale Weiler
f3c5c40104 Fix splint warning 2013-01-30 01:38:37 +00:00
Dale Weiler
76614b311e s/WARN_PREPROCESSOR/WARN_CPP/g (to stay somewhat compatible with gcc/clang warnings for the preprocessor) 2013-01-30 01:32:10 +00:00
Dale Weiler
d61172598e Removed -Wcpp (not needed any more) 2013-01-30 01:26:51 +00:00
Dale Weiler
3d35804a7d Removed #warning and #error from ftepp, and made it part of the parser routine. These are "directives" that should exist regardless if -fftepp is enabled, like #pragma. Implemented #warning, #message and #error as directives in parser instead. 2013-01-30 01:24:58 +00:00
Dale Weiler
7ea1033a43 Handle all possible subscript errors 2013-01-27 21:31:18 +00:00
Dale Weiler
1597f38f45 Better handling of __VA_ARGS__ subscripting. 2013-01-27 21:27:50 +00:00
Dale Weiler
b9fcd64a1f Spiceing up the __VA_ARGS__ test 2013-01-27 13:05:01 +00:00
Dale Weiler
6fc5b32123 Fix warning, and better tests for __VA_ARGS__ 2013-01-27 13:03:02 +00:00
Dale Weiler
001d853f38 Merge branch 'cooking' of github.com:graphitemaster/gmqcc into cooking 2013-01-27 12:56:43 +00:00
Dale Weiler
b4fbba5708 Implement subscripting for __VA_ARGS__, and added test-case. This only works on INTCONST for now. 2013-01-27 12:55:56 +00:00
Wolfgang Bumiller
370b54251e importing bsd-git/PKGBUILD 2013-01-27 13:12:57 +01:00
Wolfgang Bumiller
95e8140555 fixing an install cmd in bsd-release/PKGBUILD 2013-01-27 13:12:04 +01:00
Wolfgang Bumiller
3518646ad7 unmasking bsd-git/PKGBUILD in .gitignore 2013-01-27 13:10:44 +01:00
Wolfgang Bumiller
03f364a944 importing ArchBSD release PKGBUILD 2013-01-27 13:09:09 +01:00
Wolfgang Bumiller
44e416e790 unmasking bsd-release path in .gitignore 2013-01-27 13:08:31 +01:00
Wolfgang Bumiller
3e1c10628c adding pkgrel to arch/this, and getting rid of du's -b option since it won't work for ArchBSD 2013-01-27 10:31:27 +01:00
Dale Weiler
531fbaf28c Remove user-defined success/failure messages for the testsuite. Instead print an aligned to console string containing the tmpl file name. This closes #90. 2013-01-27 08:39:42 +00:00
Dale Weiler
a94d2fee4e Fixes, updates, and added uninstall target for makefile 2013-01-27 07:45:49 +00:00
Dale Weiler
3cc97984bf Add back the removal of the package directory after building package. 2013-01-27 07:26:50 +00:00
Dale Weiler
74ba208a44 Fix the size calculation 2013-01-27 07:25:46 +00:00
Dale Weiler
b4d3241e27 Add this/Makefile for generating a .tar.xz for arch packages. This is sort of like the debian one, it can be run from any *nix systems to generate a package. Currently only generates an x86_64 package, like the debian one (which only does i686). 2013-01-27 07:08:27 +00:00
Wolfgang Bumiller
4500facb2b manpage: wrong date 2013-01-26 14:44:00 +01:00
Wolfgang Bumiller
edfe340d09 Fix a warning 2013-01-26 14:43:49 +01:00
Wolfgang Bumiller
b39b61e514 store the actual parsing context before parsing into an expression and use that for the effectless-statement warning 2013-01-25 23:37:06 +01:00
Wolfgang Bumiller
9afe41471b error when using a type not usable as boolean in a condition, ie an if statement 2013-01-25 19:19:23 +01:00
Wolfgang Bumiller
7fb3b97e73 -v now prints the initial value of globals in -printdefs 2013-01-25 19:17:31 +01:00
Wolfgang Bumiller
48f8d0e0c3 changing some error prints to print to stderr in exec.c 2013-01-25 18:41:17 +01:00
Wolfgang Bumiller
ad7059156a now moving -Ocall-stores to -O3 2013-01-25 16:25:59 +01:00
Wolfgang Bumiller
9b51e7085b In this situation the values don't need to be in parameter order; fix: call-stores putting values into wrong extparams 2013-01-25 16:25:23 +01:00
Wolfgang Bumiller
31f0c05ebc Merge branch 'master' into cooking 2013-01-25 16:03:38 +01:00
Wolfgang Bumiller
3c8ce7c866 moving -Ocall-stores to -O4 until the vehicle issue is solved 2013-01-25 16:03:16 +01:00
Wolfgang Bumiller
69e29c3ef8 debug extparam naming shouldn't start at 8, it's confusing, param 9 is now named extparam0 2013-01-25 15:37:09 +01:00
Wolfgang Bumiller
ef0de47954 Converting gmqcc.1 from man to mdoc style. It can produce nice html output so we can create an online version of the manpage which doesn't look like crap... still todo: qcvm.1 2013-01-24 22:23:49 +01:00
Wolfgang Bumiller
32f1a5d2c8 manpage: fixing a .TP/.B mixup 2013-01-24 12:56:38 +01:00
Wolfgang Bumiller
62af1659eb adding testcase for various parentheses and ternary combinations which to test the newly refactored code; includes some cases not hit by xonotic 2013-01-18 15:22:53 +01:00
Wolfgang Bumiller
dca9dd56d1 adding missing wantop flag and some related parentheses code 2013-01-18 15:22:03 +01:00
Wolfgang Bumiller
ba207cc04c Major expression parsing code refactoring, getting rid of lots of duplicated code and in the process also fixing a bug. Still thie will require more testing. xonotic code works with it though 2013-01-18 14:50:37 +01:00
Dale Weiler
496aededb1 Fix debian package building, now works. 2013-01-18 00:45:35 +00:00
Wolfgang Bumiller
5d9ad219cf removing unused vars, and following conventions 2013-01-17 23:46:27 +01:00
Dale Weiler
99482a324e -f to supress error if file doesn't exist for rm clean target 2013-01-17 22:34:39 +00:00
Dale Weiler
57102aea4a Use $(PREFIX) 2013-01-17 22:34:06 +00:00
Dale Weiler
1d4c0bb388 Fix the brokenness 2013-01-17 22:33:02 +00:00
Wolfgang Bumiller
de28df33ec Rather than performing copying the install-procedure, the debian Makefile could just use the main Makefile's install target 2013-01-17 23:25:09 +01:00
Wolfgang Bumiller
a8d5504445 fixing manpage permissions 2013-01-17 23:22:38 +01:00
Dale Weiler
94a83ad969 Added makefile script for generating deb packages the portable .. but more manual way. It doesn't support multi-architecture yet. It just grabs what ever is already compiled. Not tested! 2013-01-17 22:10:36 +00:00
Wolfgang Bumiller
06f53b1a28 When not actually executing, don't complain about invalid progs.dat versions for now. 2013-01-17 17:36:06 +01:00
Wolfgang Bumiller
8697fa59f3 Added counter-stability test to the varargs testcase 2013-01-17 10:32:43 +01:00
Wolfgang Bumiller
1410840ef6 Make the varargs counter more stable, it'll now work with a function pointer with a different number of fixed params 2013-01-17 10:30:32 +01:00
Wolfgang Bumiller
4c0a358e2b Update CHANGES file 2013-01-17 10:06:01 +01:00
Wolfgang Bumiller
d5ba5a6e6a linenumbers and macros are stupid 2013-01-16 23:34:54 +01:00
Wolfgang Bumiller
7d2b0e9638 more linenumber madness 2013-01-16 22:58:43 +01:00
Wolfgang Bumiller
b31e9b63eb fix: trigraph check screwing up linenumbering 2013-01-16 22:09:27 +01:00
Wolfgang Bumiller
81f3a6d186 fix an off-by-one bug when copying varargs 2013-01-16 21:04:08 +01:00
Wolfgang Bumiller
00a9d2a9e3 fixing a possible NULL deref 2013-01-16 20:32:37 +01:00
Wolfgang Bumiller
e311dffcb3 fixing a warning 2013-01-16 16:16:52 +01:00
Wolfgang Bumiller
0ba8455f6a initialize max_param_count to 1 so vararg functions don't try to create an accessor for an array of 0 elements... 2013-01-16 09:37:32 +01:00
Wolfgang Bumiller
dfad837f5b this might fix some linenumbering, I hope 2013-01-15 22:29:44 +01:00
Wolfgang Bumiller
11450c11d1 manpage: -E was missing all that time in there 2013-01-15 22:08:15 +01:00
Wolfgang Bumiller
dfa6d0c9ad call ftepp_recursion_header/footer only when there are newlines in the expanded macro 2013-01-15 22:03:16 +01:00
Wolfgang Bumiller
f8f4ad8ee5 a tiny speedup, seems like -O2 doesn't do that by itself 2013-01-15 20:57:30 +01:00
Wolfgang Bumiller
e695a5919d reduce the hashtable size a bit 2013-01-15 20:35:30 +01:00
Wolfgang Bumiller
b311cd6163 that tempbool should have gone long ago... 2013-01-15 20:27:23 +01:00
Wolfgang Bumiller
73afc98699 fix: on error it was possible that leaveblock() is called after the function's already been deleted 2013-01-15 14:28:15 +01:00
Wolfgang Bumiller
150c6e21e7 fix a goto to a wrong error-cleanup part 2013-01-15 14:23:17 +01:00
Wolfgang Bumiller
c7ca5683b9 fix a possible leak 2013-01-15 14:20:08 +01:00
Wolfgang Bumiller
0f190026e8 Error on an empty paren expression 2013-01-15 14:18:03 +01:00
Wolfgang Bumiller
ee7d45f492 add a hint about -fvariadic-args to -Wvariadic-function 2013-01-15 11:35:18 +01:00
Wolfgang Bumiller
b208c1a49f Fix a crash... if (!x) delete(x) yeah right... 2013-01-15 10:50:14 +01:00
Wolfgang Bumiller
73c86127f7 fix the broken vector instructions in our executor as well... how could I forget 2013-01-14 14:22:02 +01:00
Wolfgang Bumiller
bfbbe0c771 gmqcc.ini.example: LEGACY_VECTOR_MATHS 2013-01-14 11:17:25 +01:00
Wolfgang Bumiller
0962dfdd4d manpage: -flegacy-vector-maths 2013-01-14 11:16:49 +01:00
Wolfgang Bumiller
d12e6e15c9 -flegacy-vector-maths, enabled by default 2013-01-14 11:15:06 +01:00
Wolfgang Bumiller
d7f4e981a3 fix: missing-return check: vec_size(entries) is 0 on the entry-block, also check if it's the first block 2013-01-14 10:56:56 +01:00
Wolfgang Bumiller
bec05f1bbb apparently it's possible to segfault DP with a bad INSTR_LOAD_V - so the IR should not allow this 2013-01-13 21:00:13 +01:00
Wolfgang Bumiller
ab8cc64dfd constant-fold the 1/N division from a_vector/N 2013-01-13 20:53:07 +01:00
Wolfgang Bumiller
a5029a510a test for vec/float 2013-01-13 20:49:27 +01:00
Wolfgang Bumiller
3d62cb37f1 allow vec/float 2013-01-13 20:49:16 +01:00
Wolfgang Bumiller
e0504ce482 This undef was missing there... 2013-01-13 17:37:09 +01:00
Wolfgang Bumiller
12ffd83d4f parsewarning->compile_warning 2013-01-13 17:32:54 +01:00
Wolfgang Bumiller
8d4e395092 Replacing lots of parseerror calls with compile_error calls and a more correct context information 2013-01-13 17:31:31 +01:00
Dale Weiler
1d05cd28ee Merge pull request #85 from matthiaskrgr/master
better gitignore for arch linux pkgbuild related files
2013-01-12 17:33:01 -08:00
matthiaskrgr
3ecae267ad gitignore: be more clever 2013-01-13 02:11:08 +01:00
Wolfgang Bumiller
3652a122ed Removed -fenhanced-diagnostics - it's now --correct, which makes sense since it doesn't affect the compilation process itself 2013-01-12 17:10:07 +01:00
Dale Weiler
d1def27dbb Uhh I did it again 2013-01-12 15:47:41 +00:00
Dale Weiler
08200d4f77 serpate line travis-ci build url for notifications 2013-01-12 15:47:08 +00:00
Wolfgang Bumiller
7fc88cfe5b fix a build issue 2013-01-12 16:38:49 +01:00
Wolfgang Bumiller
61b777f575 vararg testcases 2013-01-12 16:37:26 +01:00
Wolfgang Bumiller
f440c3c614 gmqcc.ini.example: VARIADIC_ARGS 2013-01-12 16:32:36 +01:00
Wolfgang Bumiller
127cc5215b manpage: -fvariadic-args 2013-01-12 16:31:51 +01:00
Wolfgang Bumiller
4df6d1e028 guarding vararg code by -fvariadic-args 2013-01-12 16:28:04 +01:00
Wolfgang Bumiller
47db74c699 this is useless and just confused me a lot, removing 2013-01-12 16:20:31 +01:00
Wolfgang Bumiller
7dd31ccf77 entity setter array subscript needs to get a correct field type 2013-01-12 15:49:31 +01:00
Wolfgang Bumiller
5887afae62 copying the output type on ast_array_index_codegen 2013-01-12 15:49:04 +01:00
Wolfgang Bumiller
a01388ea7d Copying arg counter into the local 2013-01-12 15:06:19 +01:00
Wolfgang Bumiller
57c0a09800 Creating the argument counter if requested 2013-01-12 14:59:30 +01:00
Wolfgang Bumiller
175623592b updated CHANGES file 2013-01-12 14:54:11 +01:00
Wolfgang Bumiller
e149551744 Added '...(idx,type)' to access varargs 2013-01-12 14:53:48 +01:00
Wolfgang Bumiller
cd543aad5e added gen_function_varargs_copy 2013-01-12 14:48:56 +01:00
Wolfgang Bumiller
e8b5ad6625 mask -Olocal-temps by IR_FLAG_MASK_NO_LOCAL_TEMPS which now equals IR_FLAG_MASK_NO_OVERLAP - though HAS_ARRAYS usually suffices, but not for code which _depends_ on uninitialized variables 2013-01-12 14:03:54 +01:00
Wolfgang Bumiller
2a4ea74a97 ir_function stores max_varargs now 2013-01-12 14:01:16 +01:00
Wolfgang Bumiller
1861660585 builtins are generally not declared const, so don't expect CV_CONST, otherwise we write out va_count for builtin calls as well... 2013-01-12 13:52:42 +01:00
Wolfgang Bumiller
c10d127fd7 While at it: moving generation of reserved:version to just before the functions so no global/immedate is generated _after_ it - at least from the parser's point of view 2013-01-12 13:49:06 +01:00
Wolfgang Bumiller
d78997599a create store to reserved:va_count; fix: don't build vararg accessor ast tree after generating immediates as they create new ones 2013-01-12 13:47:56 +01:00
Wolfgang Bumiller
973122ed9b ast_call now has a va_count which causes a store to reserved:va_count before the call 2013-01-12 13:29:47 +01:00
Wolfgang Bumiller
6dfdf69a8e vararg accessor generation 2013-01-12 13:01:20 +01:00
Wolfgang Bumiller
c69ba2c734 parsing of vararg-counter 2013-01-12 11:29:03 +01:00
Wolfgang Bumiller
87ff481abf updated CHANGES file 2013-01-12 11:11:31 +01:00
Wolfgang Bumiller
6a248e2498 type restricted varargs 2013-01-12 11:10:29 +01:00
Wolfgang Bumiller
ca947d782c Declaration of type-restricted varargs 2013-01-12 11:03:17 +01:00
Wolfgang Bumiller
2f9db8972e keep track of the highest parameter count of calls for later for varargs 2013-01-12 10:58:01 +01:00
Wolfgang Bumiller
3429e7d0cb 'static' shouldn't be accepted in the global scope for now 2013-01-12 10:52:18 +01:00
Wolfgang Bumiller
30eac57199 filling type_name in exec.c 2013-01-11 23:15:16 +01:00
Wolfgang Bumiller
5bb4e40c72 code cleanup: prog_tempstring used to cast const char * parameter to char * due to the old vector code which is now gone 2013-01-11 23:13:36 +01:00
Wolfgang Bumiller
7bab7fc42e fixing CHANGES: this actually was not part of 0.2 2013-01-11 23:12:00 +01:00
Wolfgang Bumiller
d6ffcbb8fc CHANGES file updated 2013-01-11 23:10:41 +01:00
Wolfgang Bumiller
199ed6c31f Fix a typo - why the hell does clang not complain? Why the hell does it even compile with clang... 2013-01-11 20:04:46 +01:00
Wolfgang Bumiller
5231279113 manpage: --add-info 2013-01-11 19:23:03 +01:00
Wolfgang Bumiller
3436fa7d89 added the --add-info compile switch: it adds a global const string named version to the 'reserved' namespace, ie ends up named 'reserved:version', containing the --version string 2013-01-11 19:18:51 +01:00
Wolfgang Bumiller
6df3c625b0 Added a flag to both ast and ir which enforces the generation of a globaldef for a value 2013-01-11 19:15:59 +01:00
Wolfgang Bumiller
5ea710e317 In order to avoid release version strings in non-git builds, by default --version on non-tagged commits now also prints 'development build' as the 2nd line 2013-01-11 10:40:33 +01:00
Wolfgang Bumiller
88cfa53dc2 replacing an error message in the enum parsing 2013-01-10 22:08:49 +01:00
Dale Weiler
0d9144eeff mention CHANGES in README 2013-01-10 20:52:23 +00:00
Dale Weiler
f6197a965c Better enumeration test 2013-01-10 20:50:42 +00:00
Wolfgang Bumiller
4a063d3518 enum testcase 2013-01-10 21:38:32 +01:00
Dale Weiler
0da4626417 will warn about "check" no such file or directory (since it aliases in the rule for the Makefile) 2013-01-10 20:28:53 +00:00
Wolfgang Bumiller
fa90d2d06e correction fix: don't try to create edits for an empty string 2013-01-10 21:09:44 +01:00
Wolfgang Bumiller
0616bb9468 CHANGES file updated 2013-01-10 21:05:10 +01:00
Wolfgang Bumiller
9c2bc7f381 Allow accessing vector components via the . operator, including components
of expressions, like: (3 * a_vector).y.
2013-01-10 21:03:35 +01:00
Wolfgang Bumiller
a474f20b84 CHANGES file updated 2013-01-10 19:59:01 +01:00
Wolfgang Bumiller
aa8b9eb1ad parse_expression_leave: also end at a closing } - enum: check for } and , after an expression again 2013-01-10 18:52:43 +01:00
Wolfgang Bumiller
a468d0b478 simple 'enum' implementation 2013-01-10 18:38:57 +01:00
Wolfgang Bumiller
1c1ea1d0f7 strictness sweep: (void)-ing all vec_ macros which don't evaluate to a sensible value 2013-01-10 18:26:35 +01:00
Wolfgang Bumiller
101cb09e91 git package is now named gmqcc-git, also added conflicts/provides 2013-01-10 16:31:01 +01:00
Wolfgang Bumiller
f69f2c2ece the -git PKGBUILD needs 'git' as makedepends according to the guidelines on the arch wiki 2013-01-10 16:25:36 +01:00
Wolfgang Bumiller
16ccaffc3f checking if git even is available 2013-01-10 16:13:47 +01:00
Wolfgang Bumiller
7a5a328c54 --version now prints GMQCC_GITINFO, which is not not defined in gmqcc.h to some empty string, it just won't exist in release builds 2013-01-10 16:07:33 +01:00
Wolfgang Bumiller
f06a59e3c7 Fix a warning 2013-01-10 16:04:58 +01:00
Wolfgang Bumiller
ffba3429fb This file seems to live in the past. Let's pull it over 2013-01-10 15:55:58 +01:00
Wolfgang Bumiller
cf676443cb manpage: updating the section about nil vs fteqcc-__NULL__ 2013-01-10 15:41:36 +01:00
Wolfgang Bumiller
81cc4194dc fixed a bug which allowed some statements to end in tokens other than semicolons... (ie closing parens) 2013-01-10 15:23:04 +01:00
Wolfgang Bumiller
428453a132 for compile-time constants << and >> are now available 2013-01-10 15:12:19 +01:00
Wolfgang Bumiller
06101d48e4 manpage: A note about __NULL__ vs nil 2013-01-09 21:54:36 +01:00
Wolfgang Bumiller
d0efaa50d4 Adding a CHANGES file 2013-01-09 21:49:28 +01:00
Wolfgang Bumiller
96126b435a manpage: __DATE__, __TIME__ predefs 2013-01-09 21:32:17 +01:00
Wolfgang Bumiller
10c7f4f838 don't call correct_edit anew for each scope 2013-01-09 21:16:22 +01:00
Wolfgang Bumiller
6b0a522bb9 Factor out the adding of globals in various places into parser_addglobal; Add globals to the correct_variables lists 2013-01-09 20:42:33 +01:00
Wolfgang Bumiller
704ddf94f8 manpage: Document change to -Wall 2013-01-09 20:41:12 +01:00
Wolfgang Bumiller
4f7113116d -Wall now does not set -Wuninitialized-global 2013-01-09 20:39:17 +01:00
Wolfgang Bumiller
be6942d972 fixing a crash caused by the correction: setting correct=NULL after freeing so the later if(correct) check properly fails 2013-01-09 19:12:27 +01:00
Wolfgang Bumiller
9eefe90d78 removing a goto loop 2013-01-09 16:00:16 +01:00
Wolfgang Bumiller
16e789419d testcase for mul_vf/fv 2013-01-08 21:55:34 +01:00
Wolfgang Bumiller
7d4340469e So it wasn't _reall_ the optimization... it just made it easier. -Olocal-temps -> -O3 2013-01-08 21:23:38 +01:00
Wolfgang Bumiller
a76ae11241 more IR dump verbosity; fix: MUL_VF/FV additional liferange must be propagated to the full vector when using a vector-member as float-parameter 2013-01-08 21:21:52 +01:00
Wolfgang Bumiller
6ece523552 sqrt and normalize builtins 2013-01-08 20:46:30 +01:00
Wolfgang Bumiller
d6809ed331 better solution to blockstart pointlife issues 2013-01-08 15:22:24 +01:00
Wolfgang Bumiller
4c05230cb3 Seems like there's still a problem with it - -Olocal-temps back up to -O4 2013-01-07 20:27:50 +01:00
Wolfgang Bumiller
3f3ed9b6f0 added a testcase for -Olocal-temps 2013-01-07 19:09:15 +01:00
Wolfgang Bumiller
57c3d48711 error when trying to break/continue outside of loops/switches instead of segfaulting at codegen 2013-01-07 15:19:53 +01:00
Wolfgang Bumiller
debfe136a5 Moving -Olocal-temps back to -O3 2013-01-07 14:55:42 +01:00
Wolfgang Bumiller
ae97ff7a80 This should fix the -Olocal-temps issue; set v->unique_life for any v with a point-life - this is a bad solution: proper dead code elimination should be done instead 2013-01-07 14:55:05 +01:00
Wolfgang Bumiller
63e5bc91de more info in the IR dump 2013-01-07 14:55:05 +01:00
Dale Weiler
a395a20dba close #76 implemented -Werror-some-warning section [errors] for the ini system. 2013-01-07 12:46:50 +00:00
Dale Weiler
54c8801bec Merge branch 'master' of github.com:graphitemaster/gmqcc 2013-01-07 12:40:03 +00:00
Dale Weiler
d8ae1cb3e9 Move splint.sh into the Makefile 2013-01-07 12:39:33 +00:00
Wolfgang Bumiller
cbb91c2026 moving -Olocal-temps to -O4 until the issues are solved 2013-01-07 12:58:56 +01:00
Wolfgang Bumiller
99249c8fa3 Guard 2 peephole optimizations which should only work on the currently-last instruction by a check if it's actually really at the end... 2013-01-07 00:22:54 +01:00
Wolfgang Bumiller
f4d1ef4740 Fix some possible NULL access in an error case 2013-01-07 00:22:16 +01:00
Wolfgang Bumiller
4d72c85f73 __STD_QCCX__ on -std=qccx - I have no idea about what qccx does/can do but at least now -fftepp includes the macros... 2013-01-06 20:52:12 +01:00
Wolfgang Bumiller
5134673461 manpage: bring the list of included -f and -W flags for each described -std up to date 2013-01-06 20:50:18 +01:00
Wolfgang Bumiller
5d1685b93d Adding -ftranslatable-strings to -std=gmqcc 2013-01-06 20:49:57 +01:00
Wolfgang Bumiller
dcc511f4c3 make the LNOF header compiler friendlier 2013-01-06 16:40:38 +01:00
Wolfgang Bumiller
e59d50ee5d Merge branch 'master' of git://github.com/graphitemaster/gmqcc 2013-01-06 16:37:05 +01:00
Wolfgang Bumiller
2531a3695f fixup qcvm parameter handling, now progs.dat can be specified anywhere not just at the end 2013-01-06 16:37:02 +01:00
Dale Weiler
985a177288 Pipe stderr from makedepend for depend rule in makefile to /dev/null 2013-01-06 15:27:39 +00:00
Dale Weiler
ecb83404ab Add test alias to check for make file 2013-01-06 15:12:46 +00:00
Dale Weiler
8ac6bcdad7 Add splint rule to makefile 2013-01-06 12:43:46 +00:00
Dale Weiler
4f873e1d9d remove never reached return 2013-01-06 12:39:37 +00:00
Dale Weiler
7cc7e912e7 Enable corrector by default 2013-01-06 12:29:25 +00:00
Dale Weiler
72f056a4d7 Merge branch 'screwaround' 2013-01-06 12:29:07 +00:00
Dale Weiler
ac5cc49840 remove a the 2013-01-06 12:28:27 +00:00
Dale Weiler
9a4e215179 Document the awesome hack 2013-01-06 12:24:05 +00:00
Wolfgang Bumiller
9c8ddb3771 An evil optimization to the trie, now has a fixed amount of branches and uses a char-to-index map to index into the branches... 2013-01-06 13:07:28 +01:00
Dale Weiler
1e17b5f696 Cleaner transformation calls (one less size_t for agruments). We can coalesce it in correct_edit. 2013-01-06 11:02:39 +00:00
Dale Weiler
3fa771f51d Leave a space here for makedepend 2013-01-06 10:56:25 +00:00
Dale Weiler
4afe61060d Add a "depend" rule for the makefile. It uses makedepend to generate dependinces that are catted to the current Makefile. 2013-01-06 10:55:22 +00:00
Dale Weiler
0f4090402d No need to +1 for comparision in correct_known_resize 2013-01-06 10:37:09 +00:00
Dale Weiler
cfdeaf4786 Fix comments 2013-01-06 10:35:43 +00:00
Dale Weiler
056779d3b8 Remove trailing shitspace 2013-01-06 10:33:09 +00:00
Dale Weiler
6f5a20e76b Use -O2 by default 2013-01-06 10:29:29 +00:00
Dale Weiler
a4c1e63637 Less pointer dereferences 2013-01-06 05:17:30 +00:00
Dale Weiler
cc7e1a3363 Screw you clang :-) 2013-01-06 05:14:57 +00:00
Dale Weiler
ee33b4e5cc A little faster, plus some more research 2013-01-06 05:13:19 +00:00
Dale Weiler
0c59274c54 This is a work of art, it deserve nice comments :) 2013-01-06 04:09:12 +00:00
Dale Weiler
d98cc564b1 Fixes and more documentation 2013-01-06 04:06:38 +00:00
Dale Weiler
44a7154f58 Add a notice 2013-01-06 03:52:37 +00:00
Dale Weiler
106db76b9d Use memcmp with strlen for correct_exists (it's a hell of a lot faster) 2013-01-06 03:34:56 +00:00
Dale Weiler
cc8558025b No more uninitialized 2013-01-06 03:33:21 +00:00
Dale Weiler
9841240aab Some more nicer loops 2013-01-06 03:29:55 +00:00
Dale Weiler
e2e4907b60 Nicer loops 2013-01-06 03:26:09 +00:00
Dale Weiler
7e87c61d78 Cleanups and documentation 2013-01-06 03:06:56 +00:00
Dale Weiler
294870c5ba Remove override macros 2013-01-06 02:41:15 +00:00
Dale Weiler
efecd160ca Remove an illegal mem_d 2013-01-06 02:40:36 +00:00
Dale Weiler
0fb089fbb7 Cleanup the pool system for correct.c. Use blubs correct_resize stuff. 2013-01-06 02:39:07 +00:00
Dale Weiler
682c43973e Don't use notices 2013-01-05 20:44:53 +00:00
Dale Weiler
726d163631 Better IRC hook 2013-01-05 20:43:47 +00:00
Dale Weiler
7a5bb20778 notifications 2013-01-05 20:39:50 +00:00
Dale Weiler
caa44e82e0 Add irc to travis 2013-01-05 20:39:17 +00:00
Dale Weiler
41a01c08e1 Add travis.yml 2013-01-05 20:31:17 +00:00
Wolfgang Bumiller
8bc9d4b427 Committing an evil allocator and a trie to speed up the correction stuff 2013-01-05 19:09:36 +01:00
Wolfgang Bumiller
b8d238d76b Merge branch 'master' of git://github.com/graphitemaster/gmqcc 2013-01-04 14:52:00 +01:00
Wolfgang Bumiller
0e3bb0e4f4 Get rid of correct_strndup and correct_concat altogether, reduces each generated edit to a single alloc 2013-01-04 14:50:50 +01:00
Dale Weiler
ec4cd0d258 Disable enhanced diagnostics as they're too slow. 2013-01-04 12:26:44 +00:00
Dale Weiler
793547a132 Implemented -f[no]enhanced-diagnostics, to enable/disable the usage of enhanced diagnostics. 2013-01-04 12:07:42 +00:00
Dale Weiler
5377835f1e Remove constant string literal for correction check, use parse_tokval of the current parser state instead. Accidently left it behind from debugging. 2013-01-04 11:58:27 +00:00
Dale Weiler
2d96b2a3ec Merge branch 'correct' 2013-01-04 11:56:07 +00:00
Dale Weiler
36d02d010e Got rid of all the memleaks. We can now merge with master. 2013-01-04 11:53:40 +00:00
Dale Weiler
18b9473cf8 Itegration of corrector. Seems to be some leaks in the score keeping for the probability system. 2013-01-04 11:44:25 +00:00
Dale Weiler
d97e032fcf Cleanups and add the corrector to the makefile. Starting integration with the parser. 2013-01-04 10:05:41 +00:00
Dale Weiler
7ef051f58a Fix all the memleaks in the corrector. Holy shit, the amount of hours I wasted trying to find out where I left out ONE little free. 2013-01-04 09:46:22 +00:00
Dale Weiler
ab64706cc3 Fix another two leaks 2013-01-03 21:38:07 +00:00
Dale Weiler
2189dd4b85 Remove some memory leaks in the corrector. There is still some memory leaks that are proving impossible to fix. 2013-01-03 21:25:35 +00:00
Dale Weiler
861987e13e Work on "did you mean? <ident>" support for errors. Using a three-part Bayes Theorem expression (language model, error model and control mechanisim). 2013-01-03 19:44:13 +00:00
Wolfgang Bumiller
9edae7fa0a Merge remote-tracking branch 'origin/pp-unary-numbers' 2013-01-03 14:58:02 +01:00
Wolfgang Bumiller
cf293bc669 handling the ast-destruction in computed goto 2013-01-03 13:21:11 +01:00
Dale Weiler
7d14fdf530 Merge branch 'master' of github.com:graphitemaster/gmqcc 2013-01-03 12:05:02 +00:00
Dale Weiler
9bda8f61f4 Add specialized diagnostics for when predefined macros are used and ftepp predefined macros are not enabled. 2013-01-03 12:04:32 +00:00
Wolfgang Bumiller
614fcb12f5 check for TYPE_NOEXPR in general when applying an operator 2013-01-03 12:56:26 +01:00
Wolfgang Bumiller
ae09831227 Introducing TYPE_NOEXPR so that these undefined labels cannot be used on the expression side of goto ternary expressions; ast_label now is TYPE_NOEXPR; we may consider setting ast_ifthen to that too unless we want ifthen to return a value... 2013-01-03 12:49:21 +01:00
Wolfgang Bumiller
e146fd121c parse_expression now takes a boolean flag on whether or not it should be creating ast_labels for undefined identifiers; creating the label later will pick it up and set its undefined flag to false 2013-01-03 12:46:33 +01:00
Dale Weiler
0ab15e9f22 Fix argument padding for win_fputs and alike. 2013-01-03 10:33:35 +00:00
Dale Weiler
a168c5efbe More error checking and proper unreferencing of ast nodes if expressions for computed goto fails. 2013-01-02 22:39:24 +00:00
Dale Weiler
c1734d1b27 Some error checking for computed goto. 2013-01-02 22:28:26 +00:00
Dale Weiler
c750828632 Fix the testsuite bug, and implemented QCFLAGS enviroment variable support for setting the compile flags (the .tmpl rules takes precedence). 2013-01-02 22:16:02 +00:00
Dale Weiler
a2f63aae33 Implemented __TIME__ for ftepp 2013-01-02 21:53:46 +00:00
Dale Weiler
908f6ded8a Implemented __DATE__ for ftepp 2013-01-02 21:51:22 +00:00
Dale Weiler
e08e4a9ce0 Remove "got" left behind from debugging. 2013-01-02 21:35:18 +00:00
Dale Weiler
a421d9a33b Implemented computed goto + added goto test for testsuite (tests both normal and computed goto statements). 2013-01-02 21:32:57 +00:00
Wolfgang Bumiller
6c076f99f6 lex->flags.preprocessing causes the lexer to parse the unary number if it is one 2013-01-02 17:38:24 +01:00
Dale Weiler
467a4740da Fix some issues 2013-01-02 16:34:55 +00:00
Wolfgang Bumiller
654eceb33b Allow unary minus in ftepp_if_value 2013-01-02 17:26:35 +01:00
Wolfgang Bumiller
0d839bd138 pragma code: signed correctness 2013-01-02 15:20:07 +01:00
Wolfgang Bumiller
558a091c08 remove ast.h-include from lexer.h to parser.c... 2013-01-02 15:08:02 +01:00
Wolfgang Bumiller
14593ce789 Makefile: ftepp.o: lexer.h 2013-01-02 15:05:52 +01:00
Wolfgang Bumiller
359ba5f728 lex.peek char->int 2013-01-02 15:03:20 +01:00
Wolfgang Bumiller
8331a2982d tests for __VA_ARGS__ 2013-01-02 14:16:42 +01:00
Wolfgang Bumiller
38a664ed72 __VA_ARGS__ support 2013-01-02 14:15:16 +01:00
Wolfgang Bumiller
3c212c8389 fix a leak: delete the output string of macro calls 2013-01-02 10:45:55 +01:00
Wolfgang Bumiller
dce7a0c72b update old_string on failure in ftepp_macro_expand to not segfault on a preprocessor-error inside recursive preprocessor calls 2013-01-02 10:44:39 +01:00
Wolfgang Bumiller
c7280fca52 when recursinve into macros copy the previous line number; fixes macros showing line 1 for each error 2013-01-02 10:35:00 +01:00
Dale Weiler
686394654f Implemented a optimized hash-set that can be used in various parts of the compiler (to get a little more speed). I intend this to replace the hackery that is code_genstring, and code_util_str_htgeth. 2013-01-01 07:59:04 +00:00
Dale Weiler
29db4a44ed Happy new years! 2013-01-01 05:08:55 +00:00
Dale Weiler
2f356f12e6 Fix util_vasprintf. 2012-12-31 18:50:57 +00:00
Dale Weiler
f4c3080824 Add todo about util_vasprintf (too lazy to fix right now) 2012-12-31 18:34:13 +00:00
Dale Weiler
1182ab55c5 Fix #include for <machine/endian.h> s/endiane/endian/ 2012-12-31 14:40:08 +00:00
Wolfgang Bumiller
2b1eaa6df3 Actually allocate a nil-vector for nil 2012-12-31 13:25:18 +01:00
Wolfgang Bumiller
5a5cb74db2 add codegen_output_type to ast_binary_codegen 2012-12-31 13:20:08 +01:00
Wolfgang Bumiller
0c673dfebb fix store op for nil as parameter 2012-12-31 13:19:34 +01:00
Wolfgang Bumiller
12d87fba1b Adding '&~=' to the -std=gmqcc operator list 2012-12-31 12:56:04 +01:00
Wolfgang Bumiller
0920cb6ec4 Another hardcoded -std=gmqcc option removed and added to the implied -std=gmqcc flags 2012-12-31 12:43:15 +01:00
Wolfgang Bumiller
0626bbef8e remove another hardcoded -std=gmqcc case 2012-12-31 12:40:09 +01:00
Wolfgang Bumiller
d8254cede0 -std=gmqcc now implies -Werror-missing-return-values; another hardcoded error removed 2012-12-31 12:37:47 +01:00
Wolfgang Bumiller
17951ac92c Just allow variable declarations in for-loop initializers in any standard... 2012-12-31 12:35:26 +01:00
Wolfgang Bumiller
d47da25b82 Changing -Wtoo-few-parameters to -Winvalid-parameter-count; removing hardcoded COMPILER_GMQCC code which makes invalid parameter counts an error and instead make -std=gmqcc imply -Werror-invalid-parameter-count 2012-12-31 12:29:25 +01:00
Wolfgang Bumiller
26d43e650f Adding some more internal-error messages where they were missing; fixed ast_ternary_codegen to use the ast_node's type instead of the ir generated ones to avoid erroring on TYPE_NIL 2012-12-31 12:08:47 +01:00
Wolfgang Bumiller
a170154927 nil in ternary, and fix ternary to honor -fcorrect-logic/-ftrue/false-empty-strings 2012-12-31 11:45:00 +01:00
Wolfgang Bumiller
2cf4b4e56d Explicitly allow 'return nil' 2012-12-31 11:39:00 +01:00
Wolfgang Bumiller
4d5153854b This should actually cover all nil cases 2012-12-31 11:34:29 +01:00
Wolfgang Bumiller
819ed10f29 nil check in paramter type checking 2012-12-31 11:30:02 +01:00
Wolfgang Bumiller
5bb9351a3f Allow assigning nil to a field 2012-12-31 11:23:49 +01:00
Wolfgang Bumiller
2637f6f824 gmqcc.ini.example: -Wparenthesis 2012-12-31 11:14:43 +01:00
Wolfgang Bumiller
f698e796d2 manpage: -Wparenthesis 2012-12-31 11:14:34 +01:00
Wolfgang Bumiller
3538b505da Activate -Wparenthesis by default 2012-12-31 11:14:24 +01:00
Wolfgang Bumiller
0c4806b4a0 Adding -Wparenthesis, fixing constant folding of && and || 2012-12-31 11:11:46 +01:00
Dale Weiler
d750d17be5 Fix evaluation order bug 2012-12-30 11:01:45 +00:00
Wolfgang Bumiller
5a013c5b89 Do we REALLY need to listen to splint? 2012-12-30 11:59:29 +01:00
Wolfgang Bumiller
d9282ed988 Clean up trailing whitespaces 2012-12-30 11:03:59 +01:00
Dale Weiler
af3ba03a5b Merge branch 'master' of github.com:graphitemaster/gmqcc 2012-12-30 09:59:32 +00:00
Dale Weiler
46374e94ca Add support for user defined messages for [[deprecated]] generalized attribute 2012-12-30 09:58:52 +00:00
Wolfgang Bumiller
048ef3e796 fix: ftepp_delete needs to ftepp_flush to not cause a leak on errors 2012-12-30 10:37:15 +01:00
Dale Weiler
921877e8a4 Implement [[deprecated]] general attribute, will mark functions as deprecated. Making calls to functions marked as such will trigger a compiler warning. Enabled by default. 2012-12-30 06:43:07 +00:00
Wolfgang Bumiller
755ee5462f Properly support globals initialized to nil 2012-12-29 21:15:59 +01:00
Wolfgang Bumiller
432a29e4d9 improvie/fix \{x...} char parsing 2012-12-29 19:11:06 +01:00
Wolfgang Bumiller
d961cfb855 gmqcc.ini.example: DIFFERENT_QUALIFIERS, DIFFERENT_ATTRIBUTES 2012-12-29 17:41:20 +01:00
Wolfgang Bumiller
64ccc88a9e manpage: -Wdifferent-qualifiers -Wdifferent-attributes 2012-12-29 17:41:20 +01:00
Wolfgang Bumiller
8bdd060112 -Wdifferent-qualifiers, -Wdifferent-attributes 2012-12-29 17:41:20 +01:00
Dale Weiler
d700bb66b2 Merge branch 'master' of github.com:graphitemaster/gmqcc 2012-12-29 14:42:17 +00:00
Dale Weiler
842b0a1271 Fix uninitialized-global 2012-12-29 14:41:47 +00:00
Wolfgang Bumiller
33be9d4559 Don't allow code like: v * '0 1 0' = 3; to actually work... 2012-12-29 15:13:54 +01:00
Wolfgang Bumiller
fda4f4d027 gmqcc.ini.example: VECTOR_COMPONENTS 2012-12-29 15:13:28 +01:00
Wolfgang Bumiller
3d67b29a7b manpage: -Ovector-components 2012-12-29 15:10:04 +01:00
Wolfgang Bumiller
73bc4cc3e4 -Ovector-components 2012-12-29 15:05:04 +01:00
Dale Weiler
c0eca32b92 Merge pull request #80 from matthiaskrgr/master
add .gitignore file
2012-12-28 19:10:06 -08:00
matthiaskrgr
3567abbd64 Merge remote-tracking branch 'upstream/master' 2012-12-28 23:33:43 +01:00
matthiaskrgr
82f37c87fc add .gitignore file 2012-12-28 23:32:33 +01:00
Wolfgang Bumiller
ded1ab3da1 Typo... 2012-12-28 21:05:04 +01:00
Wolfgang Bumiller
2ac2827256 Updating gmqcc.ini.example 2012-12-28 21:04:14 +01:00
Wolfgang Bumiller
e37adb8c47 GMQCC_GITINFO 2012-12-28 20:39:30 +01:00
Wolfgang Bumiller
14e954284e more general qualifier/attribute parsing, added not-yet-used AST_FLAG_INLINE and [[inline]] 2012-12-28 19:46:28 +01:00
Wolfgang Bumiller
898e00f5b4 manpage: -Wuninitialized-constant -Wuninitialized-global 2012-12-28 19:11:29 +01:00
Wolfgang Bumiller
9315577be6 noref testcase must use -Wno-uninitialized-global 2012-12-28 19:09:06 +01:00
Wolfgang Bumiller
47baca22d9 -Wuninitialized-const, -Wuninitialized-global 2012-12-28 19:07:43 +01:00
Wolfgang Bumiller
dae1291b37 manpage: -Wreserved-names, -funtyped-nil, -fpermissive 2012-12-28 18:27:34 +01:00
Wolfgang Bumiller
77d454725a -Wreserved-names, -fpermissive allows local variables named 'nil' to be created even with -funtyped-nil, they supersede the global untyped 'nil' 2012-12-28 18:22:09 +01:00
Wolfgang Bumiller
2e0216b7c6 'nil' global with -funtyped-nil 2012-12-28 18:16:19 +01:00
Wolfgang Bumiller
40b2a26e89 TYPE_NIL, builder->nil, ast_value_codegen for TYPE_NIL 2012-12-28 18:05:28 +01:00
Dale Weiler
3f88b5fa14 Fix teh paren! 2012-12-28 15:19:19 +00:00
Dale Weiler
8f34e9fa37 added util_vasprintf/util_asprintf .. so we can stop assuming a certian static array size for formatting strings ... I expect to see full migration to this before the next release for protection of over/under flows. As well as identifers >= 1024 bytes :) 2012-12-28 15:02:53 +00:00
Dale Weiler
2ddb49f546 memleak 2012-12-28 14:47:27 +00:00
Dale Weiler
d6e7d8ca75 s/\t/ /g - utf8.c 2012-12-28 12:57:41 +00:00
Dale Weiler
cb12460b95 Fix another Blub bug .. learn to use comments properly :P 2012-12-28 12:54:20 +00:00
Dale Weiler
3688dab048 Fix a very possible bug 2012-12-28 12:50:37 +00:00
Dale Weiler
a6f51264fd Fixed another possible implementation specific bug thanks to this progressive splint idea :) 2012-12-28 12:43:08 +00:00
Dale Weiler
e2f9aa5027 Fix another warning 2012-12-28 12:40:00 +00:00
Dale Weiler
e4b8df2dc6 Fix another warning 2012-12-28 12:36:15 +00:00
Dale Weiler
6935561b41 Fix one warning 2012-12-28 12:33:10 +00:00
Dale Weiler
f58b4a6cd9 Added splint.sh (a progressive way to fix some possible bugs) 2012-12-28 12:29:46 +00:00
Wolfgang Bumiller
f1fa8f6055 So why doesn't any popular compiler complain about this 2012-12-28 11:50:03 +01:00
Wolfgang Bumiller
126b0fe324 ... This... I'll have to git rewrite-history at some point 2012-12-28 11:43:17 +01:00
Dale Weiler
566dda6ad7 Working on getting gmqcc to work when compiled with tcc 2012-12-28 09:30:01 +00:00
Dale Weiler
a7724bffaa Reorder operands 2012-12-28 09:06:04 +00:00
Dale Weiler
dbb7a87fd8 Quoting of strings is forbid in some "make" implementations 2012-12-28 09:05:14 +00:00
Dale Weiler
cfa7119fdb Got it working on arm :) 2012-12-28 08:59:41 +00:00
Dale Weiler
ba25970f27 Always use -fsigned-char .. The compiler I was using had -funsigned-char by default on ARM (which was breaking everything ...) try it .. add -funsigned-char and run the test-suite (only 2 out of all the tests actually pass, and it's by fluke) 2012-12-28 08:52:13 +00:00
Wolfgang Bumiller
fb30f11bc1 manpage: -floop-labels 2012-12-28 00:21:59 +01:00
Wolfgang Bumiller
03c079cb8c Some default options for -std=gmqcc including -floop-labels 2012-12-28 00:21:53 +01:00
Wolfgang Bumiller
a60d0182db finish parsing of labeled loops; ast support added 2012-12-28 00:04:09 +01:00
Wolfgang Bumiller
c702970a0e distinguish between break/continue levels in the parser 2012-12-27 23:52:57 +01:00
Wolfgang Bumiller
ebb7cb2ae3 parsing of loop labels 2012-12-27 23:43:20 +01:00
Wolfgang Bumiller
c6e7e80f23 there's no -f flag named overlap-locals... removed the opts.def entry 2012-12-27 22:18:58 +01:00
Wolfgang Bumiller
4187332bb1 Merge pull request #77 from matthiaskrgr/PKGBUILD
PKGBUILDs: note myself as contributor.
2012-12-27 11:10:10 -08:00
matthiaskrgr
b1e0687373 PKGBUILDs: note myself as contributor. 2012-12-27 20:07:58 +01:00
Wolfgang Bumiller
8624af879a bumping arch/release PKGBUILD to 0.2.2 2012-12-27 14:48:52 +01:00
Wolfgang Bumiller
517b6fed81 Another bool->int fix; now clang-compiled gmqcc actually works... 2012-12-27 14:33:58 +01:00
Wolfgang Bumiller
24752b5fd1 manpage: -fbail-on-werror 2012-12-27 12:48:36 +01:00
Wolfgang Bumiller
5cfd97c344 -fbail-on-werror option 2012-12-27 12:46:36 +01:00
Wolfgang Bumiller
24f3098418 fix: when there are no additional temps the first one allocated slot's size was counted twice resulting in some additional unused globals 2012-12-27 11:46:08 +01:00
Wolfgang Bumiller
babdebee79 Merge pull request #75 from matthiaskrgr/master
mention PKGBUILDs in INSTALL file, fix typo in manpage
2012-12-27 02:06:04 -08:00
Wolfgang Bumiller
3f8f2b3f48 manpage: -Oglobal-temps 2012-12-26 23:20:49 +01:00
Wolfgang Bumiller
d4483bfda6 -Oglobal-temps 2012-12-26 23:18:45 +01:00
Wolfgang Bumiller
93dbfa18f1 fix -v option parsing in qcvm 2012-12-26 22:49:50 +01:00
Wolfgang Bumiller
1cca992a8e factoring out temp-slot-assignment and using it for the declared locals too, makes -Olocal-temps more effective 2012-12-26 22:09:54 +01:00
matthiaskrgr
3d9760473b manpage: gmqcc: fix typo 2012-12-26 22:03:08 +01:00
matthiaskrgr
00fc3a5686 INSTALL: mention ArchLinux PKGBUILDs. 2012-12-26 21:57:26 +01:00
Wolfgang Bumiller
b42328dbc6 Switch over to LONGBIT 2012-12-26 21:39:00 +01:00
Wolfgang Bumiller
24161543d9 Merge pull request #74 from matthiaskrgr/PKGBUILD
add arch PKGBUILDs for git and release build.
2012-12-26 12:31:25 -08:00
matthiaskrgr
1f867e3920 PKGBUILD: formatting 2012-12-26 20:21:41 +01:00
matthiaskrgr
1ac110d426 add PKGBUILD for release build. 2012-12-26 20:17:29 +01:00
matthiaskrgr
56568d24ff PKGBUILD: license is MIT 2012-12-26 20:13:07 +01:00
Wolfgang Bumiller
de3d8747f7 fix uninitialized warnings in ir.c 2012-12-26 20:07:57 +01:00
matthiaskrgr
9bf6b2e1bd PKGBUILD: install custom license file. 2012-12-26 20:07:51 +01:00
matthiaskrgr
c3a867f0c2 PKGBUILD: license is not GPL actually 2012-12-26 20:03:17 +01:00
Wolfgang Bumiller
f832b86dcd Fixing uninitialized warnings in parser.c 2012-12-26 20:00:17 +01:00
Wolfgang Bumiller
33c7707f56 adding -fno-strict-aliasing 2012-12-26 19:58:53 +01:00
matthiaskrgr
728a8e975a add PKGBUILD for git build. 2012-12-26 19:58:40 +01:00
Wolfgang Bumiller
365fe400b0 manpage: -dump, -dumpfin 2012-12-26 19:37:55 +01:00
Wolfgang Bumiller
b32bd22af3 Merge pull request #73 from matthiaskrgr/master
fix some typos in todo file
2012-12-26 10:21:31 -08:00
matthiaskrgr
a2504f6455 TODO: fix typos 2012-12-26 19:15:40 +01:00
Wolfgang Bumiller
700628b2cb counters for -Ocall-stores because we all love numbers 2012-12-26 19:11:26 +01:00
Wolfgang Bumiller
14889897da Don't copy return values away from OFS_RETURN if they don't get locked. 2012-12-26 18:33:16 +01:00
Wolfgang Bumiller
456e80a7d5 manpage: -Ovoid-return 2012-12-26 10:28:01 +01:00
Wolfgang Bumiller
5779fea9b4 manpage: added -v to the qcvm manpage 2012-12-26 10:26:04 +01:00
Wolfgang Bumiller
af5b552a7f -Ovoid-return - the last INSTR_RETURN of a void functions is replaced by INSTR_DONE to reduce the instruction count 2012-12-26 10:24:33 +01:00
Wolfgang Bumiller
47f7611ec9 verbose switches for the qcvm; makes -printfuns find the instruction-count of a function and print that too 2012-12-26 10:23:45 +01:00
Wolfgang Bumiller
aee7bf0de0 Actually generate the vector member ir_values in ir_function_finalize, since ir_builder_gen_global is too late / happens after life ranges; this should fix -Ooverlap-locals 2012-12-25 23:51:29 +01:00
Wolfgang Bumiller
1172e2b8cc manpage: -Ocall-stores 2012-12-25 23:28:09 +01:00
Wolfgang Bumiller
a7c3ef3e22 -Ocall-stores as part of -O1: instead of having CALL instructions issue STOREs for every parameter, use the newly introduced 'lock' flag to make the operations generating the call's parameters generate them right into the OFS_PARM if there's no interfering CALL in between 2012-12-25 23:25:59 +01:00
Wolfgang Bumiller
d7de5cb5ff do the locking before processing the call-reads otherwise all the call's parameters get locked as well 2012-12-25 23:24:31 +01:00
Wolfgang Bumiller
710f580e15 liferange calc now sets the 'locked' flag on values when reaching a CALL 2012-12-25 21:03:26 +01:00
Wolfgang Bumiller
35ba2dcaf9 The very aggressive -Ooverlap-strings 2012-12-25 20:38:05 +01:00
Wolfgang Bumiller
307746dc35 Ensure that the members[] array is filled for vector types so the liferange function can use all of them 2012-12-24 12:52:15 +01:00
Wolfgang Bumiller
fcdff3180a Tests for the previous vector-liferange change 2012-12-24 12:43:16 +01:00
Wolfgang Bumiller
dc691c8a6e Now this should deal with vector life ranges more correctly. 2012-12-24 12:43:05 +01:00
Wolfgang Bumiller
da927b5d41 print an error when static is used in global scope - this is currently not being handled as expected 2012-12-24 11:38:33 +01:00
Wolfgang Bumiller
2b468cb0ee Added the 'static' keyword.
Implements #71
2012-12-24 11:30:58 +01:00
Wolfgang Bumiller
c3dfe2c61c manpage: -q, --quiet 2012-12-24 11:03:34 +01:00
Wolfgang Bumiller
55dc45ec3e manpage: -fftepp-predefs 2012-12-24 11:01:24 +01:00
Wolfgang Bumiller
2d66431af4 -q, --quiet option 2012-12-24 10:53:51 +01:00
Dale Weiler
f811a4e876 one too many zeros 2012-12-24 08:19:57 +00:00
Dale Weiler
fa155f8a42 Added my awesome MT1997 PRNG, and use it instead of stdio's rand()/srand() .. which are implementation specific .. and simply unsafe (for example one of the compilers at work simply has it's standard library implementation of rand() return 0 always (which is perfectly conformant)). 2012-12-24 01:43:27 +00:00
Dale Weiler
0a57c408c0 Added ftepp predefs flag (ability to turn on/off predefs) disabled by default (even with -ftepp), enabled with -E, to enable use -fftepp-predefs. 2012-12-24 00:21:55 +00:00
Dale Weiler
bd12429cd0 Implemented __FILE__, __LINE__, __RANDOM__, __RANDOM_LAST__, __COUNTER__ and __COUNTER_LAST__ as predefined macros. __FUNCTION__ is not implemented yet due to the overall complexity in making it constant. 2012-12-24 00:12:24 +00:00
Wolfgang Bumiller
6a93b72ea5 -Ostrip-constant-names 2012-12-23 22:58:46 +01:00
Wolfgang Bumiller
d3568627e9 code_genstring now caches strings, no need for code_cachestring 2012-12-23 21:42:00 +01:00
Wolfgang Bumiller
6a60368a1b -Olocaltemps -> -Olocal-temps for consistency; added manpage entry; removed leftover manpage entry for -foverlap-locals; -Olocal-temps moved from -O1 to -O3 due to stability concerns 2012-12-23 21:39:23 +01:00
Wolfgang Bumiller
1ac913877e revert 3ef30e850d 2012-12-23 21:34:04 +01:00
Wolfgang Bumiller
63928e231c Remove ir_block_create_{add,sub,mul,div}, they're not used; STOREP instructions don't themselves to their target pointer's 'writes' list, but 'reads' list instead 2012-12-23 21:29:15 +01:00
Wolfgang Bumiller
435dee935b Start instruction numbering at 1 and make parameters live at 0 2012-12-23 21:20:16 +01:00
Wolfgang Bumiller
3ef30e850d Don't store off CALL results if they're never read 2012-12-23 21:11:56 +01:00
Wolfgang Bumiller
cff74493a7 Even safer vector macros 2012-12-23 20:55:15 +01:00
Wolfgang Bumiller
fb5a65c51a Life Ranges: First deal with all writes, then with all reads, since writes will remove values from the Living set 2012-12-23 20:50:21 +01:00
Wolfgang Bumiller
46c2fe2443 Fixing vector macros 2012-12-23 20:49:50 +01:00
Wolfgang Bumiller
890ca3c782 added -disasm-func to the qcvm 2012-12-23 20:45:43 +01:00
Wolfgang Bumiller
ee7051c5a4 strcmp and strncmp builtins 2012-12-23 19:22:38 +01:00
Wolfgang Bumiller
275b6f777a Adding strcat builtin to qcvm 2012-12-23 19:06:29 +01:00
Wolfgang Bumiller
3c9283cc41 don't optimize out NOT_S instructions for COND 2012-12-23 17:51:01 +01:00
Wolfgang Bumiller
2967dba7ad manpage: remove the MUL_FV/VF section, it wouldn't be legal code anyway 2012-12-23 17:50:44 +01:00
Wolfgang Bumiller
4f06daf7d0 manpage: optimization section 2012-12-23 17:46:40 +01:00
Wolfgang Bumiller
c91b457054 Mask overlap-locals by -Ooverlap-locals, and count (the amount of overlapped functions) 2012-12-23 17:40:56 +01:00
Wolfgang Bumiller
b8c61f2f88 Try generating the function-locals in a later pass; with the option to overlap them. 2012-12-23 17:32:39 +01:00
Wolfgang Bumiller
67bc99223d Fix a nasty bug in the executor; and make null-strings be shown as (null) in the trace output 2012-12-23 17:32:14 +01:00
Wolfgang Bumiller
eabe23cc24 Add -Ooverlap-locals to -O3 2012-12-23 16:31:21 +01:00
Wolfgang Bumiller
88a6437840 remember the maximum amount of required function-locals 2012-12-23 16:31:01 +01:00
Wolfgang Bumiller
7998a98818 ir_function now has a flags field - flags are: IR_FLAG_HAS_{ARRAYS,UNINITIALIZED,GOTO} 2012-12-23 16:21:38 +01:00
Wolfgang Bumiller
2382fdee50 util_swa_* + GMQCC_INLINE 2012-12-23 13:11:20 +01:00
Wolfgang Bumiller
1731a29c51 Don't generate defs for locals or parameters unless using -g 2012-12-23 12:22:27 +01:00
Wolfgang Bumiller
84fcd95d4e utf8lib.c -> utf8.c - I hope windows 8 allows this filename :P 2012-12-23 10:44:03 +01:00
Wolfgang Bumiller
95965e9ff6 license header 2012-12-23 10:35:21 +01:00
Wolfgang Bumiller
e72d141ec4 Uchar -> uchar_t for consistency 2012-12-23 10:34:29 +01:00
Wolfgang Bumiller
3e6c98d65d manpage: -futf8 2012-12-23 10:23:42 +01:00
Wolfgang Bumiller
041f8a86d7 utf8 tests 2012-12-23 10:23:42 +01:00
Wolfgang Bumiller
2164afb8cf Better error message for -futf8 2012-12-23 10:23:42 +01:00
Wolfgang Bumiller
ac0ca3de81 fix and speed up u8_analyze for our purposes 2012-12-23 10:23:42 +01:00
Wolfgang Bumiller
a707440e52 -futf8 implementation 2012-12-23 10:23:42 +01:00
Wolfgang Bumiller
aec2284f45 u8_analyze: return false on any invalid character, we do not allow invalid/overlong characters in code at all 2012-12-23 10:23:41 +01:00
Wolfgang Bumiller
fe3d8e44e6 Importing utf8lib 2012-12-23 10:23:41 +01:00
Dale Weiler
da49a40b96 Bump 0.2 -> 0.3 2012-12-23 09:18:17 +00:00
Wolfgang Bumiller
55117912ab Don't generate vector defs if the vector's name starts with a # because that's an 'IMMEDIATE' 2012-12-23 10:14:25 +01:00
Dale Weiler
d51a6ab3db Whitespace 2012-12-23 09:10:31 +00:00
Dale Weiler
5bc815c63f Revert "Whitespace fixes"
This reverts commit 4580dcf1ea.
2012-12-23 09:10:07 +00:00
Dale Weiler
4580dcf1ea Whitespace fixes 2012-12-23 08:42:53 +00:00
Dale Weiler
e0ea101838 Lies ... damned lies, all lies I tell you ... copy-pasta lies! 2012-12-23 08:17:05 +00:00
Dale Weiler
f598fbeaea Actually fix the segfault this time 2012-12-23 08:08:05 +00:00
Dale Weiler
3b27107676 con_default_out for opts.pp_only (removes recently added TODO .. and fixes a segfault) 2012-12-23 07:57:06 +00:00
Dale Weiler
c3964cf29d Make compiler and virtual-machine compile as C++ code, also removed gmqcc_voidptr hack. 2012-12-23 07:51:19 +00:00
Dale Weiler
d35d953a91 Remove parser_compile_string_len, and make parser_compiler_string take an additional length argument. 2012-12-23 07:22:15 +00:00
Dale Weiler
6951f3dfcc fix comments 2012-12-23 07:19:49 +00:00
Dale Weiler
4224ac5ca0 fixes, and removed a #pragma warning(disable ...) in MSVC .. thanks to the FILE wrapping interface. 2012-12-23 07:18:00 +00:00
Dale Weiler
d18656c2dc Cleanup flexible array / vector system 2012-12-23 07:14:16 +00:00
Dale Weiler
6bc29a1601 Merge branch 'master' of github.com:graphitemaster/gmqcc 2012-12-23 06:06:57 +00:00
Dale Weiler
13003bf6af Wrapper around FILE to take advantage of MSVC "secure" CRT. We don't actually defend bounds checks (we just hack in the few ones to silent MSVC .. and to pass WinRT "native code" rules) 2012-12-23 06:05:22 +00:00
Wolfgang Bumiller
9d54ea6b0c More stuff for qcvm -info 2012-12-22 23:30:52 +01:00
Wolfgang Bumiller
aef7ff87fc Makefile: lexer.o depends on lexer.h 2012-12-22 20:43:59 +01:00
Wolfgang Bumiller
77639bb21d guard ]] with lex->flags.noops 2012-12-22 20:41:02 +01:00
Wolfgang Bumiller
eb952f1199 fix -fshort-logic to cast to true boolean values 2012-12-22 20:05:15 +01:00
Wolfgang Bumiller
96ddc217da manpage: capital section headings, updated -fcorrect-logic description, added -Wunknown-attribute 2012-12-22 18:19:51 +01:00
Wolfgang Bumiller
e8cd9411b0 -Wunknown-attribute; and don't error on unknown attributes 2012-12-22 18:16:41 +01:00
Wolfgang Bumiller
7cf0ba5aa8 'noreturn' is now an attribute and parsed as [[noreturn]] 2012-12-22 18:09:56 +01:00
Wolfgang Bumiller
b38b3b08bd properly fill the token string for TOKEN_ATTRIBUTE_* 2012-12-22 18:09:17 +01:00
Wolfgang Bumiller
2c2bfab8bc is now no keyword anymore 2012-12-22 18:03:43 +01:00
Wolfgang Bumiller
26a80e0868 Lexer: [[ and ]] are now TOKEN_ATTRIBUTE_{OPEN,CLOSE} 2012-12-22 18:00:51 +01:00
Wolfgang Bumiller
949cd9bb06 Test cases for -fcorrect-logic 2012-12-22 17:55:55 +01:00
Wolfgang Bumiller
d858237010 Adding truth-flags testsuite for strings 2012-12-22 17:36:06 +01:00
Wolfgang Bumiller
1f070b740f -ffalse-empty-strings in && and || 2012-12-22 17:31:31 +01:00
Wolfgang Bumiller
0fe71af4ce -fcorrect-logic now handles only vectors 2012-12-22 17:18:37 +01:00
Wolfgang Bumiller
7efc3a4c21 Error when using both -ffalse-empty-strings and -ftrue-empty-strings 2012-12-22 16:50:09 +01:00
Wolfgang Bumiller
8459895fdd Fix a bug with -fperl-logic and -fcorrect-logic 2012-12-22 16:25:19 +01:00
Wolfgang Bumiller
b4e38a8fed Fix: ast_value.cvq must be an int, not a bool;
Fixes #62
2012-12-22 12:30:20 +01:00
Dale Weiler
fa401b6f56 Cleanups and make compile with clang again with no warnings. 2012-12-22 08:22:50 +00:00
Dale Weiler
7d2a2f2ade cleanups and fixes that cppcheck found 2012-12-22 08:07:54 +00:00
Dale Weiler
322fbaf389 More cleanups 2012-12-22 07:54:14 +00:00
Dale Weiler
9ba655e74c Remove more unused code 2012-12-22 07:46:43 +00:00
Dale Weiler
313e442107 Make gmqcc binary smaller (by removing some useless code) 2012-12-22 07:40:17 +00:00
Dale Weiler
ed11fe130b Stick to one hash function (no platform optimized versions) 2012-12-22 07:33:11 +00:00
Dale Weiler
7753e19ba8 Cleanups 2012-12-22 07:24:25 +00:00
Dale Weiler
88fee02228 Windows stuff for visual studio now offical works with exception to colorized output to cmd (which actually should work). As well as the testsuite which lacks implementations of task_popen/task_pclose. 2012-12-21 06:16:08 -05:00
Wolfgang Bumiller
43cf6e7cba -Opeephole now also reduces CALL stores 2012-12-21 11:42:23 +01:00
Wolfgang Bumiller
48ba6a6189 Rename ir_function_pass_tailcall->tailrecursion; Take -fadjust-vector-fields into account when storing field type return-values from functions 2012-12-21 11:33:44 +01:00
Wolfgang Bumiller
06ea71d5be manpage: -Wcpp; added a FILES section which contains gmqcc.ini.example - we should install this to some DATADIR in the install make target 2012-12-21 11:02:36 +01:00
Dale Weiler
c9e3c29a25 testsuite compiles on windows now (but doesn't work). Still need to implement bidirectional piping on stdout/stderr/stdin.. Which for some reason is incredibly stupidly complicated on windows. You need to setup SECURITY_ATTRIBUTES for each handle, do crazy handle duplication, and forking via CreateThread. Meanwhile the whole "concept" of threading is entierly broken in fundamental design on windows, which means you constantly need to store the current process handles for backup, and "inherit" from child process. It's just stupid, provide unix pipes via close/open and dup. Like normal people (they're simple and sane). 2012-12-21 01:59:34 -05:00
Dale Weiler
3c003bc168 Get gmqcc/qcvm compiling on windows again. Plus work in progress support for the testsuite on windows (does not compile yet). 2012-12-21 01:00:51 -05:00
Dale Weiler
0be55824d4 Implemented preprocessing error directive tests (should fail) 2012-12-21 04:48:01 +00:00
Dale Weiler
0e40ef172a Document ini.example 2012-12-21 04:01:47 +00:00
Dale Weiler
bf53f82d16 Update ini.example (added UNREACHABLE_CODE, and CPP) as warning options 2012-12-21 03:14:31 +00:00
Dale Weiler
f78ab9061b added -Wcpp (for turning off cpp warnings defined with #warning like GCC/clang/pathscale .. no more [-Wunused-variable]) 2012-12-21 03:12:58 +00:00
Dale Weiler
36a90bb866 Implemented #warning and #error preprocessor directives, they're functionally equivalent to CPPs (supporting both string constant and non-string constant versions). Warnings however are printed with a [-Wunused-variable] which isn't correct (TODO: allow systematic changes of -W paramaters in relation to warning fields for preprocessor directives. 2012-12-21 03:08:21 +00:00
Dale Weiler
c7a62970a6 Merge branch 'master' of github.com:graphitemaster/gmqcc 2012-12-20 23:07:33 +00:00
Dale Weiler
e1f0e40341 Implemented roboust compile-time endianess check. 2012-12-20 23:07:06 +00:00
Wolfgang Bumiller
0bbc8a3350 Remove old tempalloc code; disable -Olocaltemps for now 2012-12-20 23:52:54 +01:00
Wolfgang Bumiller
e38bdecd21 Be more correct with sizes; use a better local-alloc strategy 2012-12-20 23:48:41 +01:00
Wolfgang Bumiller
5375400e85 minor: fix ast_function_label 2012-12-20 23:27:23 +01:00
Wolfgang Bumiller
1d3fdea432 Fix util_endianswap; and endianswap the LNO data as well 2012-12-20 22:03:51 +01:00
Wolfgang Bumiller
8d86d7d1c1 Don't check for is_return but for final at the end of a function so that if 'goto' is the last expression we don't try to append a return 2012-12-20 21:05:29 +01:00
Wolfgang Bumiller
93341dd009 *sigh* 2012-12-20 20:57:05 +01:00
Wolfgang Bumiller
a6547a15f3 no need to check the array, the 2nd NOT is a NOT_F 2012-12-20 20:56:49 +01:00
Wolfgang Bumiller
8dc6696957 manpage: -fcorrect-logic, -ftrue-empty-strings, -ffalse-empty-strings 2012-12-20 20:56:08 +01:00
Wolfgang Bumiller
ccbccad994 fix -fcorrect-logic to use double-not instead of a single one - wow that was a bad one 2012-12-20 20:55:56 +01:00
Wolfgang Bumiller
712be84bba Testcases for -ftrue-empty-strings and -ffalse-empty-strings 2012-12-20 20:43:58 +01:00
Wolfgang Bumiller
68c4070f62 Fix the -fcorrect-logic condition 2012-12-20 20:40:59 +01:00
Wolfgang Bumiller
0988b731b7 Fix -fcorrect-logic 2012-12-20 20:33:05 +01:00
Wolfgang Bumiller
b595ec03f8 fix a leak in the local-allocator 2012-12-20 20:26:54 +01:00
Wolfgang Bumiller
98b6772db9 Fix a leak: free code_linenums 2012-12-20 20:26:14 +01:00
Wolfgang Bumiller
4f9c7861ec For loops may have an empty condition - don't try processing a NULL 2012-12-20 20:23:35 +01:00
Wolfgang Bumiller
a985a5cab1 while/for/do now all use process_condition, ast_loop got 2 new parameters for more efficient translation 2012-12-20 20:22:31 +01:00
Wolfgang Bumiller
d72cb42b08 process_condition function used by parse_if - need to still add it to loops 2012-12-20 19:51:30 +01:00
Wolfgang Bumiller
db577fdf17 -ftrue-empty-strings now changes type_not_instr[TYPE_STRING] to INSTR_NOT_F 2012-12-20 19:32:57 +01:00
Wolfgang Bumiller
34063108a6 since unary not doesn't fold these, remove them from immediate_is_true 2012-12-20 19:19:12 +01:00
Wolfgang Bumiller
4319922b3c introducing an immediate_is_true which follows the new -f flags on strings and vector truthfulness, used in logic-op constant folding; const folding now disabled for functions-constants on NOT because it's stupid 2012-12-20 19:18:22 +01:00
Wolfgang Bumiller
6b9eff19f1 unary not now uses NOT_F with -ftrue-empty-strings 2012-12-20 19:04:56 +01:00
Wolfgang Bumiller
b85441d6af Making logical 'and' and 'or' use NOT_ in -fcorrect-logic for both operands normally, but only for the first with -fperl-logic 2012-12-20 19:00:23 +01:00
Wolfgang Bumiller
d5cfe74d5d Adding -fcorrect-logic, -ftrue-empty-strings, -ffalse-empty-strings flags; not used yet 2012-12-20 18:59:05 +01:00
200 changed files with 27582 additions and 17515 deletions

15
.gitignore vendored Normal file
View file

@ -0,0 +1,15 @@
*.o
*.d
*.orig
*.rej
*.patch
*.diff
*.exe
gmqcc
gmqpak
qcvm
testsuite
build/
.idea/

13
AUTHORS
View file

@ -1,3 +1,10 @@
GMQCC brought to you by:
Dale Weiler
Wolfgang Bumiller
Authors:
Dale `graphitemaster` Weiler - Charismatic Visionary / Programmer
Wolfgang `Blub\w` Bumiller - Main Programmer
Thanks to:
Forest `LordHavoc` Hale - Technical support and assistance
Rudolf `divVerent` Polzer - Technical support and assistance
Matthias `matthiaskrgr` Krüger - Miscellaneous assistance
Samual `Samual` Lenks - Preprocessor assistance
Igor `ignatenkobrain` Gnatenko - Fedora packages

35
CMakeLists.txt Normal file
View file

@ -0,0 +1,35 @@
cmake_minimum_required(VERSION 2.8)
project(gmqcc)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
set(SOURCE_FILES
algo.h
ast.cpp ast.h
code.cpp
conout.cpp
fold.cpp fold.h
ftepp.cpp
gmqcc.h
intrin.cpp intrin.h
ir.cpp
ir.h
lexer.cpp lexer.h
opts.cpp
parser.cpp parser.h
stat.cpp
utf8.cpp
util.cpp)
add_library(gmqcclib ${SOURCE_FILES})
add_executable(gmqcc main.cpp)
target_link_libraries(gmqcc gmqcclib)
add_executable(testsuite test.cpp)
target_link_libraries(testsuite gmqcclib)
add_executable(qcvm exec.cpp)
target_link_libraries(qcvm gmqcclib)

39
INSTALL
View file

@ -1,39 +0,0 @@
Installing gmqcc
1. Prerequisites
- A C-Compiler such as gcc or clang
- GNU Make. This document will assume GNU-Make to be executed via
`make'. On BSD systems you probably have to use `gmake' instead.
2. Compilation
Run the GNU make program `make' or `gmake'.
make
If no error appears, the following binary files will have been
created:
- gmqcc
- qcvm
3. Installation
The `install' target will install the 2 binaries to /usr/local/bin
by default.
The Makefile honors the following variables:
- DESTDIR: The installation directory root.
- PREFIX: The installation prefix, default: /usr/local
- BINDIR: Directory for binary executables,
deafult: $PREFIX/bin
To install to /usr/local run:
make install
To install to /usr run:
make PREFIX=/usr install
To install to a package-staging directory such as $pkgdir when
writing an ArchLinux PKGBUILD file:
make DESTDIR=$pkgdir install

View file

@ -1,4 +1,4 @@
Copyright (C) 2012
Copyright (C) 2012, 2013, 2014, 2015
Dale Weiler
Wolfgang Bumiller

276
Makefile
View file

@ -1,104 +1,204 @@
DESTDIR :=
PREFIX := /usr/local
BINDIR := $(PREFIX)/bin
DATADIR := $(PREFIX)/share
MANDIR := $(DATADIR)/man
# Compilation options:
# * LTO - Link time optimization [default=0]
# * ASAN - Address sanitizer [default=0]
# * UBSAN - Undefined behavior sanitizer [default=0]
# * DEBUG - Debug build [default=0]
# * UNUSED - Remove unused references [default=1]
# * SRCDIR - Out of tree builds [default=./]
LTO ?= 0
ASAN ?= 0
UBSAN ?= 0
DEBUG ?= 0
UNUSED ?= 1
SRCDIR ?= ./
UNAME ?= $(shell uname)
CYGWIN = $(findstring CYGWIN, $(UNAME))
MINGW = $(findstring MINGW32, $(UNAME))
CC ?= clang
CFLAGS += -Wall -Wextra -I. -pedantic-errors
#turn on tons of warnings if clang is present
# but also turn off the STUPID ONES
ifeq ($(CC), clang)
CFLAGS += \
-Weverything \
-Wno-padded \
-Wno-format-nonliteral \
-Wno-disabled-macro-expansion \
-Wno-conversion \
-Wno-missing-prototypes
endif
ifeq ($(track), no)
CFLAGS += -DNOTRACK
endif
OBJ_D = util.o code.o ast.o ir.o conout.o ftepp.o opts.o
OBJ_T = test.o util.o conout.o
OBJ_C = main.o lexer.o parser.o
OBJ_X = exec-standalone.o util.o conout.o
ifneq ("$(CYGWIN)", "")
#nullify the common variables that
#most *nix systems have (for windows)
PREFIX :=
BINDIR :=
DATADIR :=
MANDIR :=
QCVM = qcvm.exe
GMQCC = gmqcc.exe
TESTSUITE = testsuite.exe
# Determine if we're building for Windows or not so we can set the right file
# extensions for the binaries and exclude the testsuite because it doesn't build
# for that platform.
ifeq ($(OS),Windows_NT)
GMQCC := gmqcc.exe
QCVM := qcvm.exe
else
ifneq ("$(MINGW)", "")
#nullify the common variables that
#most *nix systems have (for windows)
PREFIX :=
BINDIR :=
DATADIR :=
MANDIR :=
QCVM = qcvm.exe
GMQCC = gmqcc.exe
TESTSUITE = testsuite.exe
GMQCC := gmqcc
QCVM := qcvm
TESTSUITE := testsuite
endif
# C++ compiler
CXX ?= clang++
# Build artifact directories
OBJDIR := .build/objs
DEPDIR := .build/deps
# Collect all the source files for GMQCC.
GSRCS := ast.cpp
GSRCS += code.cpp
GSRCS += conout.cpp
GSRCS += fold.cpp
GSRCS += ftepp.cpp
GSRCS += intrin.cpp
GSRCS += ir.cpp
GSRCS += lexer.cpp
GSRCS += main.cpp
GSRCS += opts.cpp
GSRCS += parser.cpp
GSRCS += stat.cpp
GSRCS += utf8.cpp
GSRCS += util.cpp
# Collect all the source files for QCVM.
QSRCS := exec.cpp
QSRCS += stat.cpp
QSRCS += util.cpp
# Collect all the source files for TESTSUITE.
TSRCS := conout.cpp
TSRCS += opts.cpp
TSRCS += stat.cpp
TSRCS += test.cpp
TSRCS += util.cpp
#
# Compilation flags
#
CXXFLAGS := -Wall
CXXFLAGS += -Wextra
CXXFLAGS += -Wno-parentheses
CXXFLAGS += -Wno-class-memaccess
CXXFLAGS += -Wno-implicit-fallthrough
CXXFLAGS += -std=c++11
# Disable some unneeded features.
CXXFLAGS += -fno-exceptions
CXXFLAGS += -fno-rtti
CXXFLAGS += -fno-asynchronous-unwind-tables
# Give each function and data it's own section so the linker can remove unused
# references to each, producing smaller, tighter binaries.
ifeq ($(UNUSED),1)
CXXFLAGS += -ffunction-sections
CXXFLAGS += -fdata-sections
endif
# Enable link-time optimizations if requested.
ifeq ($(LTO),1)
CXXFLAGS += -flto
endif
ifeq ($(DEBUG),1)
# Ensure there is a frame-pointer in debug builds.
CXXFLAGS += -fno-omit-frame-pointer
# Disable all optimizations in debug builds.
CXXFLAGS += -O0
# Enable debug symbols.
CXXFLAGS += -g
else
QCVM = qcvm
GMQCC = gmqcc
TESTSUITE = testsuite
endif
# Disable all the stack protection features in release builds.
CXXFLAGS += -fno-stack-protector
CXXFLAGS += -fno-stack-check
# Disable frame pointer in release builds when AddressSanitizer isn't present.
ifeq ($(ASAN),1)
CXXFLAGS += -fno-omit-frame-pointer
else
CXXFLAGS += -fomit-frame-pointer
endif
# Highest optimization flag in release builds.
CXXFLAGS += -O3
endif
#standard rules
default: all
%.o: %.c
$(CC) -c $< -o $@ $(CFLAGS)
# Sanitizer selection
ifeq ($(ASAN),1)
CXXFLAGS += -fsanitize=address
endif
ifeq ($(UBSAN),1)
CXXFLAGS += -fsanitize=undefined
endif
exec-standalone.o: exec.c
$(CC) -c $< -o $@ $(CFLAGS) -DQCVM_EXECUTOR=1
#
# Dependency flags
#
DEPFLAGS := -MMD
DEPFLAGS += -MP
$(QCVM): $(OBJ_X)
$(CC) -o $@ $^ $(CFLAGS) -lm
#
# Linker flags
#
LDFLAGS :=
$(GMQCC): $(OBJ_C) $(OBJ_D)
$(CC) -o $@ $^ $(CFLAGS)
# Remove unreferenced sections
ifeq ($(UNUSED),1)
LDFLAGS += -Wl,--gc-sections
endif
$(TESTSUITE): $(OBJ_T)
$(CC) -o $@ $^ $(CFLAGS)
# Enable link-time optimizations if request.
ifeq ($(LTO),1)
LDFLAGS += -flto
endif
# Sanitizer selection
ifeq ($(ASAN),1)
LDFLAGS += -fsanitize=address
endif
ifeq ($(UBSAN),1)
LDFLAGS += -fsanitize=undefined
endif
# Strip the binaries when not a debug build
ifneq (,$(findstring -g,$(CXXFLAGS)))
STRIP := true
else
STRIP := strip
endif
all: $(GMQCC) $(QCVM) $(TESTSUITE)
check: all
@ ./$(TESTSUITE)
# Build artifact directories.
$(DEPDIR):
@mkdir -p $(DEPDIR)
$(OBJDIR):
@mkdir -p $(OBJDIR)
$(OBJDIR)/%.o: %.cpp $(DEPDIR)/%.d | $(OBJDIR) $(DEPDIR)
$(CXX) -MT $@ $(DEPFLAGS) -MF $(DEPDIR)/$*.Td $(CXXFLAGS) -c -o $@ $<
@mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d
$(GMQCC): $(filter %.o,$(GSRCS:%.cpp=$(OBJDIR)/%.o))
$(CXX) $^ $(LDFLAGS) -o $@
$(STRIP) $@
$(QCVM): $(filter %.o,$(QSRCS:%.cpp=$(OBJDIR)/%.o))
$(CXX) $^ $(LDFLAGS) -o $@
$(STRIP) $@
$(TESTSUITE): $(filter %.o,$(TSRCS:%.cpp=$(OBJDIR)/%.o))
$(CXX) $^ $(LDFLAGS) -o $@
$(STRIP) $@
# Determine if the tests should be run.
RUNTESTS := true
ifdef TESTSUITE
RUNTESTS := ./$(TESTSUITE)
endif
test: $(QCVM) $(TESTSUITE)
@$(RUNTESTS)
clean:
rm -f *.o $(GMQCC) $(QCVM) $(TESTSUITE) *.dat
rm -rf $(DEPDIR) $(OBJDIR)
# deps
$(OBJ_D) $(OBJ_C) $(OBJ_X): gmqcc.h opts.def
main.o: lexer.h
parser.o: ast.h lexer.h
ast.o: ast.h ir.h
ir.o: ir.h
.PHONY: test clean $(DEPDIR) $(OBJDIR)
#install rules
install: install-gmqcc install-qcvm install-doc
install-gmqcc: $(GMQCC)
install -d -m755 $(DESTDIR)$(BINDIR)
install -m755 $(GMQCC) $(DESTDIR)$(BINDIR)/gmqcc
install-qcvm: $(QCVM)
install -d -m755 $(DESTDIR)$(BINDIR)
install -m755 $(QCVM) $(DESTDIR)$(BINDIR)/qcvm
install-doc:
install -d -m755 $(DESTDIR)$(MANDIR)/man1
install -m755 doc/gmqcc.1 $(DESTDIR)$(MANDIR)/man1/
install -m755 doc/qcvm.1 $(DESTDIR)$(MANDIR)/man1/
# Dependencies
$(filter %.d,$(GSRCS:%.cpp=$(DEPDIR)/%.d)):
include $(wildcard $@)
$(filter %.d,$(QSRCS:%.cpp=$(DEPDIR)/%.d)):
include $(wildcard $@)
$(filter %.d,$(TSRCS:%.cpp=$(DEPDIR)/%.d)):
include $(wildcard $@)

10
README
View file

@ -1,9 +1 @@
GMQCC: An improved Quake C compiler
For licensing: see the LICENSE file.
For installation notes: see the INSTALL file.
For a list of authors: see the AUTHORS file.
For documentation:
See the manpages, or visit the documentation online at
http://graphitemaster.github.com/gmqcc/doc.html
An improved QuakeC compiler

157
TODO
View file

@ -1,157 +0,0 @@
GMQCC is quite feature compleat. But that doesn't address the fact that
it can be improved. This is a list of things that we'd like to support
in the distant future. When the time comes, we can just select a topic
from here and open a ticket for it on the issue tracker. But for the
meantime, this is sort of a cultivating flat file database.
Optimizations:
The following are optimizations that can be implemented after the
transformation into static-single assignment (SSA).
Global Value Numbering:
Eliminate redundancy by constructing a value graph of the source
then determinging which values are computed by equivalent expressions.
Simaler to Common Subexpression Elimination (CSE), however expressions
are determined via underlying equivalnce, opposed to lexically identical
expressions (CSE).
Spare Conditional Constant Propogation:
Simultaneously remove dead code and propogates constants. This is
not the same as indivial dead code elimination and constant propogation
passes. This is multipass.
The following are optimizations that can be implemented before the
transformation into a binary (code generator).
Code factoring:
The process of finding sequences of code that are identical,
or can be parameterized or reordered to be identical.
Which can be replaced with calls to a shared subroutine. To
reduce duplicated code. (Size optimization)
The following are optimizations that can be implemented anywhere, ideally
these are functional language optimizations.
Removing Recrusion:
Tail recrusive algorithms can be converted to iteration, which
does not have to have call overhead.
Language Features:
The following are language features that we'd like to see implemented in the
future.
Enumerations:
Like C
AST Macros:
Macros with sanity. Not textual subsitution.
Classes:
Like C++, but minus the stupidity:
- No type operator overloads
- Keep operator overloading for basic operators though.
- No inheritence
- No virtuals / pure virtuals
- Essentially "C structs but with operators" :)
Arrays:
They're currently implemented, but support in the engine
plus implicit bounds checks (and ability to turn the bounds
checking off)
Exceptions:
I feel like all languages suck at implementing this. This would
require support from the engine, but it would help catch bugs. We
could make it fast using a neat method of "frame pointers".
Overloaded Functions:
Ability to make individual functions with the same name, but take
different amount of arguments or type of arguments.
Default Argument Subsitution:
Ability to specify default values for arguments in functions.
void foo(string bar, string baz="default");
Supplying just one argument will expand the second argument to
become "default", otherwise if two arguments are specified then
the "default" string is overrode with what ever the user passes.
Character Type:
A char type would be nice to have. Essentially implemented as a
string, we can both "get" and "set" indices inside strings with
the help of builtin functions.
{
string foo = "test";
foo[0] = 'r';
print("it's time to ", foo);
}
Array Accessor With C-Semantics:
Also the abilit to use them as array accessors:
{
float hugearray['Z'];
hugearray['a'] = 100.0f;
}
Keep existing "pointer-like" semantics as well. In C arrays
simple work as pointers, a[1] -> *(a+1), or 1[a] -> *(1+a)
so we should allow both forms of syntax. As well as operand
reversal.
{
float h['Z'];
*(h+'a') = 100;
*('a'+h) = 'a'[h];
}
FTEQCC Inline Assembly:
This is still up for debate, mainly because a) it's syntax is
just utter crap. b) If we do an assembler, it should be nice.
we could provide a -std=fteqcc for the assembler itself :P
just like the compiler; although I think that's just insane.
Please see Assembler below.
Namespaces:
There is already a ticket open on this. They'd work just like C++
identically even.
Standalone QCVM:
The following are QCVM additions:
Proper ASM dissasembly:
Proper dissasembly of compiled .dat files. Annotated if possible
when -g (is used during compilation)
Debugging:
A step-through debuger -d (with seperate compilation as well)
Called -> qcdb Optionally alias to qcvm -d :)
We should beable to see the assembly and source it matches to
and the state of OFS_* and calls.
Testsuite:
The followiung are things we'd like to see added to the testsuite
in the distant future:
Multithreading:
Chances are when we start adding more and more tests, executing
them individually will be midly slow (even if that's a whole minute)
It would be nice to add a -j paramater to allow multiple threads to
be used and so we can execute many tests in parallel.
Interface:
Ability to select individual tests, or set paramaters manually
opposed to using the static task-template files. (A method to
override them rather).
Assembler:
Possibly support for a future assembler for QCASM. But we're not
entierly sure if it makes sense.

18
algo.h Normal file
View file

@ -0,0 +1,18 @@
#ifndef GMQCC_ALGO_HDR
#define GMQCC_ALGO_HDR
namespace algo {
template<typename ITER>
void shiftback(ITER element, ITER end) {
//typename ITER::value_type backup(move(*element)); // hold the element
typename std::remove_reference<decltype(*element)>::type backup(move(*element)); // hold the element
ITER p = element++;
for (; element != end; p = element++)
*p = move(*element);
*p = move(backup);
}
} // ::algo
#endif

2930
ast.c

File diff suppressed because it is too large Load diff

3125
ast.cpp Normal file

File diff suppressed because it is too large Load diff

849
ast.h

File diff suppressed because it is too large Load diff

246
code.c
View file

@ -1,246 +0,0 @@
/*
* Copyright (C) 2012
* Dale Weiler
* Wolfgang Bumiller
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "gmqcc.h"
prog_section_statement *code_statements;
int *code_linenums;
prog_section_def *code_defs;
prog_section_field *code_fields;
prog_section_function *code_functions;
int *code_globals;
char *code_chars;
uint16_t code_crc;
uint32_t code_entfields;
void code_push_statement(prog_section_statement *stmt, int linenum)
{
vec_push(code_statements, *stmt);
vec_push(code_linenums, linenum);
}
void code_pop_statement()
{
vec_pop(code_statements);
vec_pop(code_linenums);
}
void code_init() {
prog_section_function empty_function = {0,0,0,0,0,0,0,{0}};
prog_section_statement empty_statement = {0,{0},{0},{0}};
prog_section_def empty_def = {0, 0, 0};
int i = 0;
code_entfields = 0;
/*
* The way progs.dat is suppose to work is odd, there needs to be
* some null (empty) statements, functions, and 28 globals
*/
for(; i < 28; i++)
vec_push(code_globals, 0);
vec_push(code_chars, '\0');
vec_push(code_functions, empty_function);
code_push_statement(&empty_statement, 0);
vec_push(code_defs, empty_def);
vec_push(code_fields, empty_def);
}
uint32_t code_genstring(const char *str)
{
uint32_t off = vec_size(code_chars);
while (*str) {
vec_push(code_chars, *str);
++str;
}
vec_push(code_chars, 0);
return off;
}
uint32_t code_cachedstring(const char *str)
{
size_t s = 0;
/* We could implement knuth-morris-pratt or something
* and also take substrings, but I'm uncomfortable with
* pointing to subparts of strings for the sake of clarity...
*/
while (s < vec_size(code_chars)) {
if (!strcmp(str, code_chars + s))
return s;
while (code_chars[s]) ++s;
++s;
}
return code_genstring(str);
}
qcint code_alloc_field (size_t qcsize)
{
qcint pos = (qcint)code_entfields;
code_entfields += qcsize;
return pos;
}
bool code_write(const char *filename, const char *lnofile) {
prog_header code_header;
FILE *fp = NULL;
size_t it = 2;
code_header.statements.offset = sizeof(prog_header);
code_header.statements.length = vec_size(code_statements);
code_header.defs.offset = code_header.statements.offset + (sizeof(prog_section_statement) * vec_size(code_statements));
code_header.defs.length = vec_size(code_defs);
code_header.fields.offset = code_header.defs.offset + (sizeof(prog_section_def) * vec_size(code_defs));
code_header.fields.length = vec_size(code_fields);
code_header.functions.offset = code_header.fields.offset + (sizeof(prog_section_field) * vec_size(code_fields));
code_header.functions.length = vec_size(code_functions);
code_header.globals.offset = code_header.functions.offset + (sizeof(prog_section_function) * vec_size(code_functions));
code_header.globals.length = vec_size(code_globals);
code_header.strings.offset = code_header.globals.offset + (sizeof(int32_t) * vec_size(code_globals));
code_header.strings.length = vec_size(code_chars);
code_header.version = 6;
if (opts.forcecrc)
code_header.crc16 = opts.forced_crc;
else
code_header.crc16 = code_crc;
code_header.entfield = code_entfields;
if (OPTS_FLAG(DARKPLACES_STRING_TABLE_BUG)) {
util_debug("GEN", "Patching stringtable for -fdarkplaces-stringtablebug\n");
/* >= + P */
vec_push(code_chars, '\0'); /* > */
vec_push(code_chars, '\0'); /* = */
vec_push(code_chars, '\0'); /* P */
}
if (lnofile) {
uint32_t lnotype = *(unsigned int*)"LNOF";
uint32_t version = 1;
fp = util_fopen(lnofile, "wb");
if (!fp)
return false;
if (fwrite(&lnotype, sizeof(lnotype), 1, fp) != 1 ||
fwrite(&version, sizeof(version), 1, fp) != 1 ||
fwrite(&code_header.defs.length, sizeof(code_header.defs.length), 1, fp) != 1 ||
fwrite(&code_header.globals.length, sizeof(code_header.globals.length), 1, fp) != 1 ||
fwrite(&code_header.fields.length, sizeof(code_header.fields.length), 1, fp) != 1 ||
fwrite(&code_header.statements.length, sizeof(code_header.statements.length), 1, fp) != 1 ||
fwrite(code_linenums, sizeof(code_linenums[0]), vec_size(code_linenums), fp) != vec_size(code_linenums))
{
con_err("failed to write lno file\n");
}
fclose(fp);
fp = NULL;
}
/* ensure all data is in LE format */
util_endianswap(&code_header, 1, sizeof(prog_header));
util_endianswap(code_statements, vec_size(code_statements), sizeof(prog_section_statement));
util_endianswap(code_defs, vec_size(code_defs), sizeof(prog_section_def));
util_endianswap(code_fields, vec_size(code_fields), sizeof(prog_section_field));
util_endianswap(code_functions, vec_size(code_functions), sizeof(prog_section_function));
util_endianswap(code_globals, vec_size(code_globals), sizeof(int32_t));
fp = util_fopen(filename, "wb");
if (!fp)
return false;
if (1 != fwrite(&code_header, sizeof(prog_header) , 1 , fp) ||
vec_size(code_statements) != fwrite(code_statements, sizeof(prog_section_statement), vec_size(code_statements), fp) ||
vec_size(code_defs) != fwrite(code_defs, sizeof(prog_section_def) , vec_size(code_defs) , fp) ||
vec_size(code_fields) != fwrite(code_fields, sizeof(prog_section_field) , vec_size(code_fields) , fp) ||
vec_size(code_functions) != fwrite(code_functions, sizeof(prog_section_function) , vec_size(code_functions) , fp) ||
vec_size(code_globals) != fwrite(code_globals, sizeof(int32_t) , vec_size(code_globals) , fp) ||
vec_size(code_chars) != fwrite(code_chars, 1 , vec_size(code_chars) , fp))
{
fclose(fp);
return false;
}
util_debug("GEN","HEADER:\n");
util_debug("GEN"," version: = %d\n", code_header.version );
util_debug("GEN"," crc16: = %d\n", code_header.crc16 );
util_debug("GEN"," entfield: = %d\n", code_header.entfield);
util_debug("GEN"," statements = {.offset = % 8d, .length = % 8d}\n", code_header.statements.offset, code_header.statements.length);
util_debug("GEN"," defs = {.offset = % 8d, .length = % 8d}\n", code_header.defs .offset, code_header.defs .length);
util_debug("GEN"," fields = {.offset = % 8d, .length = % 8d}\n", code_header.fields .offset, code_header.fields .length);
util_debug("GEN"," functions = {.offset = % 8d, .length = % 8d}\n", code_header.functions .offset, code_header.functions .length);
util_debug("GEN"," globals = {.offset = % 8d, .length = % 8d}\n", code_header.globals .offset, code_header.globals .length);
util_debug("GEN"," strings = {.offset = % 8d, .length = % 8d}\n", code_header.strings .offset, code_header.strings .length);
/* FUNCTIONS */
util_debug("GEN", "FUNCTIONS:\n");
for (; it < vec_size(code_functions); it++) {
size_t j = code_functions[it].entry;
util_debug("GEN", " {.entry =% 5d, .firstlocal =% 5d, .locals =% 5d, .profile =% 5d, .name =% 5d, .file =% 5d, .nargs =% 5d, .argsize ={%d,%d,%d,%d,%d,%d,%d,%d} }\n",
code_functions[it].entry,
code_functions[it].firstlocal,
code_functions[it].locals,
code_functions[it].profile,
code_functions[it].name,
code_functions[it].file,
code_functions[it].nargs,
code_functions[it].argsize[0],
code_functions[it].argsize[1],
code_functions[it].argsize[2],
code_functions[it].argsize[3],
code_functions[it].argsize[4],
code_functions[it].argsize[5],
code_functions[it].argsize[6],
code_functions[it].argsize[7]
);
util_debug("GEN", " NAME: %s\n", &code_chars[code_functions[it].name]);
/* Internal functions have no code */
if (code_functions[it].entry >= 0) {
util_debug("GEN", " CODE:\n");
for (;;) {
if (code_statements[j].opcode != INSTR_DONE)
util_debug("GEN", " %-12s {% 5i,% 5i,% 5i}\n",
asm_instr[code_statements[j].opcode].m,
code_statements[j].o1.s1,
code_statements[j].o2.s1,
code_statements[j].o3.s1
);
else {
util_debug("GEN", " DONE {0x00000,0x00000,0x00000}\n");
break;
}
j++;
}
}
}
vec_free(code_statements);
vec_free(code_defs);
vec_free(code_fields);
vec_free(code_functions);
vec_free(code_globals);
vec_free(code_chars);
fclose(fp);
return true;
}

348
code.cpp Normal file
View file

@ -0,0 +1,348 @@
#include <string.h>
#include "gmqcc.h"
/*
* We could use the old method of casting to uintptr_t then to void*
* or qcint_t; however, it's incredibly unsafe for two reasons.
* 1) The compilers aliasing optimization can legally make it unstable
* (it's undefined behaviour).
*
* 2) The cast itself depends on fresh storage (newly allocated in which
* ever function is using the cast macros), the contents of which are
* transferred in a way that the obligation to release storage is not
* propagated.
*/
typedef union {
void *enter;
qcint_t leave;
} code_hash_entry_t;
/* Some sanity macros */
#define CODE_HASH_ENTER(ENTRY) ((ENTRY).enter)
#define CODE_HASH_LEAVE(ENTRY) ((ENTRY).leave)
void code_push_statement(code_t *code, prog_section_statement_t *stmt_in, lex_ctx_t ctx)
{
prog_section_statement_t stmt = *stmt_in;
if (OPTS_FLAG(TYPELESS_STORES)) {
switch (stmt.opcode) {
case INSTR_LOAD_S:
case INSTR_LOAD_ENT:
case INSTR_LOAD_FLD:
case INSTR_LOAD_FNC:
stmt.opcode = INSTR_LOAD_F;
break;
case INSTR_STORE_S:
case INSTR_STORE_ENT:
case INSTR_STORE_FLD:
case INSTR_STORE_FNC:
stmt.opcode = INSTR_STORE_F;
break;
case INSTR_STOREP_S:
case INSTR_STOREP_ENT:
case INSTR_STOREP_FLD:
case INSTR_STOREP_FNC:
stmt.opcode = INSTR_STOREP_F;
break;
}
}
if (OPTS_FLAG(SORT_OPERANDS)) {
uint16_t pair;
switch (stmt.opcode) {
case INSTR_MUL_F:
case INSTR_MUL_V:
case INSTR_ADD_F:
case INSTR_EQ_F:
case INSTR_EQ_S:
case INSTR_EQ_E:
case INSTR_EQ_FNC:
case INSTR_NE_F:
case INSTR_NE_V:
case INSTR_NE_S:
case INSTR_NE_E:
case INSTR_NE_FNC:
case INSTR_AND:
case INSTR_OR:
case INSTR_BITAND:
case INSTR_BITOR:
if (stmt.o1.u1 < stmt.o2.u1) {
uint16_t a = stmt.o2.u1;
stmt.o1.u1 = stmt.o2.u1;
stmt.o2.u1 = a;
}
break;
case INSTR_MUL_VF: pair = INSTR_MUL_FV; goto case_pair_gen;
case INSTR_MUL_FV: pair = INSTR_MUL_VF; goto case_pair_gen;
case INSTR_LT: pair = INSTR_GT; goto case_pair_gen;
case INSTR_GT: pair = INSTR_LT; goto case_pair_gen;
case INSTR_LE: pair = INSTR_GE; goto case_pair_gen;
case INSTR_GE: pair = INSTR_LE;
case_pair_gen:
if (stmt.o1.u1 < stmt.o2.u1) {
uint16_t x = stmt.o1.u1;
stmt.o1.u1 = stmt.o2.u1;
stmt.o2.u1 = x;
stmt.opcode = pair;
}
break;
}
}
code->statements.push_back(stmt);
code->linenums.push_back(ctx.line);
code->columnnums.push_back(ctx.column);
}
void code_pop_statement(code_t *code)
{
code->statements.pop_back();
code->linenums.pop_back();
code->columnnums.pop_back();
}
void *code_t::operator new(std::size_t bytes) {
return mem_a(bytes);
}
void code_t::operator delete(void *ptr) {
mem_d(ptr);
}
code_t::code_t()
{
static lex_ctx_t empty_ctx = {0, 0, 0};
static prog_section_function_t empty_function = {0,0,0,0,0,0,0,{0,0,0,0,0,0,0,0}};
static prog_section_statement_t empty_statement = {0,{0},{0},{0}};
static prog_section_def_t empty_def = {0, 0, 0};
string_cache = util_htnew(OPTS_OPTIMIZATION(OPTIM_OVERLAP_STRINGS) ? 0x100 : 1024);
// The way progs.dat is suppose to work is odd, there needs to be
// some null (empty) statements, functions, and 28 globals
globals.insert(globals.begin(), 28, 0);
chars.push_back('\0');
functions.push_back(empty_function);
code_push_statement(this, &empty_statement, empty_ctx);
defs.push_back(empty_def);
fields.push_back(empty_def);
}
code_t::~code_t()
{
util_htdel(string_cache);
}
void *code_util_str_htgeth(hash_table_t *ht, const char *key, size_t bin);
uint32_t code_genstring(code_t *code, const char *str) {
size_t hash;
code_hash_entry_t existing;
if (!str)
return 0;
if (!*str) {
if (!code->string_cached_empty) {
code->string_cached_empty = code->chars.size();
code->chars.push_back(0);
}
return code->string_cached_empty;
}
if (OPTS_OPTIMIZATION(OPTIM_OVERLAP_STRINGS)) {
hash = ((unsigned char*)str)[strlen(str)-1];
CODE_HASH_ENTER(existing) = code_util_str_htgeth(code->string_cache, str, hash);
} else {
hash = util_hthash(code->string_cache, str);
CODE_HASH_ENTER(existing) = util_htgeth(code->string_cache, str, hash);
}
if (CODE_HASH_ENTER(existing))
return CODE_HASH_LEAVE(existing);
CODE_HASH_LEAVE(existing) = code->chars.size();
code->chars.insert(code->chars.end(), str, str + strlen(str) + 1);
util_htseth(code->string_cache, str, hash, CODE_HASH_ENTER(existing));
return CODE_HASH_LEAVE(existing);
}
qcint_t code_alloc_field (code_t *code, size_t qcsize)
{
qcint_t pos = (qcint_t)code->entfields;
code->entfields += qcsize;
return pos;
}
static size_t code_size_generic(code_t *code, prog_header_t *code_header, bool lno) {
size_t size = 0;
if (lno) {
size += 4; /* LNOF */
size += sizeof(uint32_t); /* version */
size += sizeof(code_header->defs.length);
size += sizeof(code_header->globals.length);
size += sizeof(code_header->fields.length);
size += sizeof(code_header->statements.length);
size += sizeof(code->linenums[0]) * code->linenums.size();
size += sizeof(code->columnnums[0]) * code->columnnums.size();
} else {
size += sizeof(prog_header_t);
size += sizeof(prog_section_statement_t) * code->statements.size();
size += sizeof(prog_section_def_t) * code->defs.size();
size += sizeof(prog_section_field_t) * code->fields.size();
size += sizeof(prog_section_function_t) * code->functions.size();
size += sizeof(int32_t) * code->globals.size();
size += 1 * code->chars.size();
}
return size;
}
#define code_size_binary(C, H) code_size_generic((C), (H), false)
#define code_size_debug(C, H) code_size_generic((C), (H), true)
static void code_create_header(code_t *code, prog_header_t *code_header, const char *filename, const char *lnofile) {
size_t i;
code_header->statements.offset = sizeof(prog_header_t);
code_header->statements.length = code->statements.size();
code_header->defs.offset = code_header->statements.offset + (sizeof(prog_section_statement_t) * code->statements.size());
code_header->defs.length = code->defs.size();
code_header->fields.offset = code_header->defs.offset + (sizeof(prog_section_def_t) * code->defs.size());
code_header->fields.length = code->fields.size();
code_header->functions.offset = code_header->fields.offset + (sizeof(prog_section_field_t) * code->fields.size());
code_header->functions.length = code->functions.size();
code_header->globals.offset = code_header->functions.offset + (sizeof(prog_section_function_t) * code->functions.size());
code_header->globals.length = code->globals.size();
code_header->strings.offset = code_header->globals.offset + (sizeof(int32_t) * code->globals.size());
code_header->strings.length = code->chars.size();
code_header->version = 6;
code_header->skip = 0;
if (OPTS_OPTION_BOOL(OPTION_FORCECRC))
code_header->crc16 = OPTS_OPTION_U16(OPTION_FORCED_CRC);
else
code_header->crc16 = code->crc;
code_header->entfield = code->entfields;
if (OPTS_FLAG(DARKPLACES_STRING_TABLE_BUG)) {
/* >= + P */
code->chars.push_back('\0'); /* > */
code->chars.push_back('\0'); /* = */
code->chars.push_back('\0'); /* P */
}
/* ensure all data is in LE format */
util_swap_header(*code_header);
util_swap_statements(code->statements);
util_swap_defs_fields(code->defs);
util_swap_defs_fields(code->fields);
util_swap_functions(code->functions);
util_swap_globals(code->globals);
if (!OPTS_OPTION_BOOL(OPTION_QUIET)) {
if (lnofile)
con_out("writing '%s' and '%s'...\n", filename, lnofile);
else
con_out("writing '%s'\n", filename);
}
if (!OPTS_OPTION_BOOL(OPTION_QUIET) &&
!OPTS_OPTION_BOOL(OPTION_PP_ONLY))
{
char buffer[1024];
con_out("\nOptimizations:\n");
for (i = 0; i < COUNT_OPTIMIZATIONS; ++i) {
if (opts_optimizationcount[i]) {
util_optimizationtostr(opts_opt_list[i].name, buffer, sizeof(buffer));
con_out(
" %s: %u\n",
buffer,
(unsigned int)opts_optimizationcount[i]
);
}
}
}
}
static void code_stats(const char *filename, const char *lnofile, code_t *code, prog_header_t *code_header) {
if (OPTS_OPTION_BOOL(OPTION_QUIET) ||
OPTS_OPTION_BOOL(OPTION_PP_ONLY))
return;
con_out("\nFile statistics:\n");
con_out(" dat:\n");
con_out(" name: %s\n", filename);
con_out(" size: %u (bytes)\n", code_size_binary(code, code_header));
con_out(" crc: 0x%04X\n", code->crc);
if (lnofile) {
con_out(" lno:\n");
con_out(" name: %s\n", lnofile);
con_out(" size: %u (bytes)\n", code_size_debug(code, code_header));
}
con_out("\n");
}
bool code_write(code_t *code, const char *filename, const char *lnofile) {
prog_header_t code_header;
FILE *fp = nullptr;
code_create_header(code, &code_header, filename, lnofile);
if (lnofile) {
uint32_t version = 1;
fp = fopen(lnofile, "wb");
if (!fp)
return false;
util_endianswap(&version, 1, sizeof(version));
util_endianswap(&code->linenums[0], code->linenums.size(), sizeof(code->linenums[0]));
util_endianswap(&code->columnnums[0], code->columnnums.size(), sizeof(code->columnnums[0]));
if (fwrite("LNOF", 4, 1, fp) != 1 ||
fwrite(&version, sizeof(version), 1, fp) != 1 ||
fwrite(&code_header.defs.length, sizeof(code_header.defs.length), 1, fp) != 1 ||
fwrite(&code_header.globals.length, sizeof(code_header.globals.length), 1, fp) != 1 ||
fwrite(&code_header.fields.length, sizeof(code_header.fields.length), 1, fp) != 1 ||
fwrite(&code_header.statements.length, sizeof(code_header.statements.length), 1, fp) != 1 ||
fwrite(&code->linenums[0], sizeof(code->linenums[0]), code->linenums.size(), fp) != code->linenums.size() ||
fwrite(&code->columnnums[0], sizeof(code->columnnums[0]), code->columnnums.size(), fp) != code->columnnums.size())
{
con_err("failed to write lno file\n");
}
fclose(fp);
fp = nullptr;
}
fp = fopen(filename, "wb");
if (!fp)
return false;
if (1 != fwrite(&code_header, sizeof(prog_header_t) , 1 , fp) ||
code->statements.size() != fwrite(&code->statements[0], sizeof(prog_section_statement_t), code->statements.size(), fp) ||
code->defs.size() != fwrite(&code->defs[0], sizeof(prog_section_def_t) , code->defs.size() , fp) ||
code->fields.size() != fwrite(&code->fields[0], sizeof(prog_section_field_t) , code->fields.size() , fp) ||
code->functions.size() != fwrite(&code->functions[0], sizeof(prog_section_function_t) , code->functions.size() , fp) ||
code->globals.size() != fwrite(&code->globals[0], sizeof(int32_t) , code->globals.size() , fp) ||
code->chars.size() != fwrite(&code->chars[0], 1 , code->chars.size() , fp))
{
fclose(fp);
return false;
}
fclose(fp);
code_stats(filename, lnofile, code, &code_header);
return true;
}

422
conout.c
View file

@ -1,422 +0,0 @@
/*
* Copyright (C) 2012
* Dale Weiler
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "gmqcc.h"
/*
* isatty/STDERR_FILENO/STDOUT_FILNO
* + some other things likewise.
*/
#ifndef _WIN32
# include <unistd.h>
#else
# include <io.h>
/*
* Windows and it's posix underscore bullshit. We simply fix this
* with yay, another macro :P
*/
# define isatty _isatty
#endif
#define GMQCC_IS_STDOUT(X) ((FILE*)((void*)X) == stdout)
#define GMQCC_IS_STDERR(X) ((FILE*)((void*)X) == stderr)
#define GMQCC_IS_DEFINE(X) (GMQCC_IS_STDERR(X) || GMQCC_IS_STDOUT(X))
typedef struct {
FILE *handle_err;
FILE *handle_out;
int color_err;
int color_out;
} con_t;
/*
* Doing colored output on windows is fucking stupid. The linux way is
* the real way. So we emulate it on windows :)
*/
#ifdef _MSC_VER
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
/*
* Windows doesn't have constants for FILENO, sadly but the docs tell
* use the constant values.
*/
#undef STDERR_FILENO
#undef STDOUT_FILENO
#define STDERR_FILENO 2
#define STDOUT_FILENO 1
enum {
RESET = 0,
BOLD = 1,
BLACK = 30,
RED,
GREEN,
YELLOW,
BLUE,
MAGENTA,
CYAN,
GRAY,
WHITE
};
enum {
WBLACK,
WBLUE,
WGREEN = 2,
WRED = 4,
WINTENSE = 8,
WCYAN = WBLUE | WGREEN,
WMAGENTA = WBLUE | WRED,
WYELLOW = WGREEN | WRED,
WWHITE = WBLUE | WGREEN | WRED
}
static const ansi2win[] = {
WBLACK,
WRED,
WGREEN,
WYELLOW,
WBLUE,
WMAGENTA,
WCYAN,
WWHITE
};
static void win_fputs(char *str, FILE *h) {
/* state for translate */
int acolor;
int wcolor;
int icolor;
int state;
int place;
/* attributes */
int intense = -1;
int colors[] = {-1, -1 };
int colorpos = 1;
CONSOLE_SCREEN_BUFFER_INFO cinfo;
GetConsoleScreenBufferInfo (
(GMQCC_IS_STDOUT(h)) ?
GetStdHandle(STD_OUTPUT_HANDLE) :
GetStdHandle(STD_ERROR_HANDLE), &cinfo
);
icolor = cinfo.wAttributes;
while (*str) {
if (*str == '\e')
state = '\e';
else if (state == '\e' && *str == '[')
state = '[';
else if (state == '[') {
if (*str != 'm') {
colors[colorpos] = *str;
colorpos--;
} else {
int find;
int mult;
for (find = colorpos + 1, acolor = 0, mult = 1; find < 2; find++) {
acolor += (colors[find] - 48) * mult;
mult *= 10;
}
/* convert to windows color */
if (acolor == BOLD)
intense = WINTENSE;
else if (acolor == RESET) {
intense = WBLACK;
wcolor = icolor;
}
else if (BLACK < acolor && acolor <= WHITE)
wcolor = ansi2win[acolor - 30];
else if (acolor == 90) {
/* special gray really white man */
wcolor = WWHITE;
intense = WBLACK;
}
SetConsoleTextAttribute (
(h == stdout) ?
GetStdHandle(STD_OUTPUT_HANDLE) :
GetStdHandle(STD_ERROR_HANDLE),
wcolor | intense | (icolor & 0xF0)
);
colorpos = 1;
state = -1;
}
} else {
fputc(*str, h);
}
}
/* restore */
SetConsoleTextAttribute(
(GMQCC_IS_STDOUT(h)) ?
GetStdHandle(STD_OUTPUT_HANDLE) :
GetStdHandle(STD_ERROR_HANDLE),
icolor
);
}
#endif
/*
* We use standard files as default. These can be changed at any time
* with con_change(F, F)
*/
static con_t console;
/*
* Enables color on output if supported.
* NOTE: The support for checking colors is NULL. On windows this will
* always work, on *nix it depends if the term has colors.
*
* NOTE: This prevents colored output to piped stdout/err via isatty
* checks.
*/
static void con_enablecolor() {
if (console.handle_err == stderr || console.handle_err == stdout)
console.color_err = !!(isatty(STDERR_FILENO));
if (console.handle_out == stderr || console.handle_out == stdout)
console.color_out = !!(isatty(STDOUT_FILENO));
}
/*
* Does a write to the handle with the format string and list of
* arguments. This colorizes for windows as well via translate
* step.
*/
static int con_write(FILE *handle, const char *fmt, va_list va) {
int ln;
#ifndef _MSC_VER
ln = vfprintf(handle, fmt, va);
#else
{
char *data = NULL;
ln = _vscprintf(fmt, va);
data = malloc(ln + 1);
data[ln] = 0;
vsprintf(data, fmt, va);
if (GMQCC_IS_DEFINE(handle))
ln = win_fputs(data, handle);
else
ln = fputs(data, handle);
free(data);
}
#endif
return ln;
}
/**********************************************************************
* EXPOSED INTERFACE BEGINS
*********************************************************************/
void con_close() {
if (!GMQCC_IS_DEFINE(console.handle_err))
fclose(console.handle_err);
if (!GMQCC_IS_DEFINE(console.handle_out))
fclose(console.handle_out);
}
void con_color(int state) {
if (state)
con_enablecolor();
else {
console.color_err = 0;
console.color_out = 0;
}
}
void con_init() {
console.handle_err = stderr;
console.handle_out = stdout;
con_enablecolor();
}
void con_reset() {
con_close();
con_init ();
}
/*
* This is clever, say you want to change the console to use two
* files for out/err. You pass in two strings, it will properly
* close the existing handles (if they're not std* handles) and
* open them. Now say you want TO use stdout and stderr, this
* allows you to do that so long as you cast them to (char*).
* Say you need stdout for out, but want a file for error, you can
* do this too, just cast the stdout for (char*) and stick to a
* string for the error file.
*/
int con_change(const char *out, const char *err) {
con_close();
if (GMQCC_IS_DEFINE(out)) {
console.handle_out = GMQCC_IS_STDOUT(out) ? stdout : stderr;
con_enablecolor();
} else if (!(console.handle_out = fopen(out, "w"))) return 0;
if (GMQCC_IS_DEFINE(err)) {
console.handle_err = GMQCC_IS_STDOUT(err) ? stdout : stderr;
con_enablecolor();
} else if (!(console.handle_err = fopen(err, "w"))) return 0;
/* no buffering */
setvbuf(console.handle_out, NULL, _IONBF, 0);
setvbuf(console.handle_err, NULL, _IONBF, 0);
return 1;
}
int con_verr(const char *fmt, va_list va) {
return con_write(console.handle_err, fmt, va);
}
int con_vout(const char *fmt, va_list va) {
return con_write(console.handle_out, fmt, va);
}
/*
* Standard stdout/stderr printf functions used generally where they need
* to be used.
*/
int con_err(const char *fmt, ...) {
va_list va;
int ln = 0;
va_start(va, fmt);
con_verr(fmt, va);
va_end (va);
return ln;
}
int con_out(const char *fmt, ...) {
va_list va;
int ln = 0;
va_start(va, fmt);
con_vout(fmt, va);
va_end (va);
return ln;
}
/*
* Utility console message writes for lexer contexts. These will allow
* for reporting of file:line based on lexer context, These are used
* heavily in the parser/ir/ast.
*/
void con_vprintmsg_c(int level, const char *name, size_t line, const char *msgtype, const char *msg, va_list ap, const char *condname) {
/* color selection table */
static int sel[] = {
CON_WHITE,
CON_CYAN,
CON_RED
};
int err = !!(level == LVL_ERROR);
int color = (err) ? console.color_err : console.color_out;
int (*print) (const char *, ...) = (err) ? &con_err : &con_out;
int (*vprint)(const char *, va_list) = (err) ? &con_verr : &con_vout;
if (color)
print("\033[0;%dm%s:%d: \033[0;%dm%s: \033[0m", CON_CYAN, name, (int)line, sel[level], msgtype);
else
print("%s:%d: %s: ", name, (int)line, msgtype);
vprint(msg, ap);
if (condname)
print(" [%s]\n", condname);
else
print("\n");
}
void con_vprintmsg(int level, const char *name, size_t line, const char *msgtype, const char *msg, va_list ap) {
con_vprintmsg_c(level, name, line, msgtype, msg, ap, NULL);
}
void con_printmsg(int level, const char *name, size_t line, const char *msgtype, const char *msg, ...) {
va_list va;
va_start(va, msg);
con_vprintmsg(level, name, line, msgtype, msg, va);
va_end (va);
}
void con_cvprintmsg(void *ctx, int lvl, const char *msgtype, const char *msg, va_list ap) {
con_vprintmsg(lvl, ((lex_ctx*)ctx)->file, ((lex_ctx*)ctx)->line, msgtype, msg, ap);
}
void con_cprintmsg (void *ctx, int lvl, const char *msgtype, const char *msg, ...) {
va_list va;
va_start(va, msg);
con_cvprintmsg(ctx, lvl, msgtype, msg, va);
va_end (va);
}
/* General error interface */
size_t compile_errors = 0;
size_t compile_warnings = 0;
void vcompile_error(lex_ctx ctx, const char *msg, va_list ap)
{
++compile_errors;
con_cvprintmsg((void*)&ctx, LVL_ERROR, "error", msg, ap);
}
void compile_error(lex_ctx ctx, const char *msg, ...)
{
va_list ap;
va_start(ap, msg);
vcompile_error(ctx, msg, ap);
va_end(ap);
}
bool GMQCC_WARN vcompile_warning(lex_ctx ctx, int warntype, const char *fmt, va_list ap)
{
int lvl = LVL_WARNING;
char warn_name[1024];
if (!OPTS_WARN(warntype))
return false;
warn_name[0] = '-';
warn_name[1] = 'W';
(void)util_strtononcmd(opts_warn_list[warntype].name, warn_name+2, sizeof(warn_name)-2);
if (OPTS_WERROR(warntype)) {
++compile_errors;
lvl = LVL_ERROR;
}
else
++compile_warnings;
con_vprintmsg_c(lvl, ctx.file, ctx.line, ((lvl == LVL_ERROR) ? "error" : "warning"), fmt, ap, warn_name);
return OPTS_WERROR(warntype);
}
bool GMQCC_WARN compile_warning(lex_ctx ctx, int warntype, const char *fmt, ...)
{
bool r;
va_list ap;
va_start(ap, fmt);
r = vcompile_warning(ctx, warntype, fmt, ap);
va_end(ap);
return r;
}

226
conout.cpp Normal file
View file

@ -0,0 +1,226 @@
#include <stdio.h>
#include "gmqcc.h"
#define GMQCC_IS_STDOUT(X) ((X) == stdout)
#define GMQCC_IS_STDERR(X) ((X) == stderr)
#define GMQCC_IS_DEFINE(X) (GMQCC_IS_STDERR(X) || GMQCC_IS_STDOUT(X))
struct con_t {
FILE *handle_err;
FILE *handle_out;
int color_err;
int color_out;
};
static con_t console;
/*
* Enables color on output if supported.
* NOTE: The support for checking colors is nullptr. On windows this will
* always work, on *nix it depends if the term has colors.
*
* NOTE: This prevents colored output to piped stdout/err via isatty
* checks.
*/
static void con_enablecolor(void) {
console.color_err = util_isatty(console.handle_err);
console.color_out = util_isatty(console.handle_out);
}
/*
* Does a write to the handle with the format string and list of
* arguments. This colorizes for windows as well via translate
* step.
*/
static int con_write(FILE *handle, const char *fmt, va_list va) {
return vfprintf(handle, fmt, va);
}
/**********************************************************************
* EXPOSED INTERFACE BEGINS
*********************************************************************/
void con_close() {
if (!GMQCC_IS_DEFINE(console.handle_err))
fclose(console.handle_err);
if (!GMQCC_IS_DEFINE(console.handle_out))
fclose(console.handle_out);
}
void con_color(int state) {
if (state)
con_enablecolor();
else {
console.color_err = 0;
console.color_out = 0;
}
}
void con_init() {
console.handle_err = stderr;
console.handle_out = stdout;
con_enablecolor();
}
void con_reset() {
con_close();
con_init();
}
/*
* Defaultizer because stdio.h shouldn't be used anywhere except here
* and inside file.c To prevent mis-match of wrapper-interfaces.
*/
FILE *con_default_out() {
return console.handle_out = stdout;
}
FILE *con_default_err() {
return console.handle_err = stderr;
}
int con_verr(const char *fmt, va_list va) {
return con_write(console.handle_err, fmt, va);
}
int con_vout(const char *fmt, va_list va) {
return con_write(console.handle_out, fmt, va);
}
/*
* Standard stdout/stderr printf functions used generally where they need
* to be used.
*/
int con_err(const char *fmt, ...) {
va_list va;
int ln = 0;
va_start(va, fmt);
con_verr(fmt, va);
va_end(va);
return ln;
}
int con_out(const char *fmt, ...) {
va_list va;
int ln = 0;
va_start(va, fmt);
con_vout(fmt, va);
va_end (va);
return ln;
}
/*
* Utility console message writes for lexer contexts. These will allow
* for reporting of file:line based on lexer context, These are used
* heavily in the parser/ir/ast.
*/
static void con_vprintmsg_c(int level, const char *name, size_t line, size_t column, const char *msgtype, const char *msg, va_list ap, const char *condname) {
/* color selection table */
static int sel[] = {
CON_WHITE,
CON_CYAN,
CON_RED
};
int err = !!(level == LVL_ERROR);
int color = (err) ? console.color_err : console.color_out;
int (*print) (const char *, ...) = (err) ? &con_err : &con_out;
int (*vprint)(const char *, va_list) = (err) ? &con_verr : &con_vout;
if (color)
print("\033[0;%dm%s:%d:%d: \033[0;%dm%s: \033[0m", CON_CYAN, name, (int)line, (int)column, sel[level], msgtype);
else
print("%s:%d:%d: %s: ", name, (int)line, (int)column, msgtype);
vprint(msg, ap);
if (condname)
print(" [%s]\n", condname);
else
print("\n");
}
void con_vprintmsg(int level, const char *name, size_t line, size_t column, const char *msgtype, const char *msg, va_list ap) {
con_vprintmsg_c(level, name, line, column, msgtype, msg, ap, nullptr);
}
void con_printmsg(int level, const char *name, size_t line, size_t column, const char *msgtype, const char *msg, ...) {
va_list va;
va_start(va, msg);
con_vprintmsg(level, name, line, column, msgtype, msg, va);
va_end (va);
}
void con_cvprintmsg(lex_ctx_t ctx, int lvl, const char *msgtype, const char *msg, va_list ap) {
con_vprintmsg(lvl, ctx.file, ctx.line, ctx.column, msgtype, msg, ap);
}
void con_cprintmsg(lex_ctx_t ctx, int lvl, const char *msgtype, const char *msg, ...) {
va_list va;
va_start(va, msg);
con_cvprintmsg(ctx, lvl, msgtype, msg, va);
va_end (va);
}
/* General error interface: TODO seperate as part of the compiler front-end */
size_t compile_errors = 0;
size_t compile_warnings = 0;
size_t compile_Werrors = 0;
static lex_ctx_t first_werror;
void compile_show_werrors()
{
con_cprintmsg(first_werror, LVL_ERROR, "first warning", "was here");
}
void vcompile_error(lex_ctx_t ctx, const char *msg, va_list ap)
{
++compile_errors;
con_cvprintmsg(ctx, LVL_ERROR, "error", msg, ap);
}
void compile_error_(lex_ctx_t ctx, const char *msg, ...)
{
va_list ap;
va_start(ap, msg);
vcompile_error(ctx, msg, ap);
va_end(ap);
}
bool GMQCC_WARN vcompile_warning(lex_ctx_t ctx, int warntype, const char *fmt, va_list ap)
{
const char *msgtype = "warning";
int lvl = LVL_WARNING;
char warn_name[1024];
if (!OPTS_WARN(warntype))
return false;
warn_name[0] = '-';
warn_name[1] = 'W';
(void)util_strtononcmd(opts_warn_list[warntype].name, warn_name+2, sizeof(warn_name)-2);
++compile_warnings;
if (OPTS_WERROR(warntype)) {
if (!compile_Werrors)
first_werror = ctx;
++compile_Werrors;
msgtype = "Werror";
if (OPTS_FLAG(BAIL_ON_WERROR)) {
msgtype = "error";
++compile_errors;
}
lvl = LVL_ERROR;
}
con_vprintmsg_c(lvl, ctx.file, ctx.line, ctx.column, msgtype, fmt, ap, warn_name);
return OPTS_WERROR(warntype) && OPTS_FLAG(BAIL_ON_WERROR);
}
bool GMQCC_WARN compile_warning_(lex_ctx_t ctx, int warntype, const char *fmt, ...)
{
bool r;
va_list ap;
va_start(ap, fmt);
r = vcompile_warning(ctx, warntype, fmt, ap);
va_end(ap);
return r;
}

View file

@ -1,318 +1,745 @@
.\" Process with groff -man -Tascii file.3
.TH GMQCC 1 2012-07-12 "" "gmqcc Manual"
.SH NAME
gmqcc \- A Quake C compiler built from the NIH realm of sarcastic wit
.SH SYNOPSIS
.B gmqcc
[\fIOPTIONS\fR] [\fIfiles...\fR]
.SH DESCRIPTION
Traditionally, a QC compiler reads the file \fIprogs.src\fR which
in its first line contains the output filename, and the rest is a
.\"mdoc
.Dd January 24, 2013
.Dt GMQCC 1 PRM
.Os
.Sh NAME
.Nm gmqcc
.Nd A Quake C compiler built from the NIH realm of sarcastic wit
.Sh SYNOPSIS
.Nm gmqcc
.Op Cm options
.Op Ar files...
.Sh DESCRIPTION
Traditionally, a QC compiler reads the file
.Pa progs.src
which in its first line contains the output filename, and the rest is a
list of QC source files that are to be compiled in order.
\fBgmqcc\fR optionally takes options to specify the output and
.Nm gmqcc
optionally takes options to specify the output and
input files on the commandline, and also accepts assembly files.
.SH OPTIONS
\fBgmqcc\fR mostly tries to mimick gcc's commandline handling, though
.Sh OPTIONS
.Nm gmqcc
mostly tries to mimic gcc's commandline handling, though
there are also traditional long-options available.
.TP
.B "-h, --help"
.Bl -tag -width Ds
.It Fl h , Fl -help
Show a usage message and exit.
.TP
.B "-debug"
Turn on some compiler debugging mechanisms.
.TP
.B "-memchk"
Turn on compiler mem-check. (Shows allocations and checks for leaks.)
.TP
.BI "-o, --output=" filename
.It Fl o , Fl -output= Ns Ar filename
Specify the output filename. Defaults to progs.dat. This will overwrite
the output file listed in a \fIprogs.src\fR file in case such a file is used.
.TP
.BI "-O" number
the output file listed in a
.Pa progs.src
file in case such a file is used.
.Bl -tag -width indent
.It Fl O Ns Ar number
Specify the optimization level
.RS
.IP 3
.It Ar 3
Highest optimization level
.IP 2
.It Ar 2
Default optimization level
.IP 1
.It Ar 1
Minimal optimization level
.IP 0
.It Ar 0
Disable optimization entirely
.RE
.TP
.BI "-O" name "\fR, " "" -Ono- name
.El
.Pp
.It Fl O Ns Ar name , Fl Ono- Ns Ar name
Enable or disable a specific optimization. Note that these options
must be used after setting the optimization level, otherwise they'll
be overwritten.
.TP
.B -Ohelp
.It Fl O Ns Cm help
List all possible optimizations and the optimization level they're
activated at.
.TP
.BI -W warning "\fR, " "" -Wno- warning
.It Fl q , Fl -quiet
Be less verbose. In particular removes the messages about which files
are being processed, and which compilation mode is being used, and
some others. Warnings and errors will of course still be displayed.
.It Fl D Ns Ar macroname , Fl D Ns Ar macroname Ns = Ns Ar value
Predefine a macro, optionally with a optional value.
.It Fl E
Run only the preprocessor as if
.Fl f Ns Cm ftepp
was used and print the preprocessed code to stdout.
.It Fl W Ns Ar warning , Fl Wno- Ns Ar warning
Enable or disable a warning.
.TP
.B -Wall
Enable all warnings. Overrides preceding -W parameters.
.TP
.BR -Werror ", " -Wno-error
.It Fl W Ns Cm all
Enable almost all warnings. Overrides preceding
.Fl W
parameters.
.Pp
The following warnings will
.Em not
be enabled:
.Bl -tag -width indent -offset indent
.It Fl W Ns Cm uninitialized-global
.El
.It Fl W Ns Cm error , Fl Wno- Ns Cm error
Controls whether or not all warnings should be treated as errors.
.TP
.BI -Werror- warning "\fR, " "" -Wno-error- warning
.It Fl Werror- Ns Ar warning , Fl Wno-error- Ns Ar warning
Controls whether a specific warning should be an error.
.TP
.B -Whelp
.It Fl W Ns Cm help
List all possible warn flags.
.TP
.BI -f flag "\fR, " "" -fno- flag
.It Fl f Ns Ar flag , Fl fno- Ns Ar flag
Enable or disable a specific compile flag. See the list of flags
below.
.TP
.B -fhelp
.It Fl f Ns Cm help
List all possible compile flags.
.TP
.B -nocolor
.It Fl nocolor
Disables colored output
.TP
.BI -config= file
Use an ini file to read all the -O, -W and -f flag from. See the
CONFIG section about the file format.
.TP
.BI "-redirout=" file
Redirects standard output to a \fIfile\fR
.TP
.BI "-redirerr=" file
Redirects standard error to a \fIfile\fR
.TP
.BI "-std=" standard
.It Fl config= Ns Ar file
Use an ini file to read all the
.Fl O , Fl W
and
.Fl f
flag from. See the
.It Fl "debug"
Turn on some compiler debugging mechanisms.
.It Fl memchk
Turn on compiler mem-check. (Shows allocations and checks for leaks.)
.It Fl -memdumpcols Ns Ar columns
Changes the number of columns to use for the debug memory dump, defaults to 16.
.Sx CONFIG
section about the file format.
.It Fl redirout= Ns Ar file
Redirects standard output to a
.Ar file
.It Fl redirerr= Ns Ar file
Redirects standard error to a
.Ar file
.It Fl std= Ns Ar standard
Use the specified standard for parsing QC code. The following standards
are available:
.IR gmqcc , qcc , fteqcc
Selecting a standard also implies some -f options and behaves as if
those options have been written right after the -std option, meaning
if you changed them before the -std option, you're now overwriting
them.
.sp
.BR -std=gmqcc " includes:"
.in +4
-fadjust-vector-fields
.in
.BR -std=qcc " includes:"
.in +4
.nf
-fassign-function-types
-f\fIno-\fRadjust-vector-fields
.fi
.in
.BR -std=fteqcc " includes:"
.in +4
.nf
-fftepp
-ftranslatable-strings
-fassign-function-types
-Wternary-precedence
-f\fIno-\fRadjust-vector-fields
-f\fIno-\fRcorrect-ternary
.fi
.in
.SH Warnings
.TP
.B -Wunused-variable
.Ar gmqcc , Ar qcc , Ar fteqcc
Selecting a standard also implies some
.Fl f
options and behaves as if
those options have been written right after the
.Fl std
option, meaning
if you changed them before the
.Fl -std
option, you're now overwriting them.
.Pp
.Fl std= Ns Cm gmqcc No includes:
.Bl -tag -width indent -compact -offset Ds
.It Fl f Ns Cm adjust-vector-fields
.It Fl f Ns Cm correct-logic
.It Fl f Ns Cm true-empty-strings
.It Fl f Ns Cm loop-labels
.It Fl f Ns Cm initialized-nonconstants
.It Fl f Ns Cm translatable-strings
.It Fl fno- Ns Cm false-empty-strings
.It Fl W Ns Cm invalid-parameter-count
.It Fl W Ns Cm missing-returnvalues
.It Fl f Ns Cm correct-ternary Li (cannot be turned off)
.El
.Pp
.Fl std= Ns Cm qcc No includes:
.Bl -tag -width indent -compact -offset Ds
.It Fl f Ns Cm assign-function-types
.It Fl fIno- Ns Cm adjust-vector-fields
.El
.Pp
.Fl std= Ns Cm fteqcc No includes:
.Bl -tag -width indent -compact -offset Ds
.It Fl f Ns Cm ftepp
.It Fl f Ns Cm translatable-strings
.It Fl f Ns Cm assign-function-types
.It Fl W Ns Cm ternary-precedence
.It Fl fno- Ns Cm adjust-vector-fields
.It Fl fno- Ns Cm correct-ternary
.El
.It Fl -add-info
Adds compiler information to the generated binary file. Currently
this includes the following globals:
.Bl -tag -width indent -compact
.It Li reserved:version
String containing the compiler version as printed by the \-\-version
parameter.
.El
.It Fl -correct , Fl -no-correct
When enabled, errors about undefined values try to suggest an existing
value via spell checking.
.It Fl dump
DEBUG OPTION. Print the code's intermediate representation before the
optimization and finalization passes to stdout before generating the
binary.
.It Fl dumpfin
DEBUG OPTION. Print the code's intermediate representation after the
optimization and finalization passes to stdout before generating the
binary. The instructions will be enumerated, and values will contain a
list of liferanges.
.It Fl force-crc= Ns Ar CRC
Force the produced progs file to use the specified CRC.
.It Fl state-fps= Ns Ar NUM
Activate \-femulate-state and set the emulated FPS to
.Ar NUM Ns .
.El
.Sh COMPILE WARNINGS
.Bl -tag -width Ds
.It Fl W Ns Cm unused-variable
Generate a warning about variables which are declared but never used.
This can be avoided by adding the \fInoref\fR keyword in front of the
This can be avoided by adding the
.Ql noref
keyword in front of the
variable declaration. Additionally a complete section of unreferenced
variables can be opened using \fI#pragma noref 1\fR, and closed via
\fI#pragma noref 0\fR.
.TP
.B -Wused-uninitialized
variables can be opened using
.Ql #pragma noref 1
and closed via
.Ql #pragma noref 0 Ns .
.It Fl W Ns Cm unused-component
Generate a warning about vector variables which are declared but not all their
components are used.
.It Fl W Ns Cm used-uninitialized
Generate a warning if it is possible that a variable can be used
without prior initialization. Note that this warning is not
necessarily reliable if the initialization happens only under certain
conditions. The other way is \fInot\fR possible: that the warning is
\fInot\fR generated when uninitialized use \fIis possible\fR.
.TP
.B -Wunknown-control-sequence
conditions. The other way is
.Em not
possible: that the warning is
.Em not
generated when uninitialized use
.Em is
possible.
.It Fl W Ns Cm unknown-control-sequence
Generate an error when an unrecognized control sequence in a string is
used. Meaning: when there's a character after a backslash in a string
which has no known meaning.
.TP
.B -Wextensions
.It Fl W Ns Cm extensions
Warn when using special extensions which are not part of the selected
standard.
.TP
.B -Wfield-redeclared
.It Fl W Ns Cm field-redeclared
Generally QC compilers ignore redeclaration of fields. Here you can
optionally enable a warning.
.TP
.B -Wmissing-return-values
Functions which aren't of type \fIvoid\fR will warn if it possible to
.It Fl W Ns Cm missing-return-values
Functions which aren't of type
.Ft void
will warn if it possible to
reach the end without returning an actual value.
.TP
.B -Wtoo-few-parameters
Warn about a function call with fewer parameters than the function
expects.
.TP
.B -Wlocal-shadows
.It Fl W Ns Cm invalid-parameter-count
Warn about a function call with an invalid number of parameters.
.It Fl W Ns Cm local-shadows
Warn when a locally declared variable shadows variable.
.TP
.B -Wlocal-constants
.It Fl W Ns Cm local-constants
Warn when the initialization of a local variable turns the variable
into a constant. This is default behaviour unless
\fI-finitialized-nonconstants\fR is used.
.TP
.B -Wvoid-variables
There are only 2 known global variables of type void: end_sys_globals
and end_sys_fields. Any other void-variable will warn.
.TP
.B -Wimplicit-function-pointer
A global function which is not declared with the \fIvar\fR keyword is
.Fl f Ns Cm initialized-nonconstants
is used.
.It Fl W Ns Cm void-variables
There are only 2 known global variables of type void:
.Ql end_sys_globals
and
.Ql end_sys_fields Ns .
Any other void-variable will warn.
.It Fl W Ns Cm implicit-function-pointer
A global function which is not declared with the
.Ql var
keyword is
expected to have an implementing body, or be a builtin. If neither is
the case, it implicitly becomes a function pointer, and a warning is
generated.
.TP
.B -Wvariadic-function
.It Fl W Ns Cm variadic-function
Currently there's no way for an in QC implemented function to access
variadic parameters. If a function with variadic parameters has an
implementing body, a warning will be generated.
.TP
.B -Wframe-macros
Generate warnings about \fI$frame\fR commands, for instance about
.It Fl W Ns Cm frame-macros
Generate warnings about
.Ql $frame
commands, for instance about
duplicate frame definitions.
.TP
.B -Weffectless-statement
.It Fl W Ns Cm effectless-statement
Warn about statements which have no effect. Any expression which does
not call a function or assigns a variable.
.TP
.B -Wend-sys-fields
The \fIend_sys_fields\fR variable is supposed to be a global variable
of type \fIvoid\fR. It is also recognized as a \fIfield\fR but this
.It Fl W Ns Cm end-sys-fields
The
.Ql end_sys_fields
variable is supposed to be a global variable
of type
.Ft void Ns .
It is also recognized as a \fIfield\fR but this
will generate a warning.
.TP
.B -Wassign-function-types
.It Fl W Ns Cm assign-function-types
Warn when assigning to a function pointer with an unmatching
signature. This usually happens in cases like assigning the null
function to an entity's .think function pointer.
.TP
.B -Wpreprocessor
Enable warnings coming from the preprocessor. Like duplicate macro
declarations.
.TP
.B -Wmultifile-if
.It Fl W Ns Cm cpp
Show warnings created using the preprocessor's '#warning' directive.
.It Fl W Ns Cm multifile-if
Warn if there's a preprocessor \fI#if\fR spanning across several
files.
.TP
.B -Wdouble-declaration
.It Fl W Ns Cm double-declaration
Warn about multiple declarations of globals. This seems pretty common
in QC code so you probably do not want this unless you want to clean
up your code.
.TP
.B -Wconst-var
.It Fl W Ns Cm const-var
The combination of \fIconst\fR and \fIvar\fR is not illegal, however
different compilers may handle them differently. We were told, the
intention is to create a function-pointer which is not assignable.
This is exactly how we interpret it. However for this interpretation
the \fIvar\fR keyword is considered superfluous (and philosophically
the
.Ql var
keyword is considered superfluous (and philosophically
wrong), so it is possible to generate a warning about this.
.TP
.B -Wmultibyte-character
.It Fl W Ns Cm multibyte-character
Warn about multibyte character constants, they do not work right now.
.TP
.B -Wternary-precedence
.It Fl W Ns Cm ternary-precedence
Warn if a ternary expression which contains a comma operator is used
without enclosing parenthesis, since this is most likely not what you
actually want. We recommend the \fI-fcorrect-ternary\fR option.
.TP
.B -Wunknown-pragmas
Warn when encountering an unrecognized \fI#pragma\fR line.
.TP
.B -Wunreachable-code
actually want. We recommend the
.Fl f Ns Cm correct-ternary
option.
.It Fl W Ns Cm unknown-pragmas
Warn when encountering an unrecognized
.Ql #pragma
line.
.It Fl W Ns Cm unreachable-code
Warn about unreachable code. That is: code after a return statement,
or code after a call to a function marked as 'noreturn'.
.TP
.B -Wdebug
.It Fl W Ns Cm debug
Enable some warnings added in order to help debugging in the compiler.
You won't need this.
.SH Compile Flags
.TP
.B -foverlap-locals
Allow local variables to overlap with each other if they don't
interfer with each other. (Not implemented right now)
.TP
.B -fdarkplaces-string-table-bug
.It Fl W Ns Cm unknown-attribute
Warn on an unknown attribute. The warning will inlclude only the first
token inside the enclosing attribute-brackets. This may change when
the actual attribute syntax is better defined.
.It Fl W Ns Cm reserved-names
Warn when using reserved names such as
.Ql nil Ns .
.It Fl W Ns Cm uninitialized-constant
Warn about global constants (using the
.Ql const
keyword) with no
assigned value.
.It Fl W Ns Cm uninitialized-global
Warn about global variables with no initializing value. This is off by
default, and is added mostly to help find null-values which are
supposed to be replaced by the untyped 'nil' constant.
.It Fl W Ns Cm different-qualifiers
Warn when a variables is redeclared with a different qualifier. For
example when redeclaring a variable as \'var\' which was previously
marked \'const\'.
.It Fl W Ns Cm different-attributes
Similar to the above but for attributes like
.Ql [[noreturn]] Ns .
.It Fl W Ns Cm deprecated
Warn when a function is marked with the attribute
"[[deprecated]]". This flag enables a warning on calls to functions
marked as such.
.It Fl W Ns Cm parenthesis
Warn about possible mistakes caused by missing or wrong parenthesis,
like an assignment in an 'if' condition when there's no additional set
of parens around the assignment.
.It Fl W Ns Cm unsafe-types
When passing variadic parameters via
.Li ...(N)
it can happen that incompatible types are passed to functions. This
enables several warnings when static typechecking cannot guarantee
consistent behavior.
.It Fl W Ns Cm breakdef
When compiling original id1 QC there is a definition for `break`
which conflicts with the 'break' keyword in GMQCC. Enabling this
will print a warning when the definition occurs. The definition is
ignored for both cases.
.It Fl W Ns Cm const-overwrite
When compiling original QuakeWorld QC there are instances where
code overwrites constants. This is considered an error, however
for QuakeWorld to compile it needs to be treated as a warning
instead, as such this warning only works when \-std=qcc.
.It Fl W Ns Cm directive-inmacro
Warn about the use of preprocessor directives inside macros.
.It Fl W Ns Cm builtins
When using a function that is not explicitly defined, the compiler
will search its intrinsics table for something that matches that
function name by appending "__builtin_" to it. This behaviour may
be unexpected, so enabling this will produce a diagnostic when
such a function is resolved to a builtin.
.It Fl W Ns Cm inexact-compares
When comparing an inexact value such as `1.0/3.0' the result is
pathologically wrong. Enabling this will trigger a compiler warning
on such expressions.
.El
.Sh COMPILE FLAGS
.Bl -tag -width Ds
.It Fl f Ns Cm darkplaces-string-table-bug
Add some additional characters to the string table in order to
compensate for a wrong boundcheck in some specific version of the
darkplaces engine.
.TP
.B -fadjust-vector-fields
.It Fl f Ns Cm adjust-vector-fields
When assigning to field pointers of type \fI.vector\fR the common
behaviour in compilers like \fIfteqcc\fR is to only assign the
x-component of the pointer. This means that you can use the vector as
such, but you cannot use its y and z components directly. This flag
fixes this behaviour. Before using it make sure your code does not
depend on the buggy behaviour.
.TP
.B -fftepp
.It Fl f Ns Cm ftepp
Enable a partially fteqcc-compatible preprocessor. It supports all the
features used in the Xonotic codebase. If you need more, write a
ticket.
.TP
.B -frelaxed-switch
.It Fl f Ns Cm ftepp-predefs
Enable some predefined macros. This only works in combination with
\'\-fftepp' and is currently not included by '\-std=fteqcc'. The
following macros will be added:
.Bd -literal -offset indent
__LINE__
__FILE__
__COUNTER__
__COUNTER_LAST__
__RANDOM__
__RANDOM_LAST__
__DATE__
__TIME__
__FUNC__
.Ed
.Pp
Note that
.Li __FUNC__
is not actually a preprocessor macro, but is recognized by the parser
even with the preprocessor disabled.
.Pp
Note that fteqcc also defines
.Li __NULL__
which becomes the first global. Assigning it to a vector does not
yield the same result as in gmqcc where
.Li __NULL__
is defined to
.Li nil
(See
.Fl f Ns Cm untyped-nil
), which will cause the vector to be zero in all components. With fteqcc
only the first component will be 0, while the other two will become
the first to of the global return value. This behavior is odd and
relying on it should be discouraged, and thus is not supported by
gmqcc.
.It Fl f Ns Cm ftepp-mathdefs
Enable math constant definitions. This only works in combination
with \'\-fftepp' and is currently not included by '\-std=fteqcc'.
The following macros will be added:
.Bd -literal -offset indent
M_E
M_LOG2E
M_LOG10E
M_LN2
M_LN10
M_PI
M_PI_2
M_PI_4
M_1_PI
M_2_PI
M_2_SQRTPI
M_SQRT2
M_SQRT1_2
M_TAU
.Ed
.It Fl f Ns Cm ftepp-indirect-expansion
Enable indirect macro expansion. This only works in combination
with '-fftepp' and is currently not included by '-std=fteqcc'.
Enabling this behavior will allow the preprocessor to operate more
like the standard C preprocessor in that it will allow arguments
of macros which are macro-expanded to be substituted into the
definition of the macro.
.Pp
As an example:
.Bd -literal -offset indent
#define STR1(x) #x
#define STR2(x) STR1(x)
#define THE_ANSWER 42
#define THE_ANSWER_STR STR2(THE_ANSWER) /* "42" */
.Ed
With this enabled, an expansion of THE_ANSWER_STR will yield
the string "42". With this disabled an expansion of THE_ANSWER_STR
will yield "THE_ANSWER"
.It Fl f Ns Cm relaxed-switch
Allow switch cases to use non constant variables.
.TP
.B -fshort-logic
.It Fl f Ns Cm short-logic
Perform early out in logical AND and OR expressions. The final result
will be either a 0 or a 1, see the next flag for more possibilities.
.TP
.B -fperl-logic
.It Fl f Ns Cm perl-logic
In many languages, logical expressions perform early out in a special
way: If the left operand of an AND yeilds true, or the one of an OR
yields false, the complete expression evaluates to the right side.
Thus \fItrue && 5\fI evaluates to 5 rather than 1.
.TP
.B -ftranslatable-strings
Enable the underscore intrinsic: Using \fI_("A string constant")\fR
Thus
.Ql true && 5
evaluates to 5 rather than 1.
.It Fl f Ns Cm translatable-strings
Enable the underscore intrinsic: Using
.Ql _("A string constant")
will cause the string immediate to get a name with a "dotranslate_"
prefix. The darkplaces engine recognizes these and translates them in
a way similar to how gettext works.
.TP
.B -finitialized-nonconstants
.It Fl f Ns Cm initialized-nonconstants
Don't implicitly convert initialized variables to constants. With this
flag, the \fIconst\fR keyword is required to make a constant.
.TP
.B -fassign-function-types
.It Fl f Ns Cm assign-function-types
If this flag is not set, (and it is set by default in the qcc and
fteqcc standards), assigning function pointers of mismatching
signatures will result in an error rather than a warning.
.TP
.B -flno
.It Fl f Ns Cm lno
Produce a linenumber file along with the output .dat file.
.TP
.B -fcorrect-ternary
.It Fl f Ns Cm correct-ternary
Use C's operator precedence for ternary expressions. Unless your code
depends on fteqcc-compatible behaviour, you'll want to use thi
soption.
.TP
.B -fsingle-vector-defs
.It Fl f Ns Cm single-vector-defs
Normally vectors generate 4 defs, once for the vector, and once for
its components with _x, _y, _z suffixes. This option
prevents components from being listed.
.SH CONFIG
.It Fl f Ns Cm correct-logic
Most QC compilers translate
.Ql if(a_vector)
directly as an IF on the
vector, which means only the x-component is checked. This option causes
vectors to be cast to actual booleans via a NOT_V and, if necessary, a
NOT_F chained to it.
.Bd -literal -offset indent
if (a_vector) // becomes
if not(!a_vector)
// likewise
a = a_vector && a_float // becomes
a = !!a_vector && a_float
.Ed
.It Fl f Ns Cm true-empty-strings
An empty string is considered to be true everywhere. The NOT_S
instruction usually considers an empty string to be false, this option
effectively causes the unary not in strings to use NOT_F instead.
.It Fl f Ns Cm false-empty-strings
An empty string is considered to be false everywhere. This means loops
and if statements which depend on a string will perform a NOT_S
instruction on the string before using it.
.It Fl f Ns Cm utf8
Enable utf8 characters. This allows utf-8 encoded character constants,
and escape sequence codepoints in the valid utf-8 range. Effectively
enabling escape sequences like '\\{x2211}'.
.It Fl f Ns Cm bail-on-werror
When a warning is treated as an error, and this option is set (which
it is by default), it is like any other error and will cause
compilation to stop. When disabling this flag by using
\-fno-bail-on-werror, compilation will continue until the end, but no
output is generated. Instead the first such error message's context is
shown.
.It Fl f Ns Cm loop-labels
Allow loops to be labeled, and allow 'break' and 'continue' to take an
optional label to decide which loop to actually jump out of or
continue.
.Bd -literal -offset indent
for :outer (i = 0; i < n; ++i) {
while (inner) {
...;
if (something)
continue outer;
}
}
.Ed
.It Fl f Ns Cm untyped-nil
Adds a global named 'nil' which is of no type and can be assigned to
anything. No typechecking will be performed on assignments. Assigning
to it is forbidden, using it in any other kind of expression is also
not allowed.
.sp
Note that this is different from fteqcc's __NULL__: In fteqcc,
__NULL__ maps to the integer written as '0i'. It's can be assigned to
function pointers and integers, but it'll error about invalid
instructions when assigning it to floats without enabling the FTE
instruction set. There's also a bug which allows it to be assigned to
vectors, for which the source will be the global at offset 0, meaning
the vector's y and z components will contain the OFS_RETURN x and y
components.
.sp
In that gmqcc the nil global is an actual global filled with zeroes,
and can be assigned to anything including fields, vectors or function
pointers, and they end up becoming zeroed.
.It Fl f Ns Cm permissive
Various effects, usually to weaken some conditions.
.Bl -tag -width indent -offset indent
.It with Fl f Ns Cm untyped-nil
Allow local variables named
.Ql nil Ns .
(This will not allow declaring a global of that name.)
.El
.It Fl f Ns Cm variadic-args
Allow variadic parameters to be accessed by QC code. This can be
achieved via the '...' function, which takes a parameter index and a
typename.
.Pp
Example:
.Bd -literal -offset indent
void vafunc(string...count) {
float i;
for (i = 0; i < count; ++i)
print(...(i, string), "\\n");
}
.Ed
.It Fl f Ns Cm legacy-vector-maths
Most Quake VMs, including the one from FTEQW or up till recently
Darkplaces, do not cope well with vector instructions with overlapping
input and output. This option will avoid producing such code.
.It Fl f Ns Cm expressions-for-builtins
Usually builtin-numbers are just immediate constants. With this flag
expressions can be used, as long as they are compile-time constant.
.Pp
Example:
.Bd -literal -offset indent
void printA() = #1; // the usual way
void printB() = #2-1; // with a constant expression
.Ed
.It Fl f Ns Cm return-assignments
Enabiling this option will allow assigning values or expressions to the
return keyword as if it were a local variable of the same type as the
function's signature's return type.
.Pp
Example:
.Bd -literal -offset indent
float bar() { return 1024; }
float fun() {
return = bar();
return; // returns value of bar
}
.Ed
.It Fl f Ns Cm unsafe-varargs
When passing on varargs to a different functions, this turns some
static error cases into warnings. Like when the caller's varargs are
restricted to a different type than the callee's parameter. Or a list
of unrestricted varargs is passed into restricted varargs.
.It Fl f Ns Cm typeless-stores
Always use STORE_F, LOAD_F, STOREP_F when accessing scalar variables.
This is somewhat incorrect assembly instruction use, but in all engines
they do exactly the same. This makes disassembly output harder to read,
breaks decompilers, but causes the output file to be better compressible.
.It Fl f Ns Cm sort-operands
In commutative instructions, always put the lower-numbered operand first.
This shaves off 1 byte of entropy from all these instructions, reducing
compressed size of the output file.
.It Fl f Ns Cm emulate-state
Emulate OP_STATE operations in code rather than using the instruction.
The desired fps can be set via -state-fps=NUM, defaults to 10.
Specifying \-state-fps implicitly sets this flag. Defaults to off in all
standards.
.It Fl f Ns Cm arithmetic-exceptions
Turn on arithmetic exception tests in the compiler. In constant expressions
which trigger exceptions like division by zero, overflow, underflow, etc,
the following flag will produce diagnostics for what triggered that
exception.
.It Fl f Ns Cm split-vector-parameters
With this flag immediate vector literals which only ever appear as function
parameters won't be stored as vector immediates. Instead, the 3 floats making
up the vector will be copied separately. Essentially this turns a vector-store
instruction into 3 float-store instructions for such cases. This increases
code size but can dramatically reduce the amount of vector globals, which is
after all limited to 64k. There's at least one known codebase where this
lowers the number of globals from over 80k down to around 3k. In other code
bases it doesn't reduce the globals at all but only increases code size.
Just try it and see whether it helps you.
.It Fl f Ns Cm default-eraseable
Force all expressions to be "eraseable" which permits the compiler to
remove unused functions, variables and statements. This is equivlant to
putting [[eraseable]] on all definitions. This is dangerous as it breaks
auto cvars, definitions for functions the engine may be looking for and
translatable strings. Instead, you can mark a definition with [[noerase]]
to prevent this from happening.
.El
.Sh OPTIMIZATIONS
.Bl -tag -width Ds
.It Fl O Ns Cm peephole
Some general peephole optimizations. For instance the code `a = b + c`
typically generates 2 instructions, an ADD and a STORE. This
optimization removes the STORE and lets the ADD write directly into A.
.It Fl O Ns Cm tail-recursion
Tail recursive function calls will be turned into loops to avoid the
overhead of the CALL and RETURN instructions.
.It Fl O Ns Cm overlap-locals
Make all functions which use neither local arrays nor have locals
which are seen as possibly uninitialized use the same local section.
This should be pretty safe compared to other compilers which do not
check for uninitialized values properly. The problem is that there's
QC code out there which really doesn't initialize some values. This is
fine as long as this kind of optimization isn't used, but also, only
as long as the functions cannot be called in a recursive manner. Since
it's hard to know whether or not an array is actually fully
initialized, especially when initializing it via a loop, we assume
functions with arrays to be too dangerous for this optimization.
.It Fl O Ns Cm local-temps
This promotes locally declared variables to "temps". Meaning when a
temporary result of an operation has to be stored somewhere, a local
variable which is not 'alive' at that point can be used to keep the
result. This can reduce the size of the global section.
This will not have declared variables overlap, even if it was
possible.
.It Fl O Ns Cm global-temps
Causes temporary values which do not need to be backed up on a CALL to
not be stored in the function's locals-area. With this, a CALL to a
function may need to back up fewer values and thus execute faster.
.It Fl O Ns Cm strip-constant-names
Don't generate defs for immediate values or even declared constants.
Meaning variables which are implicitly constant or qualified as such
using the 'const' keyword.
.It Fl O Ns Cm overlap-strings
Aggressively reuse strings in the string section. When a string should
be added which is the trailing substring of an already existing
string, the existing string's tail will be returned instead of the new
string being added.
.Pp
For example the following code will only generate 1 string:
.Bd -literal -offset indent
print("Hello you!\\n");
print("you!\\n"); // trailing substring of "Hello you!\\n"
.Ed
.Pp
There's however one limitation. Strings are still processed in order,
so if the above print statements were reversed, this optimization
would not happen.
.It Fl O Ns Cm call-stores
By default, all parameters of a CALL are copied into the
parameter-globals right before the CALL instructions. This is the
easiest and safest way to translate calls, but also adds a lot of
unnecessary copying and unnecessary temporary values. This
optimization makes operations which are used as a parameter evaluate
directly into the parameter-global if that is possible, which is when
there's no other CALL instruction in between.
.It Fl O Ns Cm void-return
Usually an empty RETURN instruction is added to the end of a void
typed function. However, additionally after every function a DONE
instruction is added for several reasons. (For example the qcvm's
disassemble switch uses it to know when the function ends.). This
optimization replaces that last RETURN with DONE rather than adding
the DONE additionally.
.It Fl O Ns Cm vector-components
Because traditional QC code doesn't allow you to access individual
vector components of a computed vector without storing it in a local
first, sometimes people multiply it by a constant like
.Ql '0 1 0'
to get,
in this case, the y component of a vector. This optimization will turn
such a multiplication into a direct component access. If the factor is
anything other than 1, a float-multiplication will be added, which is
still faster than a vector multiplication.
.It Fl O Ns Cm const-fold-dce
For constant expressions that result in dead code (such as a branch whos
condition can be evaluated at compile-time), this will eliminate the branch
and else body (if present) to produce more optimal code.
.El
.Sh CONFIG
The configuration file is similar to regular .ini files. Comments
start with hashtags or semicolons, sections are written in square
brackets and in each section there can be arbitrary many key-value
pairs.
.sp
.Pp
There are 3 sections currently:
.IR flags ", " warnings ", and " optimizations .
They contain a list of boolean values of the form `VARNAME = true` or
`VARNAME = false`. The variable names are the same as for the
corresponding -W, -f or -O flag written with only capital letters and
.Ql flags Ns ,
.Ql warnings Ns ,
.Ql optimizations Ns .
They contain a list of boolean values of the form
.Ql VARNAME = true
or
.Ql VARNAME = false Ns .
The variable names are the same as for the
corresponding
.Fl W , Fl f
or
.Fl O
flag written with only capital letters and
dashes replaced by underscores.
.sp
.Pp
Here's an example:
.in +4
.nf
.Bd -literal -offset indent
# a GMQCC configuration file
[flags]
FTEPP = true
@ -326,12 +753,19 @@ Here's an example:
[optimizations]
PEEPHOLE = true
TAIL_RECURSION = true
.fi
.in
.SH BUGS
.Ed
.Sh FILES
.Bl -tag -width Ds
.It gmqcc.ini.example
A documented example for a gmqcc.ini file.
.El
.Sh SEE ALSO
.Xr qcvm 1
.Sh AUTHOR
See <http://graphitemaster.github.com/gmqcc>.
.Sh BUGS
Currently the '\-fftepp-predefs' flag is not included by '\-std=fteqcc',
partially because it is not entirely conformant to fteqcc.
.Pp
Please report bugs on <http://github.com/graphitemaster/gmqcc/issues>,
or see <http://graphitemaster.github.com/gmqcc> on how to contact us.
.SH SEE ALSO
.IR qcvm (1)
.SH AUTHOR
See <http://graphitemaster.github.com/gmqcc>.

View file

@ -1,92 +1,107 @@
.\" Process with groff -man -Tascii file.3
.TH QCVM 1 2012-18-12 "" "gmqcc Manual"
.SH NAME
qcvm \- A standalone QuakeC VM binary executor.
.SH SYNOPSIS
.B qcvm
[\fIOPTIONS\fR] [\fIPARAMS\fR] [\fIfile\fR]
.SH DESCRIPTION
qcvm is an executor for QuakeC VM binary files created using a QC
.\" qcvm mdoc manpage
.Dd January 31, 2013
.Dt QCVM 1 PRM
.Os
.Sh NAME
.Nm qcvm
.Nd A standalone QuakeC VM binary executor
.Sh SYNOPSIS
.Nm qcvm
.Op Cm options
.Op Cm parameters
.Ar program-file
.Sh DESCRIPTION
.Nm qcvm
is an executor for QuakeC VM binary files created using a QC
compiler such as gmqcc(1) or fteqcc. It provides a small set of
builtin functions, and by default executes the \fImain\fR function if
there is one. Some options useful for debugging are available as well.
.SH OPTIONS
builtin functions, and by default executes the
.Fn main
function if there is one. Some options useful for debugging are
available as well.
.Sh OPTIONS
There are 2 types of options. Options for the executor, and parameter
options used to add parameters which are passed to the main function
on execution.
.TP
.B "-h, --help"
.Bl -tag -width Ds
.It Fl h , Fl -help
Show a usage message and exit.
.TP
.B "-trace"
.It Fl trace
Trace the execution. Each instruction will be printed to stdout before
executing it.
.TP
.B "-profile"
.It Fl profile
Perform some profiling. This is currently not really implemented, the
option is available nonetheless.
.TP
.B "-info"
.It Fl info
Print information from the program's header instead of executing.
.TP
.B "-disasm"
.It Fl disasm
Disassemble the program by function instead of executing.
.TP
.B "-printdefs"
.It Fl disasm-func Ar function
Search for and disassemble the given function.
.It Fl printdefs
List all entries from the program's defs-section. Effectively
listing all the global variables of the program.
This option disables execution.
.TP
.B "-printfields"
.It Fl printfields
List all entries from the program's fields-section. Listing all
entity-fields declared in the program.
This option disables execution.
.TP
.B "-printfuns"
.It Fl printfuns
List functions and some information about their parameters.
This option disables execution.
.TP
.BI "-vector """ "x y z" """"
Append a vector parameter to be passed to \fImain\fR.
.TP
.BI "-float " number
Append a float parameter to be passed to \fImain\fR.
.TP
.BI "-string """ "text" """"
Append a string parameter to be passed to \fImain\fR.
.SH BUILTINS
This option disables execution. With a verbosity level of 1, builtin
numbers are printed. With a verbosity of 2, the function's sizes are
printed as well. This takes a little longer since the size is found by
searching for a
.Ql DONE
instruction in the code.
.It Fl v
Increase verbosity level, can be used multiple times.
.It Fl vector Ar 'x y z'
Append a vector parameter to be passed to
.Fn main Ns .
.It Fl float Ar number
Append a float parameter to be passed to
.Fn main Ns .
.It Fl string Ar 'text'
Append a string parameter to be passed to
.Fn main Ns .
.El
.Sh BUILTINS
The following builtin functions are available:
.TP
.RI "1) " void " print(" string... ") = " "#1" ;
.Bl -ohang
.It Li 1) void print(string...) = #1;
.Bd -unfilled -offset indent -compact
Print the passed strings to stdout. At most 8 strings are allowed.
.TP
.RI "2) " string " ftos(" float ") = " "#2" ;
Convert a float to a string.
.TP
.RI "3) " entity " spawn() = " "#3" ;
Spawn an entity.
.TP
.RI "4) " void " remove(" entity ") = " "#4" ;
Remove an entity.
.TP
.RI "5) " string " vtos(" vector ") = " "#5" ;
Convert a vector to a string.
.TP
.RI "6) " void " error(" string... ") = " "#6" ;
Print at most 8 strings to stdout and then exit with an error.
.TP
.RI "7) " float " vlen(" vector ") = " "#7" ;
Get the length of a vector.
.TP
.RI "8) " string " etos(" entity ") = " "#8" ;
Get the entity ID as string.
.TP
.RI "9) " float " stof(" string ") = " "#9" ;
Convert a string to a float.
.SH BUGS
.Ed
.It Li 2) string ftos(float) = #2;
.D1 Convert a float to a string.
.It Li 3) entity spawn() = #3;
.D1 Spawn an entity.
.It Li 4) void remove(entity) = #4;
.D1 Remove an entity.
.It Li 5) string vtos(vector) = #5;
.D1 Convert a vector to a string.
.It Li 6) void error(string...) = #6;
.D1 Print strings to stdout and then exit with an error (limited to 8 arguments)
.It Li 7) float vlen(vector) = #7;
.D1 Get the length of a vector.
.It Li 8) string etos(entity) = #8;
.D1 Get the entity ID as string.
.It Li 9) float stof(string) = #9;
.D1 Convert a string to a float.
.It Li 10) string strcat(string, string) = #10;
.D1 Concatenate two strings, returning a tempstring.
.It Li 11) float strcmp(string, string) = #11;
.Li 12) float strncmp(string, string, float) = #11;
.D1 Compare two strings. Returns the same as the corresponding C functions.
.It Li 12) vector normalize(vector) = #12;
.D1 Normalize a vector so its length is 1.
.It Li 13) float sqrt(float) = #13;
.D1 Get a value's square root.
.El
.Sh SEE ALSO
.Xr gmqcc 1
.Sh AUTHOR
See <http://graphitemaster.github.com/gmqcc>.
.Sh BUGS
Please report bugs on <http://github.com/graphitemaster/gmqcc/issues>,
or see <http://graphitemaster.github.com/gmqcc> on how to contact us.
.SH SEE ALSO
.IR gmqcc (1)
.SH AUTHOR
See <http://graphitemaster.github.com/gmqcc>.

File diff suppressed because it is too large Load diff

1679
fold.cpp Normal file

File diff suppressed because it is too large Load diff

121
fold.h Normal file
View file

@ -0,0 +1,121 @@
#ifndef GMQCC_FOLD_HDR
#define GMQCC_FOLD_HDR
#include "lexer.h"
#include "gmqcc.h"
struct ir_builder;
struct ir_value;
struct ast_function;
struct ast_ifthen;
struct ast_ternary;
struct ast_expression;
struct ast_value;
struct parser_t;
struct fold {
fold();
fold(parser_t *parser);
~fold();
// Bitmask describing which branches of a conditional to take after folding.
// Zero indicates all the branches can be removed.
// ON_TRUE means ON_FALSE can be removed.
// ON_FALSE means ON_TRUE can be removed.
// ON_TRUE | ON_FALSE means nothing can be removed.
enum {
ON_TRUE = 1 << 0,
ON_FALSE = 1 << 1,
};
bool generate(ir_builder *ir);
ast_expression *op(const oper_info *info, ast_expression **opexprs);
ast_expression *intrinsic(const char *intrinsic, size_t n_args, ast_expression **args);
static uint32_t cond_ternary(ast_value *condval, ast_ternary *branch);
static uint32_t cond_ifthen(ast_value *condval, ast_ifthen *branch);
static ast_expression *superfluous(ast_expression *left, ast_expression *right, int op);
static ast_expression *binary(lex_ctx_t ctx, int op, ast_expression *left, ast_expression *right);
ast_expression *constgen_float(qcfloat_t value, bool inexact);
ast_expression *constgen_vector(vec3_t value);
ast_expression *constgen_string(const char *str, bool translate);
ast_expression *constgen_string(const std::string &str, bool translate);
ast_value *imm_float(size_t index) const { return m_imm_float[index]; }
ast_value *imm_vector(size_t index) const { return m_imm_vector[index]; }
protected:
static qcfloat_t immvalue_float(ast_value *value);
static vec3_t immvalue_vector(ast_value *value);
static const char *immvalue_string(ast_value *value);
lex_ctx_t ctx();
bool immediate_true(ast_value *v);
bool check_except_float_impl(void (*callback)(void), ast_value *a, ast_value *b);
bool check_inexact_float(ast_value *a, ast_value *b);
ast_expression *op_mul_vec(vec3_t vec, ast_value *sel, const char *set);
ast_expression *op_neg(ast_value *a);
ast_expression *op_not(ast_value *a);
ast_expression *op_add(ast_value *a, ast_value *b);
ast_expression *op_sub(ast_value *a, ast_value *b);
ast_expression *op_mul(ast_value *a, ast_value *b);
ast_expression *op_div(ast_value *a, ast_value *b);
ast_expression *op_mod(ast_value *a, ast_value *b);
ast_expression *op_bor(ast_value *a, ast_value *b);
ast_expression *op_band(ast_value *a, ast_value *b);
ast_expression *op_xor(ast_value *a, ast_value *b);
ast_expression *op_lshift(ast_value *a, ast_value *b);
ast_expression *op_rshift(ast_value *a, ast_value *b);
ast_expression *op_andor(ast_value *a, ast_value *b, float expr);
ast_expression *op_tern(ast_value *a, ast_value *b, ast_value *c);
ast_expression *op_exp(ast_value *a, ast_value *b);
ast_expression *op_lteqgt(ast_value *a, ast_value *b);
ast_expression *op_ltgt(ast_value *a, ast_value *b, bool lt);
ast_expression *op_cmp(ast_value *a, ast_value *b, bool ne);
ast_expression *op_bnot(ast_value *a);
ast_expression *op_cross(ast_value *a, ast_value *b);
ast_expression *op_length(ast_value *a);
ast_expression *intrinsic_isfinite(ast_value *a);
ast_expression *intrinsic_isinf(ast_value *a);
ast_expression *intrinsic_isnan(ast_value *a);
ast_expression *intrinsic_isnormal(ast_value *a);
ast_expression *intrinsic_signbit(ast_value *a);
ast_expression *intrinsic_acosh(ast_value *a);
ast_expression *intrinsic_asinh(ast_value *a);
ast_expression *intrinsic_atanh(ast_value *a);
ast_expression *intrinsic_exp(ast_value *a);
ast_expression *intrinsic_exp2(ast_value *a);
ast_expression *intrinsic_expm1(ast_value *a);
ast_expression *intrinsic_pow(ast_value *lhs, ast_value *rhs);
ast_expression *intrinsic_mod(ast_value *lhs, ast_value *rhs);
ast_expression *intrinsic_fabs(ast_value *a);
ast_expression* intrinsic_nan(void);
ast_expression* intrinsic_epsilon(void);
ast_expression* intrinsic_inf(void);
static qcfloat_t immvalue_float(ir_value *value);
static vec3_t immvalue_vector(ir_value *value);
static uint32_t cond(ast_value *condval, ast_ifthen *branch);
private:
friend struct intrin;
std::vector<ast_value*> m_imm_float;
std::vector<ast_value*> m_imm_vector;
std::vector<ast_value*> m_imm_string;
hash_table_t *m_imm_string_untranslate; /* map<string, ast_value*> */
hash_table_t *m_imm_string_dotranslate; /* map<string, ast_value*> */
parser_t *m_parser;
bool m_initialized;
};
#endif

File diff suppressed because it is too large Load diff

1091
gmqcc.h

File diff suppressed because it is too large Load diff

View file

@ -1,51 +1,745 @@
# this is a template for an ini file
# these are comments
; so are these
#This configuration file is similar to a regular .ini file. Comments start
#with hashtags or semicolons, sections are written in square brackets and
#in each section there can be arbitrary many key-value pairs.
#There are 3 sections currently: flags, warnings, optimizations.
#They contain a list of boolean values of the form VARNAME = true or
#VARNAME = false. The variable names are the same as for the corre
#sponding -W, -f or -O flag written with only capital letters and dashes
#replaced by underscores.
[flags]
OVERLAP_LOCALS = false ; comments can exist on lines too
DARKPLACES_STRING_TABLE_BUG = false # like this as well
ADJUST_VECTOR_FIELDS = true
FTEPP = true
RELAXED_SWITCH = false
SHORT_LOGIC = false
PERL_LOGIC = true
TRANSLATABLE_STRINGS = false
INITIALIZED_NONCONSTANTS = false
ASSIGN_FUNCTION_TYPES = false
LNO = false
CORRECT_TERNARY = true
#Add some additional characters to the string table in order to
#compensate for a wrong boundcheck in some specific version of the
#darkplaces engine.
DARKPLACES_STRING_TABLE_BUG = true
#When assigning to field pointers of type .vector the common be
#haviour in compilers like fteqcc is to only assign the x-compo
#nent of the pointer. This means that you can use the vector as
#such, but you cannot use its y and z components directly. This
#flag fixes this behaviour. Before using it make sure your code
#does not depend on the buggy behaviour.
ADJUST_VECTOR_FIELDS = true
#Enable a partially fteqcc-compatible preprocessor. It supports
#all the features used in the Xonotic codebase. If you need more,
#write a ticket.
FTEPP = true
#Enable some predefined macros. This only works in combination
#with '-fftepp' and is currently not included by '-std=fteqcc'.
#The following macros will be added:
#
# __LINE__
# __FILE__
# __COUNTER__
# __COUNTER_LAST__
# __RANDOM__
# __RANDOM_LAST__
# __DATE__
# __TIME__
# __FUNC__
#
#Note that __FUNC__ is not actually a preprocessor macro, but is
#recognized by the parser even with the preprocessor disabled.
#
#Note that fteqcc also defines __NULL__ which becomes the first
#global. Assigning it to a vector does not yield the same result
#as in gmqcc where __NULL__ is defined to nil (See -funtyped-nil
#), which will cause the vector to be zero in all components. With
#fteqcc only the first component will be 0, while the other two
#will become the first to of the global return value. This behav
#ior is odd and relying on it should be discouraged, and thus is
#not supported by gmqcc.
FTEPP_PREDEFS = false
#Enable math constant definitions. This only works in combination
#with '-fftepp' and is currently not included by '-std=fteqcc'.
#The following macros will be added:
#
# M_E
# M_LOG2E
# M_LOG10E
# M_LN2
# M_LN10
# M_PI
# M_PI_2
# M_PI_4
# M_1_PI
# M_2_PI
# M_2_SQRTPI
# M_SQRT2
# M_SQRT1_2
# M_TAU
FTEPP_MATHDEFS = false
#Enable indirect macro expansion. This only works in combination
#with '-fftepp' and is currently not included by '-std=fteqcc'.
#Enabling this behavior will allow the preprocessor to operate more
#like the standard C preprocessor in that it will allow arguments
#of macros which are macro-expanded to be substituted into the
#definition of the macro. As an example:
#
# #define STR1(x) #x
# #define STR2(x) STR1(x)
# #define THE_ANSWER 42
# #define THE_ANSWER_STR STR2(THE_ANSWER) /* "42" */
#
#With this enabled, an expansion of THE_ANSWER_STR will yield
#the string "42". With this disabled an expansion of THE_ANSWER_STR
#will yield "THE_ANSWER"
FTEPP_INDIRECT_EXPANSION = false
#Allow switch cases to use non constant variables.
RELAXED_SWITCH = true
#Perform early out in logical AND and OR expressions. The final
#result will be either a 0 or a 1, see the next flag for more pos
#sibilities.
SHORT_LOGIC = true
#In many languages, logical expressions perform early out in a
#special way: If the left operand of an AND yeilds true, or the
#one of an OR yields false, the complete expression evaluates to
#the right side. Thus true && 5 evaluates to 5 rather than 1.
PERL_LOGIC = false
#Enable the underscore intrinsic: Using _("A string constant")
#will cause the string immediate to get a name with a "dotrans
#late_" prefix. The darkplaces engine recognizes these and trans
#lates them in a way similar to how gettext works.
TRANSLATABLE_STRINGS = true
#Don't implicitly convert initialized variables to constants. With
#this flag, the const keyword is required to make a constant.
INITIALIZED_NONCONSTANTS = false
#If this flag is not set, (and it is set by default in the qcc and
#fteqcc standards), assigning function pointers of mismatching
#signatures will result in an error rather than a warning.
ASSIGN_FUNCTION_TYPES = true
#Produce a linenumber file along with the output .dat file.
LNO = false
#Use C's operator precedence for ternary expressions. Unless your
#code depends on fteqcc-compatible behaviour, you'll want to use
#this option.
CORRECT_TERNARY = true
#Normally vectors generate 4 defs, once for the vector, and once
#for its components with _x, _y, _z suffixes. This option prevents
#components from being listed.
SINGLE_VECTOR_DEFS = true
#Most QC compilers translate if(a_vector) directly as an IF on
#the vector, which means only the x-component is checked. This
#option causes vectors to be cast to actual booleans via a NOT_V
#and, if necessary, a NOT_F chained to it.
#
# if (a_vector) // becomes
# if not(!a_vector)
# // likewise
# a = a_vector && a_float // becomes
# a = !!a_vector && a_float
CORRECT_LOGIC = true
#An empty string is considered to be true everywhere. The NOT_S
#instruction usually considers an empty string to be false, this
#option effectively causes the unary not in strings to use NOT_F
#instead.
TRUE_EMPTY_STRINGS = false
#An empty string is considered to be false everywhere. This means
#loops and if statements which depend on a string will perform a
#NOT_S instruction on the string before using it.
FALSE_EMPTY_STRINGS = true
#Enable utf8 characters. This allows utf-8 encoded character con
#stants, and escape sequence codepoints in the valid utf-8 range.
#Effectively enabling escape sequences like '\{x2211}'.
UTF8 = true
#When a warning is treated as an error, and this option is set
#(which it is by default), it is like any other error and will
#cause compilation to stop. When disabling this flag by using
#-fno-bail-on-werror, compilation will continue until the end, but
#no output is generated. Instead the first such error message's
#context is shown.
BAIL_ON_WERROR = false
#Allow loops to be labeled, and allow 'break' and 'continue' to
#take an optional label to decide which loop to actually jump out
#of or continue.
#
# for :outer (i = 0; i < n; ++i) {
# while (inner) {
# ...;
# if (something)
# continue outer;
# }
# }
LOOP_LABELS = true
#Adds a global named 'nil' which is of no type and can be assigned
#to anything. No typechecking will be performed on assignments.
#Assigning to it is forbidden, using it in any other kind of
#expression is also not allowed.
#
#Note that this is different from fteqcc's __NULL__: In fteqcc,
#__NULL__ maps to the integer written as '0i'. It's can be
#assigned to function pointers and integers, but it'll error about
#invalid instructions when assigning it to floats without enabling
#the FTE instruction set. There's also a bug which allows it to be
#assigned to vectors, for which the source will be the global at
#offset 0, meaning the vector's y and z components will contain
#the OFS_RETURN x and y components.#
#
#In that gmqcc the nil global is an actual global filled with
#zeroes, and can be assigned to anything including fields, vectors
#or function pointers, and they end up becoming zeroed.
UNTYPED_NIL = true
#Various effects, usually to weaken some conditions.
# with -funtyped-nil
# Allow local variables named nil. (This will not
# allow declaring a global of that name.)
PERMISSIVE = false
#Allow variadic parameters to be accessed by QC code. This can be
#achieved via the '...' function, which takes a parameter index
#and a typename.
#
#Example:
#
# void vafunc(string...count) {
# float i;
# for (i = 0; i < count; ++i)
# print(...(i, string), "\n");
# }
VARIADIC_ARGS = true
#Most Quake VMs, including the one from FTEQW or up till recently
#Darkplaces, do not cope well with vector instructions with over
#lapping input and output. This option will avoid producing such
#code.
LEGACY_VECTOR_MATHS = false
#Usually builtin-numbers are just immediate constants. With this
#flag expressions can be used, as long as they are compile-time
#constant.
#
#Example:
#
# void printA() = #1; // the usual way
# void printB() = #2-1; // with a constant expression
EXPRESSIONS_FOR_BUILTINS = true
#Enabiling this option will allow assigning values or expressions
#to the return keyword as if it were a local variable of the same
#type as the function's signature's return type.
#
#Example:
#
# float bar() { return 1024; }
# float fun() {
# return = bar();
# return; // returns value of bar (this can be omitted)
# }
RETURN_ASSIGNMENTS = true
#When passing on varargs to a different functions, this turns some
#static error cases into warnings. Like when the caller's varargs
#are restricted to a different type than the callee's parameter.
#Or a list of unrestricted varargs is passed into restricted
#varargs.
UNSAFE_VARARGS = false
#Always use STORE_F, LOAD_F, STOREP_F when accessing scalar variables.
#This is somewhat incorrect assembly instruction use, but in all engines
#they do exactly the same. This makes disassembly output harder to read,
#breaks decompilers, but causes the output file to be better compressible.
TYPELESS_STORES = false
#In commutative instructions, always put the lower-numbered operand first.
#This shaves off 1 byte of entropy from all these instructions, reducing
#compressed size of the output file.
SORT_OPERANDS = false
#Emulate OP_STATE operations in code rather than using the instruction.
#The desired fps can be set via -state-fps=NUM, defaults to 10.
EMULATE_STATE = false
#Turn on arithmetic exception tests in the compiler. In constant expressions
#which trigger exceptions like division by zero, overflow, underflow, etc,
#the following flag will produce diagnostics for what triggered that
#exception.
ARITHMETIC_EXCEPTIONS = false
#Split vector-literals which are only used dirctly as function parameters
#into 3 floats stored separately to reduce the number of globals at the
#expense of additional instructions.
SPLIT_VECTOR_PARAMETERS = false
#Force all expressions to be "eraseable" which permits the compiler
#to remove unused functions, variables and statements. This is
#equivlant to putting [[eraseable]] on all definitions. This is
#dangerous as it breaks auto cvars, definitions for functions the
#engine may be looking for and translatable strings. Instead, you
#can mark a definition with [[noerase]] to prevent this from happening.
DEFAULT_ERASEABLE = false
# enable all warnings (minus debug)
[warnings]
DEBUG = false
UNUSED_VARIABLE = true
USED_UNINITIALIZED = true
UNKNOWN_CONTROL_SEQUENCE = true
EXTENSIONS = true
FIELD_REDECLARED = true
MISSING_RETURN_VALUES = true
TOO_FEW_PARAMETERS = true
LOCAL_SHADOWS = true
LOCAL_CONSTANTS = true
VOID_VARIABLES = true
IMPLICIT_FUNCTION_POINTER = true
VARIADIC_FUNCTION = true
FRAME_MACROS = true
EFFECTLESS_STATEMENT = true
END_SYS_FIELDS = true
ASSIGN_FUNCTION_TYPES = true
PREPROCESSOR = true
MULTIFILE_IF = true
DOUBLE_DECLARATION = true
CONST_VAR = true
MULTIBYTE_CHARACTER = true
TERNARY_PRECEDENCE = true
UNKNOWN_PRAGMAS = true
#Generate a warning about variables which are declared but never
#used. This can be avoided by adding the noref keyword in front
#of the variable declaration. Additionally a complete section of
#unreferenced variables can be opened using #pragma noref 1 and
#closed via #pragma noref 0.
UNUSED_VARIABLE = false
#Generate a warning about vector variables which are declared but
#components of it are never used.
UNUSED_COMPONENT = false
#Generate a warning if it is possible that a variable can be used
#without prior initialization. Note that this warning is not nec
#essarily reliable if the initialization happens only under cer
#tain conditions. The other way is not possible: that the warning
#is not generated when uninitialized use is possible.
USED_UNINITIALIZED = false
#Generate an error when an unrecognized control sequence in a
#string is used. Meaning: when there's a character after a back
#slash in a string which has no known meaning.
UNKNOWN_CONTROL_SEQUENCE = false
#Warn when using special extensions which are not part of the
#selected standard.
EXTENSIONS = false
#Generally QC compilers ignore redeclaration of fields. Here you
#can optionally enable a warning.
FIELD_REDECLARED = false
#Functions which aren't of type void will warn if it possible to
#reach the end without returning an actual value.
MISSING_RETURN_VALUES = false
#Warn about a function call with an invalid number of parameters.
INVALID_PARAMETER_COUNT = false
#Warn when a locally declared variable shadows variable.
LOCAL_SHADOWS = false
#Warn when the initialization of a local variable turns the vari
#able into a constant. This is default behaviour unless
#-finitialized-nonconstants is used.
LOCAL_CONSTANTS = false
#There are only 2 known global variables of type void:
#end_sys_globals and end_sys_fields. Any other void-variable
#will warn.
VOID_VARIABLES = false
#A global function which is not declared with the var keyword is
#expected to have an implementing body, or be a builtin. If nei
#ther is the case, it implicitly becomes a function pointer, and a
#warning is generated.
IMPLICIT_FUNCTION_POINTER = false
#Currently there's no way for an in QC implemented function to
#access variadic parameters. If a function with variadic parame
#ters has an implementing body, a warning will be generated.
VARIADIC_FUNCTION = false
#Generate warnings about $frame commands, for instance about
#duplicate frame definitions.
FRAME_MACROS = false
#Warn about statements which have no effect. Any expression which
#does not call a function or assigns a variable.
EFFECTLESS_STATEMENT = false
#The end_sys_fields variable is supposed to be a global variable
#of type void. It is also recognized as a field but this will
#generate a warning.
END_SYS_FIELDS = false
#Warn when assigning to a function pointer with an unmatching sig
#nature. This usually happens in cases like assigning the null
#function to an entity's .think function pointer.
ASSIGN_FUNCTION_TYPES = false
#Show warnings created using the preprocessor's '#warning' directive
CPP = true
#Warn if there's a preprocessor #if spanning across several files.
MULTIFILE_IF = true
#Warn about multiple declarations of globals. This seems pretty
#common in QC code so you probably do not want this unless you
#want to clean up your code.
DOUBLE_DECLARATION = false
#The combination of const and var is not illegal, however differ
#ent compilers may handle them differently. We were told, the
#intention is to create a function-pointer which is not assigna
#ble. This is exactly how we interpret it. However for this
#interpretation the var keyword is considered superfluous (and
#philosophically wrong), so it is possible to generate a warning
#about this.
CONST_VAR = true
#Warn about multibyte character constants, they do not work right
#now.
MULTIBYTE_CHARACTER = false
#Warn if a ternary expression which contains a comma operator is
#used without enclosing parenthesis, since this is most likely not
#what you actually want. We recommend the -fcorrect-ternary
#option.
TERNARY_PRECEDENCE = false
#Warn when encountering an unrecognized #pragma line.
UNKNOWN_PRAGMAS = true
#Warn about unreachable code. That is: code after a return state
#ment, or code after a call to a function marked as 'noreturn'.
UNREACHABLE_CODE = true
#Enable some warnings added in order to help debugging in the com
#piler. You won't need this.
DEBUG = false
#Warn on an unknown attribute. The warning will inlclude only the
#first token inside the enclosing attribute-brackets. This may
#change when the actual attribute syntax is better defined.
UNKNOWN_ATTRIBUTE = true
#Warn when using reserved names such as nil.
RESERVED_NAMES = true
#Warn about global constants (using the const keyword) with no
#assigned value.
UNINITIALIZED_CONSTANT = true
#Warn about global variables with no initializing value. This is
#off by default, and is added mostly to help find null-values
#which are supposed to be replaced by the untyped 'nil' constant.
UNINITIALIZED_GLOBAL = true
#Warn when a variables is redeclared with a different qualifier.
#For example when redeclaring a variable as 'var' which was previ
#ously marked 'const'.
DIFFERENT_QUALIFIERS = true
#Similar to the above but for attributes like [[noreturn]].
DIFFERENT_ATTRIBUTES = true
#Warn when a function is marked with the attribute "[[depre
#cated]]". This flag enables a warning on calls to functions
#marked as such.
DEPRECATED = true
#Warn about possible mistakes caused by missing or wrong parenthe
#sis, like an assignment in an 'if' condition when there's no
#additional set of parens around the assignment.
PARENTHESIS = true
#When passing variadic parameters via ...(N) it can happen that
#incompatible types are passed to functions. This enables several
#warnings when static typechecking cannot guarantee consistent
#behavior.
UNSAFE_TYPES = true
#When compiling original id1 QC there is a definition for `break`
#which conflicts with the 'break' keyword in GMQCC. Enabling this
#print a warning when the definition occurs. The definition is
#ignored for both cases.
BREAKDEF = true
#When compiling original QuakeWorld QC there are instances where
#code overwrites constants. This is considered an error, however
#for QuakeWorld to compile it needs to be treated as a warning
#instead, as such this warning only works when -std=qcc.
CONST_OVERWRITE = true
#Warn about the use of preprocessor directives inside macros.
DIRECTIVE_INMACRO = true
#When using a function that is not explicitly defined, the compiler
#will search its intrinsics table for something that matches that
#function name by appending "__builtin_" to it. This behaviour may
#be unexpected, so enabling this will produce a diagnostic when
#such a function is resolved to a builtin.
BUILTINS = true
#When comparing an inexact value such as `1.0/3.0' the result is
#pathologically wrong. Enabling this will trigger a compiler warning
#on such expressions.
INEXACT_COMPARES = true
; enable all optimizations!
[optimizations]
PEEPHOLE = true
LOCALTEMPS = true
TAIL_RECURSION = true
TAIL_CALLS = true
#Some general peephole optimizations. For instance the code `a = b
#+ c` typically generates 2 instructions, an ADD and a STORE. This
#optimization removes the STORE and lets the ADD write directly
#into A.
PEEPHOLE = true
#Tail recursive function calls will be turned into loops to avoid
#the overhead of the CALL and RETURN instructions.
TAIL_RECURSION = true
#Make all functions which use neither local arrays nor have locals
#which are seen as possibly uninitialized use the same local sec
#tion. This should be pretty safe compared to other compilers
#which do not check for uninitialized values properly. The problem
#is that there's QC code out there which really doesn't initialize
#some values. This is fine as long as this kind of optimization
#isn't used, but also, only as long as the functions cannot be
#called in a recursive manner. Since it's hard to know whether or
#not an array is actually fully initialized, especially when ini
#tializing it via a loop, we assume functions with arrays to be
#too dangerous for this optimization.
OVERLAP_LOCALS = true
#This promotes locally declared variables to "temps". Meaning when
#a temporary result of an operation has to be stored somewhere, a
#local variable which is not 'alive' at that point can be used to
#keep the result. This can reduce the size of the global section.
#This will not have declared variables overlap, even if it was
#possible.
LOCAL_TEMPS = true
#Causes temporary values which do not need to be backed up on a
#CALL to not be stored in the function's locals-area. With this, a
#CALL to a function may need to back up fewer values and thus exe
#cute faster.
GLOBAL_TEMPS = true
#Don't generate defs for immediate values or even declared con
#stants. Meaning variables which are implicitly constant or qual
#ified as such using the 'const' keyword.
STRIP_CONSTANT_NAMES = true
#Aggressively reuse strings in the string section. When a string
#should be added which is the trailing substring of an already
#existing string, the existing string's tail will be returned
#instead of the new string being added.
#
#For example the following code will only generate 1 string:
#
# print("Hello you!\n");
# print("you!\n"); // trailing substring of "Hello you!\n"
#
#There's however one limitation. Strings are still processed in
#order, so if the above print statements were reversed, this opti
#mization would not happen.
OVERLAP_STRINGS = true
#By default, all parameters of a CALL are copied into the parame
#ter-globals right before the CALL instructions. This is the easi
#est and safest way to translate calls, but also adds a lot of
#unnecessary copying and unnecessary temporary values. This opti
#mization makes operations which are used as a parameter evaluate
#directly into the parameter-global if that is possible, which is
#when there's no other CALL instruction in between.
CALL_STORES = true
#Usually an empty RETURN instruction is added to the end of a void
#typed function. However, additionally after every function a DONE
#instruction is added for several reasons. (For example the qcvm's
#disassemble switch uses it to know when the function ends.). This
#optimization replaces that last RETURN with DONE rather than
#adding the DONE additionally.
VOID_RETURN = true
#Because traditional QC code doesn't allow you to access individ
#ual vector components of a computed vector without storing it in
#a local first, sometimes people multiply it by a constant like
#'0 1 0' to get, in this case, the y component of a vector. This
#optimization will turn such a multiplication into a direct compo
#nent access. If the factor is anything other than 1, a float-mul
#tiplication will be added, which is still faster than a vector
#multiplication.
VECTOR_COMPONENTS = true
#For constant expressions that result in dead code (such as a
#branch whos condition can be evaluated at compile-time), this
#will eliminate the branch and else body (if present) to produce
#more optimal code.
CONST_FOLD_DCE = true
#For constant expressions we can fold them to immediate values.
#this option cannot be disabled or enabled, the compiler forces
#it to stay enabled by ignoring the value entierly. There are
#plans to enable some level of constant fold disabling, but right
#now the language can't function without it. This is merley here
#as an exercise to the reader.
CONST_FOLD = true

View file

@ -1,131 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{85C266A8-7938-4AE6-AB64-428DC32B1ACD}</ProjectGuid>
<RootNamespace>gmqcc</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>.\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IntDir>.\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<TargetName>gmqcc</TargetName>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>.</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IntDir>.</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<TargetName>gmqcc</TargetName>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<ExceptionHandling>false</ExceptionHandling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FloatingPointModel>Fast</FloatingPointModel>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ManifestFile>
</ManifestFile>
<ProgramDatabaseFile>$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<ExceptionHandling>false</ExceptionHandling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FloatingPointModel>Fast</FloatingPointModel>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<ManifestFile>
</ManifestFile>
<ProgramDatabaseFile>$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="asm.c" />
<ClCompile Include="ast.c" />
<ClCompile Include="code.c" />
<ClCompile Include="error.c" />
<ClCompile Include="exec.c" />
<ClCompile Include="ir.c" />
<ClCompile Include="lexer.c" />
<ClCompile Include="main.c" />
<ClCompile Include="parser.c" />
<ClCompile Include="util.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="ast.h" />
<ClInclude Include="execloop.h" />
<ClInclude Include="gmqcc.h" />
<ClInclude Include="ir.h" />
<ClInclude Include="lexer.h" />
</ItemGroup>
<ItemGroup>
<None Include="flags.def" />
<None Include="warns.def" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

2048
intrin.cpp Normal file

File diff suppressed because it is too large Load diff

74
intrin.h Normal file
View file

@ -0,0 +1,74 @@
#ifndef GMQCC_INTRIN_HDR
#define GMQCC_INTRIN_HDR
#include "gmqcc.h"
struct fold;
struct parser_t;
struct ast_function;
struct ast_expression;
struct ast_value;
struct intrin;
struct intrin_func_t {
ast_expression *(intrin::*function)();
const char *name;
const char *alias;
size_t args;
};
struct intrin {
intrin() = default;
intrin(parser_t *parser);
ast_expression *debug_typestring();
ast_expression *do_fold(ast_value *val, ast_expression **exprs);
ast_expression *func_try(size_t offset, const char *compare);
ast_expression *func_self(const char *name, const char *from);
ast_expression *func(const char *name);
protected:
lex_ctx_t ctx() const;
ast_function *value(ast_value **out, const char *name, qc_type vtype);
void reg(ast_value *const value, ast_function *const func);
ast_expression *nullfunc();
ast_expression *isfinite_();
ast_expression *isinf_();
ast_expression *isnan_();
ast_expression *isnormal_();
ast_expression *signbit_();
ast_expression *acosh_();
ast_expression *asinh_();
ast_expression *atanh_();
ast_expression *exp_();
ast_expression *exp2_();
ast_expression *expm1_();
ast_expression *pow_();
ast_expression *mod_();
ast_expression *fabs_();
ast_expression *epsilon_();
ast_expression *nan_();
ast_expression *inf_();
ast_expression *ln_();
ast_expression *log_variant(const char *name, float base);
ast_expression *log_();
ast_expression *log10_();
ast_expression *log2_();
ast_expression *logb_();
ast_expression *shift_variant(const char *name, size_t instr);
ast_expression *lshift();
ast_expression *rshift();
void error(const char *fmt, ...);
private:
parser_t *m_parser;
fold *m_fold;
std::vector<intrin_func_t> m_intrinsics;
std::vector<ast_expression*> m_generated;
};
#endif

3811
ir.c

File diff suppressed because it is too large Load diff

4094
ir.cpp Normal file

File diff suppressed because it is too large Load diff

490
ir.h
View file

@ -1,336 +1,334 @@
/*
* Copyright (C) 2012
* Wolfgang Bumiller
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef GMQCC_IR_HDR
#define GMQCC_IR_HDR
#include "gmqcc.h"
/* ir_value */
/*
* Type large enough to hold all the possible IR flags. This should be
* changed if the static assertion at the end of this file fails.
*/
typedef uint8_t ir_flag_t;
typedef struct
{
struct ir_value;
struct ir_instr;
struct ir_block;
struct ir_function;
struct ir_builder;
struct ir_life_entry_t {
/* both inclusive */
size_t start;
size_t end;
} ir_life_entry_t;
};
struct ir_function_s;
typedef struct ir_value_s {
char *name;
int vtype;
int store;
lex_ctx context;
/* even the IR knows the subtype of a field */
int fieldtype;
/* and the output type of a function */
int outtype;
/* 'const' vs 'var' qualifier */
int cvq;
enum {
IR_FLAG_HAS_ARRAYS = 1 << 0,
IR_FLAG_HAS_UNINITIALIZED = 1 << 1,
IR_FLAG_HAS_GOTO = 1 << 2,
IR_FLAG_INCLUDE_DEF = 1 << 3,
IR_FLAG_ERASABLE = 1 << 4,
IR_FLAG_BLOCK_COVERAGE = 1 << 5,
IR_FLAG_NOREF = 1 << 6,
IR_FLAG_SPLIT_VECTOR = 1 << 7,
struct ir_instr_s **reads;
struct ir_instr_s **writes;
IR_FLAG_LAST,
IR_FLAG_MASK_NO_OVERLAP = (IR_FLAG_HAS_ARRAYS | IR_FLAG_HAS_UNINITIALIZED),
IR_FLAG_MASK_NO_LOCAL_TEMPS = (IR_FLAG_HAS_ARRAYS | IR_FLAG_HAS_UNINITIALIZED)
};
/* constantvalues */
bool hasvalue;
struct ir_value {
ir_value(std::string&& name, store_type storetype, qc_type vtype);
ir_value(ir_function *owner, std::string&& name, store_type storetype, qc_type vtype);
~ir_value();
ir_value *vectorMember(unsigned int member);
bool GMQCC_WARN setFloat(float);
bool GMQCC_WARN setFunc(int);
bool GMQCC_WARN setString(const char*);
bool GMQCC_WARN setVector(vec3_t);
bool GMQCC_WARN setField(ir_value*);
#if 0
bool GMQCC_WARN setInt(int);
#endif
bool lives(size_t at);
void dumpLife(int (*oprintf)(const char*, ...)) const;
void setCodeAddress(int32_t gaddr);
int32_t codeAddress() const;
bool insertLife(size_t idx, ir_life_entry_t);
bool setAlive(size_t position);
bool mergeLife(const ir_value *other);
std::string m_name;
qc_type m_vtype;
store_type m_store;
lex_ctx_t m_context;
qc_type m_fieldtype; // even the IR knows the subtype of a field
qc_type m_outtype; // and the output type of a function
int m_cvq; // 'const' vs 'var' qualifier
ir_flag_t m_flags;
std::vector<ir_instr *> m_reads;
std::vector<ir_instr *> m_writes;
// constant values
bool m_hasvalue;
union {
float vfloat;
int vint;
vector vvec;
int32_t ivec[3];
char *vstring;
struct ir_value_s *vpointer;
struct ir_function_s *vfunc;
} constval;
qcfloat_t vfloat;
int vint;
vec3_t vvec;
int32_t ivec[3];
char *vstring;
ir_value *vpointer;
ir_function *vfunc;
} m_constval;
struct {
int32_t globaladdr;
int32_t name;
/* filled by the local-allocator */
int32_t local;
/* added for members */
int32_t addroffset;
/* to generate field-addresses early */
int32_t fieldaddr;
} code;
int32_t local; // filled by the local-allocator
int32_t addroffset; // added for members
int32_t fieldaddr; // to generate field-addresses early
} m_code;
/* for acessing vectors */
struct ir_value_s *members[3];
struct ir_value_s *memberof;
// for accessing vectors
ir_value *m_members[3];
ir_value *m_memberof;
/* arrays will never overlap with temps */
bool unique_life;
bool m_unique_life; // arrays will never overlap with temps
bool m_locked; // temps living during a CALL must be locked
bool m_callparam;
/* For the temp allocator */
ir_life_entry_t *life;
} ir_value;
std::vector<ir_life_entry_t> m_life; // For the temp allocator
int32_t ir_value_code_addr(const ir_value*);
size_t size() const;
/* ir_value can be a variable, or created by an operation */
ir_value* ir_value_var(const char *name, int st, int vtype);
/* if a result of an operation: the function should store
* it to remember to delete it / garbage collect it
*/
ir_value* ir_value_out(struct ir_function_s *owner, const char *name, int st, int vtype);
void ir_value_delete(ir_value*);
bool ir_value_set_name(ir_value*, const char *name);
ir_value* ir_value_vector_member(ir_value*, unsigned int member);
bool GMQCC_WARN vec_ir_value_find(ir_value **vec, ir_value *what, size_t *idx);
bool GMQCC_WARN ir_value_set_float(ir_value*, float f);
bool GMQCC_WARN ir_value_set_func(ir_value*, int f);
#if 0
bool GMQCC_WARN ir_value_set_int(ir_value*, int i);
#endif
bool GMQCC_WARN ir_value_set_string(ir_value*, const char *s);
bool GMQCC_WARN ir_value_set_vector(ir_value*, vector v);
bool GMQCC_WARN ir_value_set_field(ir_value*, ir_value *fld);
/*bool ir_value_set_pointer_v(ir_value*, ir_value* p); */
/*bool ir_value_set_pointer_i(ir_value*, int i); */
/* merge an instruction into the life-range */
/* returns false if the lifepoint was already known */
bool ir_value_life_merge(ir_value*, size_t);
bool ir_value_life_merge_into(ir_value*, const ir_value*);
/* check if a value lives at a specific point */
bool ir_value_lives(ir_value*, size_t);
/* check if the life-range of 2 values overlaps */
bool ir_values_overlap(const ir_value*, const ir_value*);
void ir_value_dump(ir_value*, int (*oprintf)(const char*,...));
void ir_value_dump_life(const ir_value *self, int (*oprintf)(const char*,...));
void dump(int (*oprintf)(const char*, ...)) const;
};
/* PHI data */
typedef struct ir_phi_entry_s
{
ir_value *value;
struct ir_block_s *from;
} ir_phi_entry_t;
struct ir_phi_entry_t {
ir_value *value;
ir_block *from;
};
/* instruction */
typedef struct ir_instr_s
{
int opcode;
lex_ctx context;
ir_value* (_ops[3]);
struct ir_block_s* (bops[2]);
struct ir_instr {
ir_instr(lex_ctx_t, ir_block *owner, int opcode);
~ir_instr();
ir_phi_entry_t *phi;
ir_value **params;
int m_opcode;
lex_ctx_t m_context;
ir_value *(_m_ops[3]) = { nullptr, nullptr, nullptr };
ir_block *(m_bops[2]) = { nullptr, nullptr };
/* For the temp-allocation */
size_t eid;
std::vector<ir_phi_entry_t> m_phi;
std::vector<ir_value *> m_params;
/* For IFs */
bool likely;
// For the temp-allocation
size_t m_eid = 0;
struct ir_block_s *owner;
} ir_instr;
// For IFs
bool m_likely = true;
ir_instr* ir_instr_new(lex_ctx ctx, struct ir_block_s *owner, int opcode);
void ir_instr_delete(ir_instr*);
bool GMQCC_WARN vec_ir_instr_find(ir_instr **vec, ir_instr *what, size_t *idx);
bool GMQCC_WARN ir_instr_op(ir_instr*, int op, ir_value *value, bool writing);
void ir_instr_dump(ir_instr* in, char *ind, int (*oprintf)(const char*,...));
ir_block *m_owner;
};
/* block */
typedef struct ir_block_s
{
char *label;
lex_ctx context;
bool final; /* once a jump is added we're done */
struct ir_block {
ir_block(ir_function *owner, const std::string& name);
~ir_block();
ir_instr **instr;
struct ir_block_s **entries;
struct ir_block_s **exits;
ir_value **living;
ir_function *m_owner;
std::string m_label;
lex_ctx_t m_context;
bool m_final = false; /* once a jump is added we're done */
std::vector<ir_instr *> m_instr;
std::vector<ir_block *> m_entries;
std::vector<ir_block *> m_exits;
std::vector<ir_value *> m_living;
/* For the temp-allocation */
size_t eid;
bool is_return;
size_t run_id;
size_t m_entry_id = 0;
size_t m_eid = 0;
bool m_is_return = false;
struct ir_function_s *owner;
bool m_generated = false;
size_t m_code_start = 0;
};
bool generated;
size_t code_start;
} ir_block;
ir_block* ir_block_new(struct ir_function_s *owner, const char *label);
void ir_block_delete(ir_block*);
bool ir_block_set_label(ir_block*, const char *label);
ir_value* ir_block_create_binop(ir_block*, lex_ctx, const char *label, int op,
ir_value *left, ir_value *right);
ir_value* ir_block_create_unary(ir_block*, lex_ctx, const char *label, int op,
ir_value *operand);
bool GMQCC_WARN ir_block_create_store_op(ir_block*, lex_ctx, int op, ir_value *target, ir_value *what);
bool GMQCC_WARN ir_block_create_store(ir_block*, lex_ctx, ir_value *target, ir_value *what);
bool GMQCC_WARN ir_block_create_storep(ir_block*, lex_ctx, ir_value *target, ir_value *what);
/* field must be of TYPE_FIELD */
ir_value* ir_block_create_load_from_ent(ir_block*, lex_ctx, const char *label, ir_value *ent, ir_value *field, int outype);
ir_value* ir_block_create_fieldaddress(ir_block*, lex_ctx, const char *label, ir_value *entity, ir_value *field);
ir_value* ir_block_create_binop(ir_block*, lex_ctx_t, const char *label, int op, ir_value *left, ir_value *right);
ir_value* ir_block_create_unary(ir_block*, lex_ctx_t, const char *label, int op, ir_value *operand);
bool GMQCC_WARN ir_block_create_store_op(ir_block*, lex_ctx_t, int op, ir_value *target, ir_value *what);
bool GMQCC_WARN ir_block_create_storep(ir_block*, lex_ctx_t, ir_value *target, ir_value *what);
ir_value* ir_block_create_load_from_ent(ir_block*, lex_ctx_t, const char *label, ir_value *ent, ir_value *field, qc_type outype);
ir_value* ir_block_create_fieldaddress(ir_block*, lex_ctx_t, const char *label, ir_value *entity, ir_value *field);
bool GMQCC_WARN ir_block_create_state_op(ir_block*, lex_ctx_t, ir_value *frame, ir_value *think);
/* This is to create an instruction of the form
* <outtype>%label := opcode a, b
*/
ir_value* ir_block_create_general_instr(ir_block *self, lex_ctx, const char *label,
int op, ir_value *a, ir_value *b, int outype);
ir_value* ir_block_create_add(ir_block*, lex_ctx, const char *label, ir_value *l, ir_value *r);
ir_value* ir_block_create_sub(ir_block*, lex_ctx, const char *label, ir_value *l, ir_value *r);
ir_value* ir_block_create_mul(ir_block*, lex_ctx, const char *label, ir_value *l, ir_value *r);
ir_value* ir_block_create_div(ir_block*, lex_ctx, const char *label, ir_value *l, ir_value *r);
ir_instr* ir_block_create_phi(ir_block*, lex_ctx, const char *label, int vtype);
ir_instr* ir_block_create_phi(ir_block*, lex_ctx_t, const char *label, qc_type vtype);
ir_value* ir_phi_value(ir_instr*);
void ir_phi_add(ir_instr*, ir_block *b, ir_value *v);
ir_instr* ir_block_create_call(ir_block*, lex_ctx, const char *label, ir_value *func, bool noreturn);
ir_instr* ir_block_create_call(ir_block*, lex_ctx_t, const char *label, ir_value *func, bool noreturn);
ir_value* ir_call_value(ir_instr*);
void ir_call_param(ir_instr*, ir_value*);
bool GMQCC_WARN ir_block_create_return(ir_block*, lex_ctx, ir_value *opt_value);
bool GMQCC_WARN ir_block_create_return(ir_block*, lex_ctx_t, ir_value *opt_value);
bool GMQCC_WARN ir_block_create_if(ir_block*, lex_ctx, ir_value *cond,
bool GMQCC_WARN ir_block_create_if(ir_block*, lex_ctx_t, ir_value *cond,
ir_block *ontrue, ir_block *onfalse);
/* A 'goto' is an actual 'goto' coded in QC, whereas
/*
* A 'goto' is an actual 'goto' coded in QC, whereas
* a 'jump' is a virtual construct which simply names the
* next block to go to.
* A goto usually becomes an OP_GOTO in the resulting code,
* whereas a 'jump' usually doesn't add any actual instruction.
*/
bool GMQCC_WARN ir_block_create_jump(ir_block*, lex_ctx, ir_block *to);
bool GMQCC_WARN ir_block_create_goto(ir_block*, lex_ctx, ir_block *to);
void ir_block_dump(ir_block*, char *ind, int (*oprintf)(const char*,...));
bool GMQCC_WARN ir_block_create_jump(ir_block*, lex_ctx_t, ir_block *to);
bool GMQCC_WARN ir_block_create_goto(ir_block*, lex_ctx_t, ir_block *to);
/* function */
struct ir_function {
ir_function(ir_builder *owner, qc_type returntype);
~ir_function();
typedef struct ir_function_s
{
char *name;
int outtype;
int *params;
ir_block **blocks;
ir_builder *m_owner;
int builtin;
std::string m_name;
qc_type m_outtype;
std::vector<int> m_params;
ir_flag_t m_flags = 0;
int m_builtin = 0;
ir_value *value;
std::vector<std::unique_ptr<ir_block>> m_blocks;
/* values generated from operations
/*
* values generated from operations
* which might get optimized away, so anything
* in there needs to be deleted in the dtor.
*/
ir_value **values;
std::vector<std::unique_ptr<ir_value>> m_values;
std::vector<std::unique_ptr<ir_value>> m_locals; /* locally defined variables */
ir_value *m_value = nullptr;
/* locally defined variables */
ir_value **locals;
size_t m_allocated_locals = 0;
size_t m_globaltemps = 0;
size_t allocated_locals;
ir_block* m_first = nullptr;
ir_block* m_last = nullptr;
ir_block* first;
ir_block* last;
lex_ctx_t m_context;
lex_ctx context;
/* for prototypes - first we generate all the
/*
* for prototypes - first we generate all the
* globals, and we remember teh function-defs
* so we can later fill in the entry pos
*
* remember the ID:
*/
qcint code_function_def;
qcint_t m_code_function_def = -1;
/* for temp allocation */
size_t run_id;
size_t m_run_id = 0;
struct ir_builder_s *owner;
} ir_function;
/* vararg support: */
size_t m_max_varargs = 0;
};
ir_function* ir_function_new(struct ir_builder_s *owner, int returntype);
void ir_function_delete(ir_function*);
void ir_function_collect_value(ir_function*, ir_value *value);
bool ir_function_set_name(ir_function*, const char *name);
ir_value* ir_function_create_local(ir_function *self, const char *name, int vtype, bool param);
ir_value* ir_function_create_local(ir_function *self, const std::string& name, qc_type vtype, bool param);
bool GMQCC_WARN ir_function_finalize(ir_function*);
/*
bool ir_function_naive_phi(ir_function*);
bool ir_function_enumerate(ir_function*);
bool ir_function_calculate_liferanges(ir_function*);
*/
ir_block* ir_function_create_block(lex_ctx ctx, ir_function*, const char *label);
void ir_function_dump(ir_function*, char *ind, int (*oprintf)(const char*,...));
ir_block* ir_function_create_block(lex_ctx_t ctx, ir_function*, const char *label);
/* builder */
#define IR_HT_SIZE 1024
typedef struct ir_builder_s
{
char *name;
ir_function **functions;
ir_value **globals;
ir_value **fields;
#define IR_HT_SIZE 1024
#define IR_MAX_VINSTR_TEMPS 2
ht htfunctions;
ht htglobals;
ht htfields;
struct ir_builder {
ir_builder(const std::string& modulename);
~ir_builder();
ir_value **extparams;
ir_function *createFunction(const std::string &name, qc_type outtype);
ir_value *createGlobal(const std::string &name, qc_type vtype);
ir_value *createField(const std::string &name, qc_type vtype);
ir_value *get_va_count();
bool generate(const char *filename);
void dump(int (*oprintf)(const char*, ...)) const;
const char **filenames;
qcint *filestrings;
/* we cache the #IMMEDIATE string here */
qcint str_immediate;
} ir_builder;
ir_value *generateExtparamProto();
void generateExtparam();
ir_builder* ir_builder_new(const char *modulename);
void ir_builder_delete(ir_builder*);
ir_value *literalFloat(float value, bool add_to_list);
bool ir_builder_set_name(ir_builder *self, const char *name);
std::string m_name;
std::vector<std::unique_ptr<ir_function>> m_functions;
std::vector<std::unique_ptr<ir_value>> m_globals;
std::vector<std::unique_ptr<ir_value>> m_fields;
// for reusing them in vector-splits, TODO: sort this or use a radix-tree
std::vector<ir_value*> m_const_floats;
ir_function* ir_builder_get_function(ir_builder*, const char *fun);
ir_function* ir_builder_create_function(ir_builder*, const char *name, int outtype);
ht m_htfunctions;
ht m_htglobals;
ht m_htfields;
ir_value* ir_builder_get_global(ir_builder*, const char *fun);
ir_value* ir_builder_create_global(ir_builder*, const char *name, int vtype);
ir_value* ir_builder_get_field(ir_builder*, const char *fun);
ir_value* ir_builder_create_field(ir_builder*, const char *name, int vtype);
// extparams' ir_values reference the ones from extparam_protos
std::vector<std::unique_ptr<ir_value>> m_extparam_protos;
std::vector<ir_value*> m_extparams;
bool ir_builder_generate(ir_builder *self, const char *filename);
// the highest func->allocated_locals
size_t m_max_locals = 0;
size_t m_max_globaltemps = 0;
uint32_t m_first_common_local = 0;
uint32_t m_first_common_globaltemp = 0;
void ir_builder_dump(ir_builder*, int (*oprintf)(const char*, ...));
std::vector<const char*> m_filenames;
std::vector<qcint_t> m_filestrings;
/* This code assumes 32 bit floats while generating binary */
extern int check_int_and_float_size
[ (sizeof(int32_t) == sizeof(qcfloat)) ? 1 : -1 ];
// we cache the #IMMEDIATE string here
qcint_t m_str_immediate = 0;
// there should just be this one nil
ir_value *m_nil;
ir_value *m_reserved_va_count = nullptr;
ir_value *m_coverage_func = nullptr;
/* some virtual instructions require temps, and their code is isolated
* so that we don't need to keep track of their liveness.
*/
ir_value *m_vinstr_temp[IR_MAX_VINSTR_TEMPS];
/* code generator */
std::unique_ptr<code_t> m_code;
private:
qcint_t filestring(const char *filename);
bool generateGlobal(ir_value*, bool is_local);
bool generateGlobalFunction(ir_value*);
bool generateGlobalFunctionCode(ir_value*);
bool generateFunctionLocals(ir_value*);
};
/*
* This code assumes 32 bit floats while generating binary
* Blub: don't use extern here, it's annoying and shows up in nm
* for some reason :P
*/
typedef int static_assert_is_32bit_float [(sizeof(int32_t) == 4) ? 1 : -1];
typedef int static_assert_is_32bit_integer[(sizeof(qcfloat_t) == 4) ? 1 : -1];
/*
* If the condition creates a situation where this becomes -1 size it means there are
* more IR_FLAGs than the type ir_flag_t is capable of holding. So either eliminate
* the IR flag count or change the ir_flag_t typedef to a type large enough to accomodate
* all the flags.
*/
typedef int static_assert_is_ir_flag_safe [((IR_FLAG_LAST) <= (ir_flag_t)(-1)) ? 1 : -1];
#endif

File diff suppressed because it is too large Load diff

380
lexer.h
View file

@ -1,60 +1,19 @@
/*
* Copyright (C) 2012
* Wolfgang Bumiller
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef GMQCC_LEXER_HDR
#define GMQCC_LEXER_HDR
#include "gmqcc.h"
typedef struct token_s token;
#include "ast.h"
struct token_s {
int ttype;
char *value;
union {
vector v;
int i;
double f;
int t; /* type */
} constval;
#if 0
struct token_s *next;
struct token_s *prev;
#endif
lex_ctx ctx;
struct token {
int ttype;
char *value;
union {
vec3_t v;
int i;
qcfloat_t f;
qc_type t; /* type */
} constval;
lex_ctx_t ctx;
};
#if 0
token* token_new();
void token_delete(token*);
token* token_copy(const token *cp);
void token_delete_all(token *t);
token* token_copy_all(const token *cp);
#endif
/* Lexer
*
*/
@ -73,6 +32,13 @@ enum {
TOKEN_DOTS, /* 3 dots, ... */
TOKEN_ATTRIBUTE_OPEN, /* [[ */
TOKEN_ATTRIBUTE_CLOSE, /* ]] */
TOKEN_VA_ARGS, /* for the ftepp only */
TOKEN_VA_ARGS_ARRAY, /* for the ftepp only */
TOKEN_VA_COUNT, /* to get the count of vaargs */
TOKEN_STRINGCONST, /* not the typename but an actual "string" */
TOKEN_CHARCONST,
TOKEN_VECTORCONST,
@ -82,7 +48,11 @@ enum {
TOKEN_WHITE,
TOKEN_EOL,
TOKEN_EOF,
/* if we add additional tokens before this, the exposed API
* should not be broken anyway, but EOF/ERROR/... should
* still be at the bottom
*/
TOKEN_EOF = 1024,
/* We use '< TOKEN_ERROR', so TOKEN_FATAL must come after it and any
* other error related tokens as well
@ -91,41 +61,42 @@ enum {
TOKEN_FATAL /* internal error, eg out of memory */
};
typedef struct {
struct frame_macro {
char *name;
int value;
} frame_macro;
int value;
};
typedef struct {
FILE *file;
const char *open_string;
size_t open_string_length;
size_t open_string_pos;
struct lex_file {
FILE *file;
const char *open_string;
size_t open_string_length;
size_t open_string_pos;
char *name;
size_t line;
size_t sline; /* line at the start of a token */
char *name;
size_t line;
size_t sline; /* line at the start of a token */
size_t column;
char peek[256];
size_t peekpos;
int peek[256];
size_t peekpos;
bool eof;
bool eof;
token tok; /* not a pointer anymore */
token tok; /* not a pointer anymore */
struct {
bool noops;
bool nodigraphs; /* used when lexing string constants */
bool preprocessing; /* whitespace and EOLs become actual tokens */
bool mergelines; /* backslash at the end of a line escapes the newline */
} flags;
struct {
unsigned noops:1;
unsigned nodigraphs:1; /* used when lexing string constants */
unsigned preprocessing:1; /* whitespace and EOLs become actual tokens */
unsigned mergelines:1; /* backslash at the end of a line escapes the newline */
} flags; /* sizeof == 1 */
int framevalue;
frame_macro *frames;
char *modelname;
frame_macro *frames;
char *modelname;
size_t push_line;
} lex_file;
size_t push_line;
};
lex_file* lex_open (const char *file);
lex_file* lex_open_string(const char *str, size_t len, const char *name);
@ -145,179 +116,188 @@ enum {
#define OP_SUFFIX 1
#define OP_PREFIX 2
typedef struct {
struct oper_info {
const char *op;
unsigned int operands;
unsigned int id;
unsigned int assoc;
signed int prec;
unsigned int flags;
} oper_info;
bool folds;
};
#define opid1(a) (a)
#define opid2(a,b) ((a<<8)|b)
#define opid3(a,b,c) ((a<<16)|(b<<8)|c)
/*
* Explicit uint8_t casts since the left operand of shift operator cannot
* be negative, even though it won't happen, this supresses the future
* possibility.
*/
#define opid1(a) ((uint8_t)a)
#define opid2(a,b) (((uint8_t)a<<8) |(uint8_t)b)
#define opid3(a,b,c) (((uint8_t)a<<16)|((uint8_t)b<<8)|(uint8_t)c)
static const oper_info c_operators[] = {
{ "(", 0, opid1('('), ASSOC_LEFT, 99, OP_PREFIX}, /* paren expression - non function call */
{ "(", 0, opid1('('), ASSOC_LEFT, 99, OP_PREFIX, false}, /* paren expression - non function call */
{ "_length", 1, opid3('l','e','n'), ASSOC_RIGHT, 98, OP_PREFIX, true},
{ "++", 1, opid3('S','+','+'), ASSOC_LEFT, 15, OP_SUFFIX},
{ "--", 1, opid3('S','-','-'), ASSOC_LEFT, 15, OP_SUFFIX},
{ ".", 2, opid1('.'), ASSOC_LEFT, 15, 0 },
{ "(", 0, opid1('('), ASSOC_LEFT, 15, 0 }, /* function call */
{ "[", 2, opid1('['), ASSOC_LEFT, 15, 0 }, /* array subscript */
{ "++", 1, opid3('S','+','+'), ASSOC_LEFT, 17, OP_SUFFIX, false},
{ "--", 1, opid3('S','-','-'), ASSOC_LEFT, 17, OP_SUFFIX, false},
{ ".", 2, opid1('.'), ASSOC_LEFT, 17, 0, false},
{ "(", 0, opid1('('), ASSOC_LEFT, 17, 0, false}, /* function call */
{ "[", 2, opid1('['), ASSOC_LEFT, 17, 0, false}, /* array subscript */
{ "!", 1, opid2('!', 'P'), ASSOC_RIGHT, 14, OP_PREFIX },
{ "~", 1, opid2('~', 'P'), ASSOC_RIGHT, 14, OP_PREFIX },
{ "+", 1, opid2('+','P'), ASSOC_RIGHT, 14, OP_PREFIX },
{ "-", 1, opid2('-','P'), ASSOC_RIGHT, 14, OP_PREFIX },
{ "++", 1, opid3('+','+','P'), ASSOC_RIGHT, 14, OP_PREFIX },
{ "--", 1, opid3('-','-','P'), ASSOC_RIGHT, 14, OP_PREFIX },
/* { "&", 1, opid2('&','P'), ASSOC_RIGHT, 14, OP_PREFIX }, */
{ "++", 1, opid3('+','+','P'), ASSOC_RIGHT, 16, OP_PREFIX, false},
{ "--", 1, opid3('-','-','P'), ASSOC_RIGHT, 16, OP_PREFIX, false},
{ "*", 2, opid1('*'), ASSOC_LEFT, 13, 0 },
{ "/", 2, opid1('/'), ASSOC_LEFT, 13, 0 },
{ "%", 2, opid1('%'), ASSOC_LEFT, 13, 0 },
{ "**", 2, opid2('*','*'), ASSOC_RIGHT, 14, 0, true},
{ "!", 1, opid2('!','P'), ASSOC_RIGHT, 14, OP_PREFIX, true},
{ "~", 1, opid2('~','P'), ASSOC_RIGHT, 14, OP_PREFIX, true},
{ "+", 1, opid2('+','P'), ASSOC_RIGHT, 14, OP_PREFIX, false},
{ "-", 1, opid2('-','P'), ASSOC_RIGHT, 14, OP_PREFIX, true},
/* { "&", 1, opid2('&','P'), ASSOC_RIGHT, 14, OP_PREFIX, false}, */
{ "+", 2, opid1('+'), ASSOC_LEFT, 12, 0 },
{ "-", 2, opid1('-'), ASSOC_LEFT, 12, 0 },
{ "*", 2, opid1('*'), ASSOC_LEFT, 13, 0, true},
{ "/", 2, opid1('/'), ASSOC_LEFT, 13, 0, true},
{ "%", 2, opid1('%'), ASSOC_LEFT, 13, 0, true},
{ "><", 2, opid2('>','<'), ASSOC_LEFT, 13, 0, true},
{ "<<", 2, opid2('<','<'), ASSOC_LEFT, 11, 0 },
{ ">>", 2, opid2('>','>'), ASSOC_LEFT, 11, 0 },
{ "+", 2, opid1('+'), ASSOC_LEFT, 12, 0, true},
{ "-", 2, opid1('-'), ASSOC_LEFT, 12, 0, true},
{ "<", 2, opid1('<'), ASSOC_LEFT, 10, 0 },
{ ">", 2, opid1('>'), ASSOC_LEFT, 10, 0 },
{ "<=", 2, opid2('<','='), ASSOC_LEFT, 10, 0 },
{ ">=", 2, opid2('>','='), ASSOC_LEFT, 10, 0 },
{ "<<", 2, opid2('<','<'), ASSOC_LEFT, 11, 0, true},
{ ">>", 2, opid2('>','>'), ASSOC_LEFT, 11, 0, true},
{ "==", 2, opid2('=','='), ASSOC_LEFT, 9, 0 },
{ "!=", 2, opid2('!','='), ASSOC_LEFT, 9, 0 },
{ "<", 2, opid1('<'), ASSOC_LEFT, 10, 0, false},
{ ">", 2, opid1('>'), ASSOC_LEFT, 10, 0, false},
{ "<=>", 2, opid3('<','=','>'), ASSOC_LEFT, 10, 0, true},
{ "<=", 2, opid2('<','='), ASSOC_LEFT, 10, 0, false},
{ ">=", 2, opid2('>','='), ASSOC_LEFT, 10, 0, false},
{ "&", 2, opid1('&'), ASSOC_LEFT, 8, 0 },
{ "==", 2, opid2('=','='), ASSOC_LEFT, 9, 0, true},
{ "!=", 2, opid2('!','='), ASSOC_LEFT, 9, 0, true},
{ "^", 2, opid1('^'), ASSOC_LEFT, 7, 0 },
{ "&", 2, opid1('&'), ASSOC_LEFT, 8, 0, true},
{ "|", 2, opid1('|'), ASSOC_LEFT, 6, 0 },
{ "^", 2, opid1('^'), ASSOC_LEFT, 7, 0, true},
{ "&&", 2, opid2('&','&'), ASSOC_LEFT, 5, 0 },
{ "|", 2, opid1('|'), ASSOC_LEFT, 6, 0, true},
{ "||", 2, opid2('|','|'), ASSOC_LEFT, 4, 0 },
{ "&&", 2, opid2('&','&'), ASSOC_LEFT, 5, 0, true},
{ "?", 3, opid2('?',':'), ASSOC_RIGHT, 3, 0 },
{ "||", 2, opid2('|','|'), ASSOC_LEFT, 4, 0, true},
{ "=", 2, opid1('='), ASSOC_RIGHT, 2, 0 },
{ "+=", 2, opid2('+','='), ASSOC_RIGHT, 2, 0 },
{ "-=", 2, opid2('-','='), ASSOC_RIGHT, 2, 0 },
{ "*=", 2, opid2('*','='), ASSOC_RIGHT, 2, 0 },
{ "/=", 2, opid2('/','='), ASSOC_RIGHT, 2, 0 },
{ "%=", 2, opid2('%','='), ASSOC_RIGHT, 2, 0 },
{ ">>=", 2, opid3('>','>','='), ASSOC_RIGHT, 2, 0 },
{ "<<=", 2, opid3('<','<','='), ASSOC_RIGHT, 2, 0 },
{ "&=", 2, opid2('&','='), ASSOC_RIGHT, 2, 0 },
{ "^=", 2, opid2('^','='), ASSOC_RIGHT, 2, 0 },
{ "|=", 2, opid2('|','='), ASSOC_RIGHT, 2, 0 },
{ "?", 3, opid2('?',':'), ASSOC_RIGHT, 3, 0, true},
{ ":", 0, opid2(':','?'), ASSOC_RIGHT, 1, 0 },
{ "=", 2, opid1('='), ASSOC_RIGHT, 2, 0, false},
{ "+=", 2, opid2('+','='), ASSOC_RIGHT, 2, 0, false},
{ "-=", 2, opid2('-','='), ASSOC_RIGHT, 2, 0, false},
{ "*=", 2, opid2('*','='), ASSOC_RIGHT, 2, 0, false},
{ "/=", 2, opid2('/','='), ASSOC_RIGHT, 2, 0, false},
{ "%=", 2, opid2('%','='), ASSOC_RIGHT, 2, 0, false},
{ ">>=", 2, opid3('>','>','='), ASSOC_RIGHT, 2, 0, false},
{ "<<=", 2, opid3('<','<','='), ASSOC_RIGHT, 2, 0, false},
{ "&=", 2, opid2('&','='), ASSOC_RIGHT, 2, 0, false},
{ "^=", 2, opid2('^','='), ASSOC_RIGHT, 2, 0, false},
{ "|=", 2, opid2('|','='), ASSOC_RIGHT, 2, 0, false},
{ ",", 2, opid1(','), ASSOC_LEFT, 0, 0 }
{ ":", 0, opid2(':','?'), ASSOC_RIGHT, 1, 0, false},
{ ",", 2, opid1(','), ASSOC_LEFT, 0, 0, false}
};
static const size_t c_operator_count = (sizeof(c_operators) / sizeof(c_operators[0]));
static const oper_info fte_operators[] = {
{ "(", 0, opid1('('), ASSOC_LEFT, 99, OP_PREFIX}, /* paren expression - non function call */
{ "(", 0, opid1('('), ASSOC_LEFT, 99, OP_PREFIX, false}, /* paren expression - non function call */
{ "++", 1, opid3('S','+','+'), ASSOC_LEFT, 15, OP_SUFFIX},
{ "--", 1, opid3('S','-','-'), ASSOC_LEFT, 15, OP_SUFFIX},
{ ".", 2, opid1('.'), ASSOC_LEFT, 15, 0 },
{ "(", 0, opid1('('), ASSOC_LEFT, 15, 0 }, /* function call */
{ "[", 2, opid1('['), ASSOC_LEFT, 15, 0 }, /* array subscript */
{ "++", 1, opid3('S','+','+'), ASSOC_LEFT, 15, OP_SUFFIX, false},
{ "--", 1, opid3('S','-','-'), ASSOC_LEFT, 15, OP_SUFFIX, false},
{ ".", 2, opid1('.'), ASSOC_LEFT, 15, 0, false},
{ "(", 0, opid1('('), ASSOC_LEFT, 15, 0, false}, /* function call */
{ "[", 2, opid1('['), ASSOC_LEFT, 15, 0, false}, /* array subscript */
{ "!", 1, opid2('!', 'P'), ASSOC_RIGHT, 14, OP_PREFIX },
{ "+", 1, opid2('+','P'), ASSOC_RIGHT, 14, OP_PREFIX },
{ "-", 1, opid2('-','P'), ASSOC_RIGHT, 14, OP_PREFIX },
{ "++", 1, opid3('+','+','P'), ASSOC_RIGHT, 14, OP_PREFIX },
{ "--", 1, opid3('-','-','P'), ASSOC_RIGHT, 14, OP_PREFIX },
{ "!", 1, opid2('!','P'), ASSOC_RIGHT, 14, OP_PREFIX, true},
{ "+", 1, opid2('+','P'), ASSOC_RIGHT, 14, OP_PREFIX, false},
{ "-", 1, opid2('-','P'), ASSOC_RIGHT, 14, OP_PREFIX, true},
{ "++", 1, opid3('+','+','P'), ASSOC_RIGHT, 14, OP_PREFIX, false},
{ "--", 1, opid3('-','-','P'), ASSOC_RIGHT, 14, OP_PREFIX, false},
{ "*", 2, opid1('*'), ASSOC_LEFT, 13, 0 },
{ "/", 2, opid1('/'), ASSOC_LEFT, 13, 0 },
{ "&", 2, opid1('&'), ASSOC_LEFT, 13, 0 },
{ "|", 2, opid1('|'), ASSOC_LEFT, 13, 0 },
{ "*", 2, opid1('*'), ASSOC_LEFT, 13, 0, true},
{ "/", 2, opid1('/'), ASSOC_LEFT, 13, 0, true},
{ "&", 2, opid1('&'), ASSOC_LEFT, 13, 0, true},
{ "|", 2, opid1('|'), ASSOC_LEFT, 13, 0, true},
{ "+", 2, opid1('+'), ASSOC_LEFT, 12, 0 },
{ "-", 2, opid1('-'), ASSOC_LEFT, 12, 0 },
{ "+", 2, opid1('+'), ASSOC_LEFT, 12, 0, true},
{ "-", 2, opid1('-'), ASSOC_LEFT, 12, 0, true},
{ "<", 2, opid1('<'), ASSOC_LEFT, 10, 0 },
{ ">", 2, opid1('>'), ASSOC_LEFT, 10, 0 },
{ "<=", 2, opid2('<','='), ASSOC_LEFT, 10, 0 },
{ ">=", 2, opid2('>','='), ASSOC_LEFT, 10, 0 },
{ "==", 2, opid2('=','='), ASSOC_LEFT, 10, 0 },
{ "!=", 2, opid2('!','='), ASSOC_LEFT, 10, 0 },
{ "<<", 2, opid2('<','<'), ASSOC_LEFT, 11, 0, true},
{ ">>", 2, opid2('>','>'), ASSOC_LEFT, 11, 0, true},
{ "?", 3, opid2('?',':'), ASSOC_RIGHT, 9, 0 },
{ "<", 2, opid1('<'), ASSOC_LEFT, 10, 0, false},
{ ">", 2, opid1('>'), ASSOC_LEFT, 10, 0, false},
{ "<=", 2, opid2('<','='), ASSOC_LEFT, 10, 0, false},
{ ">=", 2, opid2('>','='), ASSOC_LEFT, 10, 0, false},
{ "==", 2, opid2('=','='), ASSOC_LEFT, 10, 0, true},
{ "!=", 2, opid2('!','='), ASSOC_LEFT, 10, 0, true},
{ "=", 2, opid1('='), ASSOC_RIGHT, 8, 0 },
{ "+=", 2, opid2('+','='), ASSOC_RIGHT, 8, 0 },
{ "-=", 2, opid2('-','='), ASSOC_RIGHT, 8, 0 },
{ "*=", 2, opid2('*','='), ASSOC_RIGHT, 8, 0 },
{ "/=", 2, opid2('/','='), ASSOC_RIGHT, 8, 0 },
{ "%=", 2, opid2('%','='), ASSOC_RIGHT, 8, 0 },
{ "&=", 2, opid2('&','='), ASSOC_RIGHT, 8, 0 },
{ "|=", 2, opid2('|','='), ASSOC_RIGHT, 8, 0 },
{ "&~=", 2, opid3('&','~','='), ASSOC_RIGHT, 8, 0 },
{ "?", 3, opid2('?',':'), ASSOC_RIGHT, 9, 0, true},
{ "&&", 2, opid2('&','&'), ASSOC_LEFT, 5, 0 },
{ "||", 2, opid2('|','|'), ASSOC_LEFT, 5, 0 },
{ "=", 2, opid1('='), ASSOC_RIGHT, 8, 0, false},
{ "+=", 2, opid2('+','='), ASSOC_RIGHT, 8, 0, false},
{ "-=", 2, opid2('-','='), ASSOC_RIGHT, 8, 0, false},
{ "*=", 2, opid2('*','='), ASSOC_RIGHT, 8, 0, false},
{ "/=", 2, opid2('/','='), ASSOC_RIGHT, 8, 0, false},
{ "%=", 2, opid2('%','='), ASSOC_RIGHT, 8, 0, false},
{ "&=", 2, opid2('&','='), ASSOC_RIGHT, 8, 0, false},
{ "|=", 2, opid2('|','='), ASSOC_RIGHT, 8, 0, false},
{ "&~=", 2, opid3('&','~','='), ASSOC_RIGHT, 8, 0, false},
{ "&&", 2, opid2('&','&'), ASSOC_LEFT, 5, 0, true},
{ "||", 2, opid2('|','|'), ASSOC_LEFT, 5, 0, true},
/* Leave precedence 3 for : with -fcorrect-ternary */
{ ",", 2, opid1(','), ASSOC_LEFT, 2, 0 },
{ ":", 0, opid2(':','?'), ASSOC_RIGHT, 1, 0 }
{ ",", 2, opid1(','), ASSOC_LEFT, 2, 0, false},
{ ":", 0, opid2(':','?'), ASSOC_RIGHT, 1, 0, false}
};
static const size_t fte_operator_count = (sizeof(fte_operators) / sizeof(fte_operators[0]));
static const oper_info qcc_operators[] = {
{ "(", 0, opid1('('), ASSOC_LEFT, 99, OP_PREFIX}, /* paren expression - non function call */
{ "(", 0, opid1('('), ASSOC_LEFT, 99, OP_PREFIX, false}, /* paren expression - non function call */
{ ".", 2, opid1('.'), ASSOC_LEFT, 15, 0 },
{ "(", 0, opid1('('), ASSOC_LEFT, 15, 0 }, /* function call */
{ "[", 2, opid1('['), ASSOC_LEFT, 15, 0 }, /* array subscript */
{ ".", 2, opid1('.'), ASSOC_LEFT, 15, 0, false},
{ "(", 0, opid1('('), ASSOC_LEFT, 15, 0, false}, /* function call */
{ "[", 2, opid1('['), ASSOC_LEFT, 15, 0, false}, /* array subscript */
{ "!", 1, opid2('!', 'P'), ASSOC_RIGHT, 14, OP_PREFIX },
{ "+", 1, opid2('+','P'), ASSOC_RIGHT, 14, OP_PREFIX },
{ "-", 1, opid2('-','P'), ASSOC_RIGHT, 14, OP_PREFIX },
{ "!", 1, opid2('!','P'), ASSOC_RIGHT, 14, OP_PREFIX, true},
{ "+", 1, opid2('+','P'), ASSOC_RIGHT, 14, OP_PREFIX, false},
{ "-", 1, opid2('-','P'), ASSOC_RIGHT, 14, OP_PREFIX, true},
{ "*", 2, opid1('*'), ASSOC_LEFT, 13, 0 },
{ "/", 2, opid1('/'), ASSOC_LEFT, 13, 0 },
{ "&", 2, opid1('&'), ASSOC_LEFT, 13, 0 },
{ "|", 2, opid1('|'), ASSOC_LEFT, 13, 0 },
{ "*", 2, opid1('*'), ASSOC_LEFT, 13, 0, true},
{ "/", 2, opid1('/'), ASSOC_LEFT, 13, 0, true},
{ "&", 2, opid1('&'), ASSOC_LEFT, 13, 0, true},
{ "|", 2, opid1('|'), ASSOC_LEFT, 13, 0, true},
{ "+", 2, opid1('+'), ASSOC_LEFT, 12, 0 },
{ "-", 2, opid1('-'), ASSOC_LEFT, 12, 0 },
{ "+", 2, opid1('+'), ASSOC_LEFT, 12, 0, true},
{ "-", 2, opid1('-'), ASSOC_LEFT, 12, 0, true},
{ "<", 2, opid1('<'), ASSOC_LEFT, 10, 0 },
{ ">", 2, opid1('>'), ASSOC_LEFT, 10, 0 },
{ "<=", 2, opid2('<','='), ASSOC_LEFT, 10, 0 },
{ ">=", 2, opid2('>','='), ASSOC_LEFT, 10, 0 },
{ "==", 2, opid2('=','='), ASSOC_LEFT, 10, 0 },
{ "!=", 2, opid2('!','='), ASSOC_LEFT, 10, 0 },
{ "<", 2, opid1('<'), ASSOC_LEFT, 10, 0, false},
{ ">", 2, opid1('>'), ASSOC_LEFT, 10, 0, false},
{ "<=", 2, opid2('<','='), ASSOC_LEFT, 10, 0, false},
{ ">=", 2, opid2('>','='), ASSOC_LEFT, 10, 0, false},
{ "==", 2, opid2('=','='), ASSOC_LEFT, 10, 0, true},
{ "!=", 2, opid2('!','='), ASSOC_LEFT, 10, 0, true},
{ "=", 2, opid1('='), ASSOC_RIGHT, 8, 0 },
{ "+=", 2, opid2('+','='), ASSOC_RIGHT, 8, 0 },
{ "-=", 2, opid2('-','='), ASSOC_RIGHT, 8, 0 },
{ "*=", 2, opid2('*','='), ASSOC_RIGHT, 8, 0 },
{ "/=", 2, opid2('/','='), ASSOC_RIGHT, 8, 0 },
{ "%=", 2, opid2('%','='), ASSOC_RIGHT, 8, 0 },
{ "&=", 2, opid2('&','='), ASSOC_RIGHT, 8, 0 },
{ "|=", 2, opid2('|','='), ASSOC_RIGHT, 8, 0 },
{ "=", 2, opid1('='), ASSOC_RIGHT, 8, 0, false},
{ "+=", 2, opid2('+','='), ASSOC_RIGHT, 8, 0, false},
{ "-=", 2, opid2('-','='), ASSOC_RIGHT, 8, 0, false},
{ "*=", 2, opid2('*','='), ASSOC_RIGHT, 8, 0, false},
{ "/=", 2, opid2('/','='), ASSOC_RIGHT, 8, 0, false},
{ "%=", 2, opid2('%','='), ASSOC_RIGHT, 8, 0, false},
{ "&=", 2, opid2('&','='), ASSOC_RIGHT, 8, 0, false},
{ "|=", 2, opid2('|','='), ASSOC_RIGHT, 8, 0, false},
{ "&&", 2, opid2('&','&'), ASSOC_LEFT, 5, 0 },
{ "||", 2, opid2('|','|'), ASSOC_LEFT, 5, 0 },
{ "&&", 2, opid2('&','&'), ASSOC_LEFT, 5, 0, true},
{ "||", 2, opid2('|','|'), ASSOC_LEFT, 5, 0, true},
{ ",", 2, opid1(','), ASSOC_LEFT, 2, 0 },
{ ",", 2, opid1(','), ASSOC_LEFT, 2, 0, false},
};
static const size_t qcc_operator_count = (sizeof(qcc_operators) / sizeof(qcc_operators[0]));
extern const oper_info *operators;
extern size_t operator_count;
void lexerror(lex_file*, const char *fmt, ...);
#endif

View file

@ -1,40 +1,20 @@
/*
* Copyright (C) 2012
* Dale Weiler
* Wolfgang Bumiller
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <stdlib.h>
#include <string.h>
#include "gmqcc.h"
#include "lexer.h"
#include "parser.h"
/* TODO: cleanup this whole file .. it's a fuckign mess */
/* set by the standard */
const oper_info *operators = NULL;
size_t operator_count = 0;
static bool opts_output_wasset = false;
typedef struct { char *filename; int type; } argitem;
typedef struct { char *name; char *value; } ppitem;
static argitem *items = NULL;
static ppitem *ppems = NULL;
const oper_info *operators = nullptr;
size_t operator_count = 0;
static bool opts_output_wasset = false;
struct argitem { char *filename; int type; };
struct ppitem { char *name; char *value; };
static argitem *items = nullptr;
static ppitem *ppems = nullptr;
#define TYPE_QC 0
#define TYPE_ASM 1
@ -42,8 +22,8 @@ static ppitem *ppems = NULL;
static const char *app_name;
static void version() {
con_out("GMQCC %d.%d.%d Built %s %s\n",
static void version(void) {
con_out("GMQCC %d.%d.%d Built %s %s\n" GMQCC_DEV_VERSION_STRING,
GMQCC_VERSION_MAJOR,
GMQCC_VERSION_MINOR,
GMQCC_VERSION_PATCH,
@ -52,15 +32,15 @@ static void version() {
);
}
static int usage() {
static int usage(void) {
con_out("usage: %s [options] [files...]", app_name);
con_out("options:\n"
" -h, --help show this help message\n"
" -debug turns on compiler debug messages\n"
" -memchk turns on compiler memory leak check\n");
" -debug turns on compiler debug messages\n");
con_out(" -o, --output=file output file, defaults to progs.dat\n"
" -s filename add a progs.src file to be used\n");
con_out(" -E stop after preprocessing\n");
con_out(" -q, --quiet be less verbose\n");
con_out(" -config file use the specified ini file\n");
con_out(" -std=standard select one of the following standards\n"
" -std=qcc original QuakeC\n"
@ -81,6 +61,8 @@ static int usage() {
" -Ono-<name> disable specific optimization\n"
" -Ohelp list optimizations\n");
con_out(" -force-crc=num force a specific checksum into the header\n");
con_out(" -state-fps=num emulate OP_STATE with the specified FPS\n");
con_out(" -coverage add coverage support\n");
return -1;
}
@ -135,18 +117,16 @@ static bool options_long_gcc(const char *optname, int *argc_, char ***argv_, cha
return options_long_witharg_all(optname, argc_, argv_, out, 1, false);
}
static bool options_parse(int argc, char **argv) {
static bool options_parse(int argc, char **argv, bool *has_progs_src) {
bool argend = false;
size_t itr;
char buffer[1024];
char *redirout = (char*)stdout;
char *redirerr = (char*)stderr;
char *config = NULL;
char buffer[1024];
char *config = nullptr;
while (!argend && argc > 1) {
char *argarg;
argitem item;
ppitem macro;
ppitem macro;
++argv;
--argc;
@ -156,14 +136,31 @@ static bool options_parse(int argc, char **argv) {
if (options_long_gcc("std", &argc, &argv, &argarg)) {
if (!strcmp(argarg, "gmqcc") || !strcmp(argarg, "default")) {
opts_set(opts.flags, ADJUST_VECTOR_FIELDS, true);
opts.standard = COMPILER_GMQCC;
opts_set(opts.flags, ADJUST_VECTOR_FIELDS, true);
opts_set(opts.flags, CORRECT_LOGIC, true);
opts_set(opts.flags, SHORT_LOGIC, true);
opts_set(opts.flags, UNTYPED_NIL, true);
opts_set(opts.flags, VARIADIC_ARGS, true);
opts_set(opts.flags, FALSE_EMPTY_STRINGS, false);
opts_set(opts.flags, TRUE_EMPTY_STRINGS, true);
opts_set(opts.flags, LOOP_LABELS, true);
opts_set(opts.flags, TRANSLATABLE_STRINGS, true);
opts_set(opts.flags, INITIALIZED_NONCONSTANTS, true);
opts_set(opts.werror, WARN_INVALID_PARAMETER_COUNT, true);
opts_set(opts.werror, WARN_MISSING_RETURN_VALUES, true);
opts_set(opts.flags, EXPRESSIONS_FOR_BUILTINS, true);
opts_set(opts.warn, WARN_BREAKDEF, true);
OPTS_OPTION_U32(OPTION_STANDARD) = COMPILER_GMQCC;
} else if (!strcmp(argarg, "qcc")) {
opts_set(opts.flags, ADJUST_VECTOR_FIELDS, false);
opts_set(opts.flags, ASSIGN_FUNCTION_TYPES, true);
opts.standard = COMPILER_QCC;
OPTS_OPTION_U32(OPTION_STANDARD) = COMPILER_QCC;
} else if (!strcmp(argarg, "fte") || !strcmp(argarg, "fteqcc")) {
@ -171,14 +168,16 @@ static bool options_parse(int argc, char **argv) {
opts_set(opts.flags, TRANSLATABLE_STRINGS, true);
opts_set(opts.flags, ADJUST_VECTOR_FIELDS, false);
opts_set(opts.flags, ASSIGN_FUNCTION_TYPES, true);
opts_set(opts.warn, WARN_TERNARY_PRECEDENCE, true);
opts_set(opts.flags, CORRECT_TERNARY, false);
opts.standard = COMPILER_FTEQCC;
opts_set(opts.warn, WARN_TERNARY_PRECEDENCE, true);
opts_set(opts.warn, WARN_BREAKDEF, true);
OPTS_OPTION_U32(OPTION_STANDARD) = COMPILER_FTEQCC;
} else if (!strcmp(argarg, "qccx")) {
opts_set(opts.flags, ADJUST_VECTOR_FIELDS, false);
opts.standard = COMPILER_QCCX;
OPTS_OPTION_U32(OPTION_STANDARD) = COMPILER_QCCX;
} else {
con_out("Unknown standard: %s\n", argarg);
@ -187,27 +186,28 @@ static bool options_parse(int argc, char **argv) {
continue;
}
if (options_long_gcc("force-crc", &argc, &argv, &argarg)) {
opts.forcecrc = true;
opts.forced_crc = strtol(argarg, NULL, 0);
OPTS_OPTION_BOOL(OPTION_FORCECRC) = true;
OPTS_OPTION_U16 (OPTION_FORCED_CRC) = strtol(argarg, nullptr, 0);
continue;
}
if (options_long_gcc("redirout", &argc, &argv, &redirout)) {
con_change(redirout, redirerr);
continue;
}
if (options_long_gcc("redirerr", &argc, &argv, &redirerr)) {
con_change(redirout, redirerr);
if (options_long_gcc("state-fps", &argc, &argv, &argarg)) {
OPTS_OPTION_U32(OPTION_STATE_FPS) = strtol(argarg, nullptr, 0);
opts_set(opts.flags, EMULATE_STATE, true);
continue;
}
if (options_long_gcc("config", &argc, &argv, &argarg)) {
config = argarg;
continue;
}
if (options_long_gcc("progsrc", &argc, &argv, &argarg)) {
OPTS_OPTION_STR(OPTION_PROGSRC) = argarg;
*has_progs_src = true;
continue;
}
/* show defaults (like pathscale) */
if (!strcmp(argv[0]+1, "show-defaults")) {
size_t itr;
char buffer[1024];
for (itr = 0; itr < COUNT_FLAGS; ++itr) {
if (!OPTS_FLAG(itr))
continue;
@ -230,25 +230,25 @@ static bool options_parse(int argc, char **argv) {
}
if (!strcmp(argv[0]+1, "debug")) {
opts.debug = true;
OPTS_OPTION_BOOL(OPTION_DEBUG) = true;
continue;
}
if (!strcmp(argv[0]+1, "dump")) {
opts.dump = true;
OPTS_OPTION_BOOL(OPTION_DUMP) = true;
continue;
}
if (!strcmp(argv[0]+1, "dumpfin")) {
opts.dumpfin = true;
continue;
}
if (!strcmp(argv[0]+1, "memchk")) {
opts.memchk = true;
OPTS_OPTION_BOOL(OPTION_DUMPFIN) = true;
continue;
}
if (!strcmp(argv[0]+1, "nocolor")) {
con_color(0);
continue;
}
if (!strcmp(argv[0]+1, "coverage")) {
OPTS_OPTION_BOOL(OPTION_COVERAGE) = true;
continue;
}
switch (argv[0][1]) {
/* -h, show usage but exit with 0 */
@ -262,13 +262,18 @@ static bool options_parse(int argc, char **argv) {
exit(0);
case 'E':
opts.pp_only = true;
OPTS_OPTION_BOOL(OPTION_PP_ONLY) = true;
opts_set(opts.flags, FTEPP_PREDEFS, true); /* predefs on for -E */
break;
/* debug turns on -flno */
case 'g':
opts_setflag("LNO", true);
opts.g = true;
OPTS_OPTION_BOOL(OPTION_G) = true;
break;
case 'q':
OPTS_OPTION_BOOL(OPTION_QUIET) = true;
break;
case 'D':
@ -279,7 +284,7 @@ static bool options_parse(int argc, char **argv) {
if (!(argarg = strchr(argv[0] + 2, '='))) {
macro.name = util_strdup(argv[0]+2);
macro.value = NULL;
macro.value = nullptr;
} else {
*argarg='\0'; /* terminate for name */
macro.name = util_strdup(argv[0]+2);
@ -292,7 +297,7 @@ static bool options_parse(int argc, char **argv) {
case 'f':
util_strtocmd(argv[0]+2, argv[0]+2, strlen(argv[0]+2)+1);
if (!strcmp(argv[0]+2, "HELP") || *(argv[0]+2) == '?') {
con_out("Possible flags:\n");
con_out("Possible flags:\n\n");
for (itr = 0; itr < COUNT_FLAGS; ++itr) {
util_strtononcmd(opts_flag_list[itr].name, buffer, sizeof(buffer));
con_out(" -f%s\n", buffer);
@ -317,31 +322,37 @@ static bool options_parse(int argc, char **argv) {
for (itr = 0; itr < COUNT_WARNINGS; ++itr) {
util_strtononcmd(opts_warn_list[itr].name, buffer, sizeof(buffer));
con_out(" -W%s\n", buffer);
if (itr == WARN_DEBUG)
con_out(" Warnings included by -Wall:\n");
}
exit(0);
}
else if (!strcmp(argv[0]+2, "NO_ERROR") ||
!strcmp(argv[0]+2, "NO_ERROR_ALL"))
{
for (itr = 0; itr < sizeof(opts.werror)/sizeof(opts.werror[0]); ++itr)
for (itr = 0; itr < GMQCC_ARRAY_COUNT(opts.werror); ++itr)
opts.werror[itr] = 0;
break;
}
else if (!strcmp(argv[0]+2, "ERROR") ||
!strcmp(argv[0]+2, "ERROR_ALL"))
{
for (itr = 0; itr < sizeof(opts.werror)/sizeof(opts.werror[0]); ++itr)
opts_backup_non_Werror_all();
for (itr = 0; itr < GMQCC_ARRAY_COUNT(opts.werror); ++itr)
opts.werror[itr] = 0xFFFFFFFFL;
opts_restore_non_Werror_all();
break;
}
else if (!strcmp(argv[0]+2, "NONE")) {
for (itr = 0; itr < sizeof(opts.warn)/sizeof(opts.warn[0]); ++itr)
for (itr = 0; itr < GMQCC_ARRAY_COUNT(opts.warn); ++itr)
opts.warn[itr] = 0;
break;
}
else if (!strcmp(argv[0]+2, "ALL")) {
for (itr = 0; itr < sizeof(opts.warn)/sizeof(opts.warn[0]); ++itr)
opts_backup_non_Wall();
for (itr = 0; itr < GMQCC_ARRAY_COUNT(opts.warn); ++itr)
opts.warn[itr] = 0xFFFFFFFFL;
opts_restore_non_Wall();
break;
}
else if (!strncmp(argv[0]+2, "ERROR_", 6)) {
@ -373,9 +384,10 @@ static bool options_parse(int argc, char **argv) {
con_out("option -O requires a numerical argument, or optimization name with an optional 'no-' prefix\n");
return false;
}
if (isdigit(argarg[0])) {
opts.O = atoi(argarg);
opts_setoptimlevel(opts.O);
if (util_isdigit(argarg[0])) {
uint32_t val = (uint32_t)strtol(argarg, nullptr, 10);
OPTS_OPTION_U32(OPTION_O) = val;
opts_setoptimlevel(val);
} else {
util_strtocmd(argarg, argarg, strlen(argarg)+1);
if (!strcmp(argarg, "HELP")) {
@ -387,9 +399,10 @@ static bool options_parse(int argc, char **argv) {
exit(0);
}
else if (!strcmp(argarg, "ALL"))
opts_setoptimlevel(opts.O = 9999);
opts_setoptimlevel(OPTS_OPTION_U32(OPTION_O) = 9999);
else if (!strncmp(argarg, "NO_", 3)) {
if (!opts_setoptim(argarg+3, false)) {
/* constant folding cannot be turned off for obvious reasons */
if (!strcmp(argarg, "NO_CONST_FOLD") || !opts_setoptim(argarg+3, false)) {
con_out("unknown optimization: %s\n", argarg+3);
return false;
}
@ -408,7 +421,7 @@ static bool options_parse(int argc, char **argv) {
con_out("option -o requires an argument: the output file name\n");
return false;
}
opts.output = argarg;
OPTS_OPTION_STR(OPTION_OUTPUT) = argarg;
opts_output_wasset = true;
break;
@ -422,6 +435,9 @@ static bool options_parse(int argc, char **argv) {
}
item.filename = argarg;
vec_push(items, item);
if (item.type == TYPE_SRC) {
*has_progs_src = true;
}
break;
case '-':
@ -439,10 +455,18 @@ static bool options_parse(int argc, char **argv) {
version();
exit(0);
}
else if (!strcmp(argv[0]+2, "quiet")) {
OPTS_OPTION_BOOL(OPTION_QUIET) = true;
break;
}
else if (!strcmp(argv[0]+2, "add-info")) {
OPTS_OPTION_BOOL(OPTION_ADD_INFO) = true;
break;
}
else {
/* All long options with arguments */
if (options_long_witharg("output", &argc, &argv, &argarg)) {
opts.output = argarg;
OPTS_OPTION_STR(OPTION_OUTPUT) = argarg;
opts_output_wasset = true;
} else {
con_out("Unknown parameter: %s\n", argv[0]);
@ -469,21 +493,21 @@ static bool options_parse(int argc, char **argv) {
}
/* returns the line number, or -1 on error */
static bool progs_nextline(char **out, size_t *alen,FILE *src) {
static bool progs_nextline(char **out, size_t *alen, FILE *src) {
int len;
char *line;
char *start;
char *end;
line = *out;
len = util_getline(&line, alen, src);
len = util_getline(&line, alen, src);
if (len == -1)
return false;
/* start at first non-blank */
for (start = line; isspace(*start); ++start) {}
for (start = line; util_isspace(*start); ++start) {}
/* end at the first non-blank */
for (end = start; *end && !isspace(*end); ++end) {}
for (end = start; *end && !util_isspace(*end); ++end) {}
*out = line;
/* move the actual filename to the beginning */
@ -496,30 +520,38 @@ static bool progs_nextline(char **out, size_t *alen,FILE *src) {
int main(int argc, char **argv) {
size_t itr;
int retval = 0;
bool opts_output_free = false;
bool operators_free = false;
bool progs_src = false;
FILE *outfile = NULL;
int retval = 0;
bool operators_free = false;
bool has_progs_src = false;
FILE *outfile = nullptr;
parser_t *parser = nullptr;
ftepp_t *ftepp = nullptr;
app_name = argv[0];
con_init ();
opts_init("progs.dat", COMPILER_GMQCC, (1024 << 3));
opts_init("progs.dat", COMPILER_QCC, (1024 << 3));
if (!options_parse(argc, argv)) {
util_seed(time(0));
if (!options_parse(argc, argv, &has_progs_src)) {
return usage();
}
if (OPTS_FLAG(TRUE_EMPTY_STRINGS) && OPTS_FLAG(FALSE_EMPTY_STRINGS)) {
con_err("-ftrue-empty-strings and -ffalse-empty-strings are mutually exclusive");
exit(EXIT_FAILURE);
}
/* the standard decides which set of operators to use */
if (opts.standard == COMPILER_GMQCC) {
if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_GMQCC) {
operators = c_operators;
operator_count = c_operator_count;
} else if (opts.standard == COMPILER_FTEQCC) {
operator_count = GMQCC_ARRAY_COUNT(c_operators);
} else if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_FTEQCC) {
operators = fte_operators;
operator_count = fte_operator_count;
operator_count = GMQCC_ARRAY_COUNT(fte_operators);
} else {
operators = qcc_operators;
operator_count = qcc_operator_count;
operator_count = GMQCC_ARRAY_COUNT(qcc_operators);
}
if (operators == fte_operators) {
@ -530,10 +562,10 @@ int main(int argc, char **argv) {
operators[operator_count-1].id != opid2(':','?'))
{
con_err("internal error: operator precedence table wasn't updated correctly!\n");
exit(1);
exit(EXIT_FAILURE);
}
operators_free = true;
newops = mem_a(sizeof(operators[0]) * operator_count);
newops = (oper_info*)mem_a(sizeof(operators[0]) * operator_count);
memcpy(newops, operators, sizeof(operators[0]) * operator_count);
memcpy(&newops[operator_count-2], &operators[operator_count-1], sizeof(newops[0]));
memcpy(&newops[operator_count-1], &operators[operator_count-2], sizeof(newops[0]));
@ -542,52 +574,51 @@ int main(int argc, char **argv) {
}
}
if (opts.dump) {
if (OPTS_OPTION_BOOL(OPTION_DUMP)) {
for (itr = 0; itr < COUNT_FLAGS; ++itr)
con_out("Flag %s = %i\n", opts_flag_list[itr].name, OPTS_FLAG(itr));
for (itr = 0; itr < COUNT_WARNINGS; ++itr)
con_out("Warning %s = %i\n", opts_warn_list[itr].name, OPTS_WARN(itr));
con_out("output = %s\n", opts.output);
con_out("optimization level = %d\n", opts.O);
con_out("standard = %i\n", opts.standard);
con_out("output = %s\n", OPTS_OPTION_STR(OPTION_OUTPUT));
con_out("optimization level = %u\n", OPTS_OPTION_U32(OPTION_O));
con_out("standard = %u\n", OPTS_OPTION_U32(OPTION_STANDARD));
}
if (opts.pp_only) {
if (OPTS_OPTION_BOOL(OPTION_PP_ONLY)) {
if (opts_output_wasset) {
outfile = util_fopen(opts.output, "wb");
outfile = fopen(OPTS_OPTION_STR(OPTION_OUTPUT), "wb");
if (!outfile) {
con_err("failed to open `%s` for writing\n", opts.output);
con_err("failed to open `%s` for writing\n", OPTS_OPTION_STR(OPTION_OUTPUT));
retval = 1;
goto cleanup;
}
}
else
outfile = stdout;
else {
outfile = con_default_out();
}
}
if (!opts.pp_only) {
if (!parser_init()) {
if (!OPTS_OPTION_BOOL(OPTION_PP_ONLY)) {
if (!(parser = parser_create())) {
con_err("failed to initialize parser\n");
retval = 1;
goto cleanup;
}
}
if (opts.pp_only || OPTS_FLAG(FTEPP)) {
if (!ftepp_init()) {
if (OPTS_OPTION_BOOL(OPTION_PP_ONLY) || OPTS_FLAG(FTEPP)) {
if (!(ftepp = ftepp_create())) {
con_err("failed to initialize parser\n");
retval = 1;
goto cleanup;
}
}
util_debug("COM", "starting ...\n");
/* add macros */
if (opts.pp_only || OPTS_FLAG(FTEPP)) {
if (OPTS_OPTION_BOOL(OPTION_PP_ONLY) || OPTS_FLAG(FTEPP)) {
for (itr = 0; itr < vec_size(ppems); itr++) {
ftepp_add_macro(ppems[itr].name, ppems[itr].value);
ftepp_add_macro(ftepp, ppems[itr].name, ppems[itr].value);
mem_d(ppems[itr].name);
/* can be null */
@ -596,56 +627,62 @@ int main(int argc, char **argv) {
}
}
if (!vec_size(items)) {
if (!vec_size(items) && !has_progs_src) {
FILE *fp = fopen(OPTS_OPTION_STR(OPTION_PROGSRC), "rb");
if (fp) {
has_progs_src = true;
fclose(fp);
}
}
if (has_progs_src) {
FILE *src;
char *line;
char *line = nullptr;
size_t linelen = 0;
bool has_first_line = false;
progs_src = true;
src = util_fopen("progs.src", "rb");
src = fopen(OPTS_OPTION_STR(OPTION_PROGSRC), "rb");
if (!src) {
con_err("failed to open `progs.src` for reading\n");
con_err("failed to open `%s` for reading\n", OPTS_OPTION_STR(OPTION_PROGSRC));
retval = 1;
goto cleanup;
}
line = NULL;
if (!progs_nextline(&line, &linelen, src) || !line[0]) {
con_err("illformatted progs.src file: expected output filename in first line\n");
retval = 1;
goto srcdone;
}
if (!opts_output_wasset) {
opts.output = util_strdup(line);
opts_output_free = true;
}
while (progs_nextline(&line, &linelen, src)) {
argitem item;
if (!line[0] || (line[0] == '/' && line[1] == '/'))
if (!line[0] || (line[0] == '/' && line[1] == '/')) {
continue;
item.filename = util_strdup(line);
item.type = TYPE_QC;
vec_push(items, item);
}
if (has_first_line) {
item.filename = util_strdup(line);
item.type = TYPE_QC;
vec_push(items, item);
} else {
if (!opts_output_wasset) {
OPTS_OPTION_DUP(OPTION_OUTPUT) = util_strdup(line);
}
has_first_line = true;
}
}
srcdone:
fclose(src);
mem_d(line);
}
if (retval)
goto cleanup;
if (vec_size(items)) {
if (!opts.pp_only) {
con_out("Mode: %s\n", (progs_src ? "progs.src" : "manual"));
if (!OPTS_OPTION_BOOL(OPTION_QUIET) &&
!OPTS_OPTION_BOOL(OPTION_PP_ONLY))
{
con_out("Mode: %s\n", (has_progs_src ? "progs.src" : "manual"));
con_out("There are %lu items to compile:\n", (unsigned long)vec_size(items));
}
for (itr = 0; itr < vec_size(items); ++itr) {
if (!opts.pp_only) {
if (!OPTS_OPTION_BOOL(OPTION_QUIET) &&
!OPTS_OPTION_BOOL(OPTION_PP_ONLY))
{
con_out(" item: %s (%s)\n",
items[itr].filename,
( (items[itr].type == TYPE_QC ? "qc" :
@ -654,80 +691,82 @@ srcdone:
("unknown"))))));
}
if (opts.pp_only) {
if (items[itr].type == TYPE_SRC) {
continue;
}
if (OPTS_OPTION_BOOL(OPTION_PP_ONLY)) {
const char *out;
if (!ftepp_preprocess_file(items[itr].filename)) {
if (!ftepp_preprocess_file(ftepp, items[itr].filename)) {
retval = 1;
goto cleanup;
}
out = ftepp_get();
out = ftepp_get(ftepp);
if (out)
fprintf(outfile, "%s", out);
ftepp_flush();
ftepp_flush(ftepp);
}
else {
if (OPTS_FLAG(FTEPP)) {
const char *data;
if (!ftepp_preprocess_file(items[itr].filename)) {
if (!ftepp_preprocess_file(ftepp, items[itr].filename)) {
retval = 1;
goto cleanup;
}
data = ftepp_get();
data = ftepp_get(ftepp);
if (vec_size(data)) {
if (!parser_compile_string_len(items[itr].filename, data, vec_size(data))) {
if (!parser_compile_string(parser, items[itr].filename, data, vec_size(data))) {
retval = 1;
goto cleanup;
}
}
ftepp_flush();
ftepp_flush(ftepp);
}
else {
if (!parser_compile_file(items[itr].filename)) {
if (!parser_compile_file(parser, items[itr].filename)) {
retval = 1;
goto cleanup;
}
}
}
if (progs_src) {
if (has_progs_src) {
mem_d(items[itr].filename);
items[itr].filename = NULL;
items[itr].filename = nullptr;
}
}
ftepp_finish();
if (!opts.pp_only) {
if (!parser_finish(opts.output)) {
ftepp_finish(ftepp);
ftepp = nullptr;
if (!OPTS_OPTION_BOOL(OPTION_PP_ONLY)) {
if (!parser_finish(parser, OPTS_OPTION_STR(OPTION_OUTPUT))) {
retval = 1;
goto cleanup;
}
}
}
/* stuff */
if (!opts.pp_only) {
for (itr = 0; itr < COUNT_OPTIMIZATIONS; ++itr) {
if (opts_optimizationcount[itr]) {
con_out("%s: %u\n", opts_opt_list[itr].name, (unsigned int)opts_optimizationcount[itr]);
}
}
}
cleanup:
util_debug("COM", "cleaning ...\n");
ftepp_finish();
if (ftepp)
ftepp_finish(ftepp);
con_close();
vec_free(items);
vec_free(ppems);
if (!opts.pp_only)
parser_cleanup();
if (opts_output_free)
mem_d((char*)opts.output);
if (!OPTS_OPTION_BOOL(OPTION_PP_ONLY))
delete parser;
/* free allocated option strings */
for (itr = 0; itr < OPTION_COUNT; itr++)
if (OPTS_OPTION_DUPED(itr))
mem_d(OPTS_OPTION_STR(itr));
if (operators_free)
mem_d((void*)operators);
lex_cleanup();
util_meminfo();
if (!retval && compile_errors)
retval = 1;
return retval;
}

51
misc/check-doc.sh Executable file
View file

@ -0,0 +1,51 @@
#!/bin/sh
prog=$0
die() {
echo "$@"
exit 1
}
want() {
test -e "$1" && return
echo "$prog: missing $1"
echo "$prog: run this script from the top of a gmqcc source tree"
exit 1
}
for i in opts.def \
doc/gmqcc.1 \
gmqcc.ini.example
do want "$i"; done
# y/_ABCDEFGHIJKLMNOPQRSTUVWXYZ/-abcdefghijklmnopqrstuvwxyz/;
check_opt() {
opt_def_name=$1
arg_char=$2
for i in $(sed -ne \
'/^#ifdef GMQCC_TYPE_'${opt_def_name}'$/,/^#endif/{
/GMQCC_DEFINE_FLAG/{
s/^.*GMQCC_DEFINE_FLAG(\([^,)]*\)[),].*$/\1/;p;
}
}' opts.def)
do
opt=$(echo "$i" | tr -- '_A-Z' '-a-z')
grep -qF -- ".It Fl "${arg_char}" Ns Cm $opt" \
doc/gmqcc.1 || echo "doc/gmqcc.1: missing: -${arg_char}$opt"
grep -q -- "[^a-zA-Z_]$i[^a-zA-Z_]" \
gmqcc.ini.example || echo "gmqcc.ini.example: missing: $i"
done
}
check_opt FLAGS f
check_opt WARNS W
check_opt OPTIMIZATIONS O
# TODO: linux version
if [ "$(uname -s)" != "Linux" ]; then
for i in doc/*.1;
do
mandoc -Tlint -Wall "$i";
done
fi

View file

@ -1,33 +1,43 @@
/*
* Copyright (C) 2012
* Wolfgang Bumiller
* Dale Weiler
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "gmqcc.h"
unsigned int opts_optimizationcount[COUNT_OPTIMIZATIONS];
opts_cmd_t opts; /* command lien options */
#include <string.h>
#include <stdlib.h>
static void opts_setdefault() {
#include "gmqcc.h"
const unsigned int opts_opt_oflag[COUNT_OPTIMIZATIONS+1] = {
# define GMQCC_TYPE_OPTIMIZATIONS
# define GMQCC_DEFINE_FLAG(NAME, MIN_O) MIN_O,
# include "opts.def"
0
};
const opts_flag_def_t opts_opt_list[COUNT_OPTIMIZATIONS+1] = {
# define GMQCC_TYPE_OPTIMIZATIONS
# define GMQCC_DEFINE_FLAG(NAME, MIN_O) { #NAME, LONGBIT(OPTIM_##NAME) },
# include "opts.def"
{ nullptr, LONGBIT(0) }
};
const opts_flag_def_t opts_warn_list[COUNT_WARNINGS+1] = {
# define GMQCC_TYPE_WARNS
# define GMQCC_DEFINE_FLAG(X) { #X, LONGBIT(WARN_##X) },
# include "opts.def"
{ nullptr, LONGBIT(0) }
};
const opts_flag_def_t opts_flag_list[COUNT_FLAGS+1] = {
# define GMQCC_TYPE_FLAGS
# define GMQCC_DEFINE_FLAG(X) { #X, LONGBIT(X) },
# include "opts.def"
{ nullptr, LONGBIT(0) }
};
unsigned int opts_optimizationcount[COUNT_OPTIMIZATIONS];
opts_cmd_t opts; /* command line options */
static void opts_setdefault(void) {
memset(&opts, 0, sizeof(opts_cmd_t));
OPTS_OPTION_STR(OPTION_PROGSRC) = "progs.src";
/* warnings */
opts_set(opts.warn, WARN_UNUSED_VARIABLE, true);
opts_set(opts.warn, WARN_USED_UNINITIALIZED, true);
@ -35,8 +45,7 @@ static void opts_setdefault() {
opts_set(opts.warn, WARN_EXTENSIONS, true);
opts_set(opts.warn, WARN_FIELD_REDECLARED, true);
opts_set(opts.warn, WARN_MISSING_RETURN_VALUES, true);
opts_set(opts.warn, WARN_TOO_FEW_PARAMETERS, true);
opts_set(opts.warn, WARN_LOCAL_SHADOWS, false);
opts_set(opts.warn, WARN_INVALID_PARAMETER_COUNT, true);
opts_set(opts.warn, WARN_LOCAL_CONSTANTS, true);
opts_set(opts.warn, WARN_VOID_VARIABLES, true);
opts_set(opts.warn, WARN_IMPLICIT_FUNCTION_POINTER, true);
@ -45,44 +54,78 @@ static void opts_setdefault() {
opts_set(opts.warn, WARN_EFFECTLESS_STATEMENT, true);
opts_set(opts.warn, WARN_END_SYS_FIELDS, true);
opts_set(opts.warn, WARN_ASSIGN_FUNCTION_TYPES, true);
opts_set(opts.warn, WARN_PREPROCESSOR, true);
opts_set(opts.warn, WARN_CPP, true);
opts_set(opts.warn, WARN_MULTIFILE_IF, true);
opts_set(opts.warn, WARN_DOUBLE_DECLARATION, true);
opts_set(opts.warn, WARN_CONST_VAR, true);
opts_set(opts.warn, WARN_MULTIBYTE_CHARACTER, true);
opts_set(opts.warn, WARN_UNKNOWN_PRAGMAS, true);
opts_set(opts.warn, WARN_UNREACHABLE_CODE, true);
opts_set(opts.warn, WARN_UNKNOWN_ATTRIBUTE, true);
opts_set(opts.warn, WARN_RESERVED_NAMES, true);
opts_set(opts.warn, WARN_UNINITIALIZED_CONSTANT, true);
opts_set(opts.warn, WARN_DEPRECATED, true);
opts_set(opts.warn, WARN_PARENTHESIS, true);
opts_set(opts.warn, WARN_CONST_OVERWRITE, true);
opts_set(opts.warn, WARN_DIRECTIVE_INMACRO, true);
opts_set(opts.warn, WARN_BUILTINS, true);
opts_set(opts.warn, WARN_INEXACT_COMPARES, true);
/* flags */
opts_set(opts.flags, ADJUST_VECTOR_FIELDS, true);
opts_set(opts.flags, FTEPP, false);
opts_set(opts.flags, CORRECT_TERNARY, true);
opts_set(opts.flags, BAIL_ON_WERROR, true);
opts_set(opts.flags, LEGACY_VECTOR_MATHS, true);
opts_set(opts.flags, DARKPLACES_STRING_TABLE_BUG, true);
/* options */
OPTS_OPTION_U32(OPTION_STATE_FPS) = 10;
}
void opts_backup_non_Wall() {
size_t i;
for (i = 0; i <= WARN_DEBUG; ++i)
opts_set(opts.warn_backup, i, OPTS_WARN(i));
}
void opts_restore_non_Wall() {
size_t i;
for (i = 0; i <= WARN_DEBUG; ++i)
opts_set(opts.warn, i, OPTS_GENERIC(opts.warn_backup, i));
}
void opts_backup_non_Werror_all() {
size_t i;
for (i = 0; i <= WARN_DEBUG; ++i)
opts_set(opts.werror_backup, i, OPTS_WERROR(i));
}
void opts_restore_non_Werror_all() {
size_t i;
for (i = 0; i <= WARN_DEBUG; ++i)
opts_set(opts.werror, i, OPTS_GENERIC(opts.werror_backup, i));
}
void opts_init(const char *output, int standard, size_t arraysize) {
opts_setdefault();
opts.output = output;
opts.standard = standard;
opts.max_array_size = arraysize;
OPTS_OPTION_STR(OPTION_OUTPUT) = output;
OPTS_OPTION_U32(OPTION_STANDARD) = standard;
OPTS_OPTION_U32(OPTION_MAX_ARRAY_SIZE) = arraysize;
}
static bool opts_setflag_all(const char *name, bool on, uint32_t *flags, const opts_flag_def *list, size_t listsize) {
static bool opts_setflag_all(const char *name, bool on, uint32_t *flags, const opts_flag_def_t *list, size_t listsize) {
size_t i;
for (i = 0; i < listsize; ++i) {
if (!strcmp(name, list[i].name)) {
longbit lb = list[i].bit;
#if 0
if (on)
flags[lb.idx] |= (1<<(lb.bit));
else
flags[lb.idx] &= ~(1<<(lb.bit));
#else
if (on)
flags[0] |= (1<<lb);
else
flags[0] &= ~(1<<(lb));
#endif
return true;
}
}
@ -102,24 +145,22 @@ bool opts_setoptim (const char *name, bool on) {
}
void opts_set(uint32_t *flags, size_t idx, bool on) {
longbit lb = LONGBIT(idx);
#if 0
longbit lb;
LONGBIT_SET(lb, idx);
if (on)
flags[lb.idx] |= (1<<(lb.bit));
flags[lb.idx] |= (1u<<(lb.bit));
else
flags[lb.idx] &= ~(1<<(lb.bit));
#else
if (on)
flags[0] |= (1<<(lb));
else
flags[0] &= ~(1<<(lb));
#endif
flags[lb.idx] &= ~(1u<<(lb.bit));
}
void opts_setoptimlevel(unsigned int level) {
size_t i;
for (i = 0; i < COUNT_OPTIMIZATIONS; ++i)
opts_set(opts.optimization, i, level >= opts_opt_oflag[i]);
if (!level)
opts.optimizeoff = true;
}
/*
@ -130,14 +171,14 @@ void opts_setoptimlevel(unsigned int level) {
* from a progs.src.
*/
static char *opts_ini_rstrip(char *s) {
char *p = s + strlen(s);
while(p > s && isspace(*--p))
*p = '\0';
char *p = s + strlen(s) - 1;
while (p > s && util_isspace(*p))
*p = '\0', p--;
return s;
}
static char *opts_ini_lskip(const char *s) {
while (*s && isspace(*s))
while (*s && util_isspace(*s))
s++;
return (char*)s;
}
@ -145,20 +186,21 @@ static char *opts_ini_lskip(const char *s) {
static char *opts_ini_next(const char *s, char c) {
bool last = false;
while (*s && *s != c && !(last && *s == ';'))
last = !!isspace(*s), s++;
last = !!util_isspace(*s), s++;
return (char*)s;
}
static size_t opts_ini_parse (
FILE *filehandle,
char *(*loadhandle)(const char *, const char *, const char *),
char **errorhandle
FILE *filehandle,
char *(*loadhandle)(const char *, const char *, const char *, char **),
char **errorhandle,
char **parse_file
) {
size_t linesize;
size_t lineno = 1;
size_t error = 0;
char *line = NULL;
char *line = nullptr;
char section_data[2048] = "";
char oldname_data[2048] = "";
@ -189,7 +231,7 @@ static size_t opts_ini_parse (
/* section found */
if (*(parse_end = opts_ini_next(parse_beg + 1, ']')) == ']') {
* parse_end = '\0'; /* terminate bro */
strncpy(section_data, parse_beg + 1, sizeof(section_data));
util_strncpy(section_data, parse_beg + 1, sizeof(section_data));
section_data[sizeof(section_data) - 1] = '\0';
*oldname_data = '\0';
} else if (!error) {
@ -199,7 +241,7 @@ static size_t opts_ini_parse (
} else if (*parse_beg && *parse_beg != ';') {
/* not a comment, must be a name value pair :) */
if (*(parse_end = opts_ini_next(parse_beg, '=')) != '=')
parse_end = opts_ini_next(parse_beg, ':');
parse_end = opts_ini_next(parse_beg, ':');
if (*parse_end == '=' || *parse_end == ':') {
*parse_end = '\0'; /* terminate bro */
@ -210,11 +252,23 @@ static size_t opts_ini_parse (
opts_ini_rstrip(read_value);
/* valid name value pair, lets call down to handler */
strncpy(oldname_data, read_name, sizeof(oldname_data));
util_strncpy(oldname_data, read_name, sizeof(oldname_data));
oldname_data[sizeof(oldname_data) - 1] ='\0';
if ((*errorhandle = loadhandle(section_data, read_name, read_value)) && !error)
if ((*errorhandle = loadhandle(section_data, read_name, read_value, parse_file)) && !error)
error = lineno;
} else if (!strcmp(section_data, "includes")) {
/* Includes are special */
if (*(parse_end = opts_ini_next(parse_beg, '=')) == '='
|| *(parse_end = opts_ini_next(parse_beg, ':')) == ':') {
static const char *invalid_include = "invalid use of include";
vec_append(*errorhandle, strlen(invalid_include), invalid_include);
error = lineno;
} else {
read_name = opts_ini_rstrip(parse_beg);
if ((*errorhandle = loadhandle(section_data, read_name, read_name, parse_file)) && !error)
error = lineno;
}
} else if (!error) {
/* otherwise set error to the current line number */
error = lineno;
@ -224,6 +278,7 @@ static size_t opts_ini_parse (
}
mem_d(line);
return error;
}
/*
@ -232,21 +287,41 @@ static size_t opts_ini_parse (
static bool opts_ini_bool(const char *value) {
if (!strcmp(value, "true")) return true;
if (!strcmp(value, "false")) return false;
return !!atoi(value);
return !!strtol(value, nullptr, 10);
}
static char *opts_ini_load(const char *section, const char *name, const char *value) {
char *error = NULL;
static char *opts_ini_load(const char *section, const char *name, const char *value, char **parse_file) {
char *error = nullptr;
bool found = false;
/*
* undef all of these because they may still be defined like in my
* case they where.
*/
*/
#undef GMQCC_TYPE_FLAGS
#undef GMQCC_TYPE_OPTIMIZATIONS
#undef GMQCC_TYPE_WARNS
/* deal with includes */
if (!strcmp(section, "includes")) {
static const char *include_error_beg = "failed to open file `";
static const char *include_error_end = "' for inclusion";
FILE *file = fopen(value, "r");
found = true;
if (!file) {
vec_append(error, strlen(include_error_beg), include_error_beg);
vec_append(error, strlen(value), value);
vec_append(error, strlen(include_error_end), include_error_end);
} else {
if (opts_ini_parse(file, &opts_ini_load, &error, parse_file) != 0)
found = false;
/* Change the file name */
mem_d(*parse_file);
*parse_file = util_strdup(value);
fclose(file);
}
}
/* flags */
#define GMQCC_TYPE_FLAGS
#define GMQCC_DEFINE_FLAG(X) \
@ -265,6 +340,15 @@ static char *opts_ini_load(const char *section, const char *name, const char *va
}
#include "opts.def"
/* Werror-individuals */
#define GMQCC_TYPE_WARNS
#define GMQCC_DEFINE_FLAG(X) \
if (!strcmp(section, "errors") && !strcmp(name, #X)) { \
opts_set(opts.werror, WARN_##X, opts_ini_bool(value)); \
found = true; \
}
#include "opts.def"
/* optimizations */
#define GMQCC_TYPE_OPTIMIZATIONS
#define GMQCC_DEFINE_FLAG(X,Y) \
@ -276,24 +360,29 @@ static char *opts_ini_load(const char *section, const char *name, const char *va
/* nothing was found ever! */
if (!found) {
if (strcmp(section, "flags") &&
strcmp(section, "warnings") &&
if (strcmp(section, "includes") &&
strcmp(section, "flags") &&
strcmp(section, "warnings") &&
strcmp(section, "optimizations"))
{
vec_upload(error, "invalid section `", 17);
vec_upload(error, section, strlen(section));
vec_push (error, '`');
vec_push (error, '\0');
static const char *invalid_section = "invalid_section `";
vec_append(error, strlen(invalid_section), invalid_section);
vec_append(error, strlen(section), section);
vec_push(error, '`');
} else if (strcmp(section, "includes")) {
static const char *invalid_variable = "invalid_variable `";
static const char *in_section = "` in section: `";
vec_append(error, strlen(invalid_variable), invalid_variable);
vec_append(error, strlen(name), name);
vec_append(error, strlen(in_section), in_section);
vec_append(error, strlen(section), section);
vec_push(error, '`');
} else {
vec_upload(error, "invalid variable `", 18);
vec_upload(error, name, strlen(name));
vec_push (error, '`');
vec_upload(error, " in section: `", 14);
vec_upload(error, section, strlen(section));
vec_push (error, '`');
vec_push (error, '\0');
static const char *expected_something = "expected something";
vec_append(error, strlen(expected_something), expected_something);
}
}
vec_push(error, '\0');
return error;
}
@ -307,11 +396,11 @@ void opts_ini_init(const char *file) {
* gmqcc.ini
* gmqcc.cfg
*/
char *error;
char *error = nullptr;
char *parse_file = nullptr;
size_t line;
FILE *ini;
FILE *ini;
if (!file) {
/* try ini */
if (!(ini = fopen((file = "gmqcc.ini"), "r")))
@ -323,11 +412,13 @@ void opts_ini_init(const char *file) {
con_out("found ini file `%s`\n", file);
if ((line = opts_ini_parse(ini, &opts_ini_load, &error)) != 0) {
parse_file = util_strdup(file);
if ((line = opts_ini_parse(ini, &opts_ini_load, &error, &parse_file)) != 0) {
/* there was a parse error with the ini file */
con_printmsg(LVL_ERROR, file, line, "error", error);
con_printmsg(LVL_ERROR, parse_file, line, 0 /*TODO: column for ini error*/, "error", error);
vec_free(error);
}
mem_d(parse_file);
fclose(ini);
}
}

104
opts.def
View file

@ -1,36 +1,15 @@
/*
* Copyright (C) 2012
* Wolfgang Bumiller
* Dale Weiler
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef GMQCC_DEFINE_FLAG
# define GMQCC_DEFINE_FLAG(x)
# error "bad opts.def usage"
#endif
/* codegen flags */
#ifdef GMQCC_TYPE_FLAGS
GMQCC_DEFINE_FLAG(OVERLAP_LOCALS)
GMQCC_DEFINE_FLAG(DARKPLACES_STRING_TABLE_BUG)
GMQCC_DEFINE_FLAG(ADJUST_VECTOR_FIELDS)
GMQCC_DEFINE_FLAG(FTEPP)
GMQCC_DEFINE_FLAG(FTEPP_PREDEFS)
GMQCC_DEFINE_FLAG(FTEPP_MATHDEFS)
GMQCC_DEFINE_FLAG(FTEPP_INDIRECT_EXPANSION)
GMQCC_DEFINE_FLAG(RELAXED_SWITCH)
GMQCC_DEFINE_FLAG(SHORT_LOGIC)
GMQCC_DEFINE_FLAG(PERL_LOGIC)
@ -40,18 +19,39 @@
GMQCC_DEFINE_FLAG(LNO)
GMQCC_DEFINE_FLAG(CORRECT_TERNARY)
GMQCC_DEFINE_FLAG(SINGLE_VECTOR_DEFS)
GMQCC_DEFINE_FLAG(CORRECT_LOGIC)
GMQCC_DEFINE_FLAG(TRUE_EMPTY_STRINGS)
GMQCC_DEFINE_FLAG(FALSE_EMPTY_STRINGS)
GMQCC_DEFINE_FLAG(UTF8)
GMQCC_DEFINE_FLAG(BAIL_ON_WERROR)
GMQCC_DEFINE_FLAG(LOOP_LABELS)
GMQCC_DEFINE_FLAG(UNTYPED_NIL)
GMQCC_DEFINE_FLAG(PERMISSIVE)
GMQCC_DEFINE_FLAG(VARIADIC_ARGS)
GMQCC_DEFINE_FLAG(LEGACY_VECTOR_MATHS)
GMQCC_DEFINE_FLAG(EXPRESSIONS_FOR_BUILTINS)
GMQCC_DEFINE_FLAG(RETURN_ASSIGNMENTS)
GMQCC_DEFINE_FLAG(UNSAFE_VARARGS)
GMQCC_DEFINE_FLAG(TYPELESS_STORES)
GMQCC_DEFINE_FLAG(SORT_OPERANDS)
GMQCC_DEFINE_FLAG(EMULATE_STATE)
GMQCC_DEFINE_FLAG(ARITHMETIC_EXCEPTIONS)
GMQCC_DEFINE_FLAG(SPLIT_VECTOR_PARAMETERS)
GMQCC_DEFINE_FLAG(DEFAULT_ERASEABLE)
#endif
/* warning flags */
#ifdef GMQCC_TYPE_WARNS
GMQCC_DEFINE_FLAG(UNINITIALIZED_GLOBAL)
GMQCC_DEFINE_FLAG(DEBUG)
GMQCC_DEFINE_FLAG(UNUSED_VARIABLE)
GMQCC_DEFINE_FLAG(UNUSED_COMPONENT)
GMQCC_DEFINE_FLAG(USED_UNINITIALIZED)
GMQCC_DEFINE_FLAG(UNKNOWN_CONTROL_SEQUENCE)
GMQCC_DEFINE_FLAG(EXTENSIONS)
GMQCC_DEFINE_FLAG(FIELD_REDECLARED)
GMQCC_DEFINE_FLAG(MISSING_RETURN_VALUES)
GMQCC_DEFINE_FLAG(TOO_FEW_PARAMETERS)
GMQCC_DEFINE_FLAG(INVALID_PARAMETER_COUNT)
GMQCC_DEFINE_FLAG(LOCAL_SHADOWS)
GMQCC_DEFINE_FLAG(LOCAL_CONSTANTS)
GMQCC_DEFINE_FLAG(VOID_VARIABLES)
@ -61,7 +61,7 @@
GMQCC_DEFINE_FLAG(EFFECTLESS_STATEMENT)
GMQCC_DEFINE_FLAG(END_SYS_FIELDS)
GMQCC_DEFINE_FLAG(ASSIGN_FUNCTION_TYPES)
GMQCC_DEFINE_FLAG(PREPROCESSOR)
GMQCC_DEFINE_FLAG(CPP)
GMQCC_DEFINE_FLAG(MULTIFILE_IF)
GMQCC_DEFINE_FLAG(DOUBLE_DECLARATION)
GMQCC_DEFINE_FLAG(CONST_VAR)
@ -69,16 +69,58 @@
GMQCC_DEFINE_FLAG(TERNARY_PRECEDENCE)
GMQCC_DEFINE_FLAG(UNKNOWN_PRAGMAS)
GMQCC_DEFINE_FLAG(UNREACHABLE_CODE)
GMQCC_DEFINE_FLAG(UNKNOWN_ATTRIBUTE)
GMQCC_DEFINE_FLAG(RESERVED_NAMES)
GMQCC_DEFINE_FLAG(UNINITIALIZED_CONSTANT)
GMQCC_DEFINE_FLAG(DIFFERENT_QUALIFIERS)
GMQCC_DEFINE_FLAG(DIFFERENT_ATTRIBUTES)
GMQCC_DEFINE_FLAG(DEPRECATED)
GMQCC_DEFINE_FLAG(PARENTHESIS)
GMQCC_DEFINE_FLAG(UNSAFE_TYPES)
GMQCC_DEFINE_FLAG(BREAKDEF)
GMQCC_DEFINE_FLAG(CONST_OVERWRITE)
GMQCC_DEFINE_FLAG(DIRECTIVE_INMACRO)
GMQCC_DEFINE_FLAG(BUILTINS)
GMQCC_DEFINE_FLAG(INEXACT_COMPARES)
#endif
#ifdef GMQCC_TYPE_OPTIMIZATIONS
GMQCC_DEFINE_FLAG(PEEPHOLE, 1)
GMQCC_DEFINE_FLAG(LOCALTEMPS, 1)
GMQCC_DEFINE_FLAG(TAIL_RECURSION, 1)
GMQCC_DEFINE_FLAG(TAIL_CALLS, 2)
GMQCC_DEFINE_FLAG(PEEPHOLE, 1)
GMQCC_DEFINE_FLAG(TAIL_RECURSION, 1)
GMQCC_DEFINE_FLAG(OVERLAP_LOCALS, 3)
GMQCC_DEFINE_FLAG(LOCAL_TEMPS, 3)
GMQCC_DEFINE_FLAG(GLOBAL_TEMPS, 3)
GMQCC_DEFINE_FLAG(STRIP_CONSTANT_NAMES, 1)
GMQCC_DEFINE_FLAG(OVERLAP_STRINGS, 2)
GMQCC_DEFINE_FLAG(CALL_STORES, 3)
GMQCC_DEFINE_FLAG(VOID_RETURN, 1)
GMQCC_DEFINE_FLAG(VECTOR_COMPONENTS, 1)
GMQCC_DEFINE_FLAG(CONST_FOLD_DCE, 2)
GMQCC_DEFINE_FLAG(CONST_FOLD, 0) /* cannot be turned off */
#endif
#ifdef GMQCC_TYPE_OPTIONS
GMQCC_DEFINE_FLAG(O)
GMQCC_DEFINE_FLAG(OUTPUT)
GMQCC_DEFINE_FLAG(QUIET)
GMQCC_DEFINE_FLAG(G)
GMQCC_DEFINE_FLAG(STANDARD)
GMQCC_DEFINE_FLAG(DEBUG)
GMQCC_DEFINE_FLAG(DUMPFIN)
GMQCC_DEFINE_FLAG(DUMP)
GMQCC_DEFINE_FLAG(FORCECRC)
GMQCC_DEFINE_FLAG(FORCED_CRC)
GMQCC_DEFINE_FLAG(PP_ONLY)
GMQCC_DEFINE_FLAG(MAX_ARRAY_SIZE)
GMQCC_DEFINE_FLAG(ADD_INFO)
GMQCC_DEFINE_FLAG(PROGSRC)
GMQCC_DEFINE_FLAG(COVERAGE)
GMQCC_DEFINE_FLAG(STATE_FPS)
#endif
/* some cleanup so we don't have to */
#undef GMQCC_TYPE_FLAGS
#undef GMQCC_TYPE_WARNS
#undef GMQCC_TYPE_OPTIONS
#undef GMQCC_TYPE_OPTIMIZATIONS
#undef GMQCC_DEFINE_FLAG

4756
parser.c

File diff suppressed because it is too large Load diff

6416
parser.cpp Normal file

File diff suppressed because it is too large Load diff

84
parser.h Normal file
View file

@ -0,0 +1,84 @@
#ifndef GMQCC_PARSER_HDR
#define GMQCC_PARSER_HDR
#include "gmqcc.h"
#include "lexer.h"
#include "ast.h"
#include "intrin.h"
#include "fold.h"
struct parser_t;
#define parser_ctx(p) ((p)->lex->tok.ctx)
struct parser_t {
parser_t();
~parser_t();
void remove_ast();
lex_file *lex;
int tok;
bool ast_cleaned;
std::vector<ast_expression *> globals;
std::vector<ast_expression *> fields;
std::vector<ast_function *> functions;
size_t translated;
/* must be deleted first, they reference immediates and values */
std::vector<ast_value *> accessors;
ast_value *nil;
ast_value *reserved_version;
size_t crc_globals;
size_t crc_fields;
ast_function *function;
ht aliases;
/* All the labels the function defined...
* Should they be in ast_function instead?
*/
std::vector<ast_label*> labels;
std::vector<ast_goto*> gotos;
std::vector<const char *> breaks;
std::vector<const char *> continues;
/* A list of hashtables for each scope */
std::vector<ht> variables;
ht htfields;
ht htglobals;
std::vector<ht> typedefs;
/* not to be used directly, we use the hash table */
std::vector<ast_expression*> _locals;
std::vector<size_t> _blocklocals;
std::vector<std::unique_ptr<ast_value>> _typedefs;
std::vector<size_t> _blocktypedefs;
std::vector<lex_ctx_t> _block_ctx;
/* we store the '=' operator info */
const oper_info *assign_op;
/* magic values */
ast_value *const_vec[3];
/* pragma flags */
bool noref;
/* collected information */
size_t max_param_count;
fold m_fold;
intrin m_intrin;
};
/* parser.c */
char *parser_strdup (const char *str);
ast_expression *parser_find_global(parser_t *parser, const char *name);
#endif

250
stat.cpp Normal file
View file

@ -0,0 +1,250 @@
#include <string.h>
#include <stdlib.h>
#include "gmqcc.h"
/*
* strdup does it's own malloc, we need to track malloc. We don't want
* to overwrite malloc though, infact, we can't really hook it at all
* without library specific assumptions. So we re implement strdup.
*/
char *stat_mem_strdup(const char *src, bool empty) {
size_t len = 0;
char *ptr = nullptr;
if (!src)
return nullptr;
len = strlen(src);
if ((!empty ? len : true) && (ptr = (char*)mem_a(len + 1))) {
memcpy(ptr, src, len);
ptr[len] = '\0';
}
return ptr;
}
/*
* The reallocate function for resizing vectors.
*/
void _util_vec_grow(void **a, size_t i, size_t s) {
vector_t *d = nullptr;
size_t m = 0;
void *p = nullptr;
if (*a) {
d = vec_meta(*a);
m = 2 * d->allocated + i;
p = mem_r(d, s * m + sizeof(vector_t));
} else {
m = i + 1;
p = mem_a(s * m + sizeof(vector_t));
((vector_t*)p)->used = 0;
}
d = (vector_t*)p;
d->allocated = m;
*a = d + 1;
}
void _util_vec_delete(void *data) {
mem_d(vec_meta(data));
}
/*
* Hash table for generic data, based on dynamic memory allocations
* all around. This is the internal interface, please look for
* EXPOSED INTERFACE comment below
*/
struct hash_node_t {
char *key; /* the key for this node in table */
void *value; /* pointer to the data as void* */
hash_node_t *next; /* next node (linked list) */
};
size_t hash(const char *key);
size_t util_hthash(hash_table_t *ht, const char *key) {
return hash(key) % ht->size;
}
static hash_node_t *_util_htnewpair(const char *key, void *value) {
hash_node_t *node;
if (!(node = (hash_node_t*)mem_a(sizeof(hash_node_t))))
return nullptr;
if (!(node->key = util_strdupe(key))) {
mem_d(node);
return nullptr;
}
node->value = value;
node->next = nullptr;
return node;
}
/*
* EXPOSED INTERFACE for the hashtable implementation
* util_htnew(size) -- to make a new hashtable
* util_htset(table, key, value, sizeof(value)) -- to set something in the table
* util_htget(table, key) -- to get something from the table
* util_htdel(table) -- to delete the table
*/
hash_table_t *util_htnew(size_t size) {
hash_table_t *hashtable = nullptr;
if (size < 1)
return nullptr;
if (!(hashtable = (hash_table_t*)mem_a(sizeof(hash_table_t))))
return nullptr;
if (!(hashtable->table = (hash_node_t**)mem_a(sizeof(hash_node_t*) * size))) {
mem_d(hashtable);
return nullptr;
}
hashtable->size = size;
memset(hashtable->table, 0, sizeof(hash_node_t*) * size);
return hashtable;
}
void util_htseth(hash_table_t *ht, const char *key, size_t bin, void *value) {
hash_node_t *newnode = nullptr;
hash_node_t *next = nullptr;
hash_node_t *last = nullptr;
next = ht->table[bin];
while (next && next->key && strcmp(key, next->key) > 0)
last = next, next = next->next;
/* already in table, do a replace */
if (next && next->key && strcmp(key, next->key) == 0) {
next->value = value;
} else {
/* not found, grow a pair man :P */
newnode = _util_htnewpair(key, value);
if (next == ht->table[bin]) {
newnode->next = next;
ht->table[bin] = newnode;
} else if (!next) {
last->next = newnode;
} else {
newnode->next = next;
last->next = newnode;
}
}
}
void util_htset(hash_table_t *ht, const char *key, void *value) {
util_htseth(ht, key, util_hthash(ht, key), value);
}
void *util_htgeth(hash_table_t *ht, const char *key, size_t bin) {
hash_node_t *pair = ht->table[bin];
while (pair && pair->key && strcmp(key, pair->key) > 0)
pair = pair->next;
if (!pair || !pair->key || strcmp(key, pair->key) != 0)
return nullptr;
return pair->value;
}
void *util_htget(hash_table_t *ht, const char *key) {
return util_htgeth(ht, key, util_hthash(ht, key));
}
void *code_util_str_htgeth(hash_table_t *ht, const char *key, size_t bin);
void *code_util_str_htgeth(hash_table_t *ht, const char *key, size_t bin) {
hash_node_t *pair;
size_t len, keylen;
int cmp;
keylen = strlen(key);
pair = ht->table[bin];
while (pair && pair->key) {
len = strlen(pair->key);
if (len < keylen) {
pair = pair->next;
continue;
}
if (keylen == len) {
cmp = strcmp(key, pair->key);
if (cmp == 0)
return pair->value;
if (cmp < 0)
return nullptr;
pair = pair->next;
continue;
}
cmp = strcmp(key, pair->key + len - keylen);
if (cmp == 0) {
uintptr_t up = (uintptr_t)pair->value;
up += len - keylen;
return (void*)up;
}
pair = pair->next;
}
return nullptr;
}
/*
* Free all allocated data in a hashtable, this is quite the amount
* of work.
*/
void util_htrem(hash_table_t *ht, void (*callback)(void *data)) {
size_t i = 0;
for (; i < ht->size; ++i) {
hash_node_t *n = ht->table[i];
hash_node_t *p;
/* free in list */
while (n) {
if (n->key)
mem_d(n->key);
if (callback)
callback(n->value);
p = n;
n = p->next;
mem_d(p);
}
}
/* free table */
mem_d(ht->table);
mem_d(ht);
}
void util_htrmh(hash_table_t *ht, const char *key, size_t bin, void (*cb)(void*)) {
hash_node_t **pair = &ht->table[bin];
hash_node_t *tmp;
while (*pair && (*pair)->key && strcmp(key, (*pair)->key) > 0)
pair = &(*pair)->next;
tmp = *pair;
if (!tmp || !tmp->key || strcmp(key, tmp->key) != 0)
return;
if (cb)
(*cb)(tmp->value);
*pair = tmp->next;
mem_d(tmp->key);
mem_d(tmp);
}
void util_htrm(hash_table_t *ht, const char *key, void (*cb)(void*)) {
util_htrmh(ht, key, util_hthash(ht, key), cb);
}
void util_htdel(hash_table_t *ht) {
util_htrem(ht, nullptr);
}

1149
test.c

File diff suppressed because it is too large Load diff

1305
test.cpp Normal file

File diff suppressed because it is too large Load diff

18
tests/accumulate.qc Normal file
View file

@ -0,0 +1,18 @@
#define ACCUMULATE_FUNCTION(FUNC) \
[[accumulate]] void FUNC ()
ACCUMULATE_FUNCTION(foo) {
print("hello ");
}
ACCUMULATE_FUNCTION(foo) {
print("accumulation ");
}
ACCUMULATE_FUNCTION(foo) {
print("world\n");
}
void main() {
foo();
}

5
tests/accumulate.tmpl Normal file
View file

@ -0,0 +1,5 @@
I: accumulate.qc
D: test function accumulation
T: -execute
C: -std=gmqcc -fftepp
M: hello accumulation world

34
tests/aliases.qc Normal file
View file

@ -0,0 +1,34 @@
float alias_1 = 3.14;
void alias_2() {
print("alias_2\n");
}
[[alias("alias_2")]] void alias_2_aliased();
[[alias("alias_1")]] float alias_1_aliased;
// alias to an alias?
vector alias_3;
[[alias("alias_3")]] vector alias_3_aliased;
// expected output
// alias_2
// 3.14
void main() {
alias_2_aliased();
alias_3_aliased= '1 2 3';
print(
ftos(
alias_1_aliased
),
"\n"
);
print(
"x ", ftos(alias_3_aliased_x), "\n",
"y ", ftos(alias_3_aliased_y), "\n",
"z ", ftos(alias_3_aliased_z), "\n"
);
}

9
tests/aliases.tmpl Normal file
View file

@ -0,0 +1,9 @@
I: aliases.qc
D: test aliases
T: -execute
C: -std=gmqcc
M: alias_2
M: 3.14
M: x 1
M: y 2
M: z 3

13
tests/arithexcept.qc Normal file
View file

@ -0,0 +1,13 @@
const float huge = 340282346638528859811704183484516925440.000000; // FLT_MAX
#ifdef DIVBYZERO
const float a = 1.0 / 0.0;
#endif
#ifdef OVERFLOW
const float a = huge * huge;
#endif
#ifdef UNDERFLOW
const float a = 1 / huge;
#endif

4
tests/arithexcept.tmpl Normal file
View file

@ -0,0 +1,4 @@
I: arithexcept.qc
D: arithmetic exceptions (divide by zero)
T: -fail
C: -std=fteqcc -farithmetic-exceptions -DDIVBYZERO

View file

@ -0,0 +1,4 @@
I: arithexcept.qc
D: arithmetic exceptions (overflow)
T: -fail
C: -std=fteqcc -farithmetic-exceptions -DOVERFLOW

View file

@ -0,0 +1,4 @@
I: arithexcept.qc
D: arithmetic exceptions (underflow)
T: -fail
C: -std=fteqcc -farithmetic-exceptions -DUNDERFLOW

View file

@ -1,7 +1,3 @@
void print(...) = #1;
string ftos (float) = #2;
entity() spawn = #3;
float glob[7];
.float above;

View file

@ -1,7 +1,7 @@
I: arrays.qc
D: array accessors and functionality
I: arrays2.qc
D: initialized arrays
T: -execute
C: -std=fteqcc
M: 1001 1101 1201 1301 1401 1501
M: 1001 1101 1201 1301 1401 1501 1601
M: 1001 1101 1201 1301 1401 1501
M: 10 20 30 40 50 60 70
M: 100 200 300 400 500 600 0
M: Hello World

18
tests/arrays2.qc Normal file
View file

@ -0,0 +1,18 @@
float glob1[7] = { 10, 20, 30, 40, 50, 60, 70 };
float glob2[7] = { 100, 200, 300, 400, 500, 600 };
string globs[] = { "Hello ", "World" };
void main() {
float i;
print(ftos(glob1[0]));
for (i = 1; i != 7; ++i)
print(" ", ftos(glob1[i]));
print("\n");
print(ftos(glob2[0]));
for (i = 1; i != 7; ++i)
print(" ", ftos(glob2[i]));
print("\n");
print(globs[0], globs[1], "\n");
}

7
tests/arrays2.tmpl Normal file
View file

@ -0,0 +1,7 @@
I: arrays.qc
D: array accessors and functionality
T: -execute
C: -std=fteqcc
M: 1001 1101 1201 1301 1401 1501
M: 1001 1101 1201 1301 1401 1501 1601
M: 1001 1101 1201 1301 1401 1501

37
tests/bitnot.qc Normal file
View file

@ -0,0 +1,37 @@
void main() {
float a; a = 1;
float b; b = 1;
float c; c = 1;
float d; d = 1;
vector e; e = '1 1 1';
vector f; f = '1 1 1';
#ifdef __STD_FTEQCC__
a &~= 1; // 0
#else
a &= ~1; // 0
#endif
#ifdef __STD_GMQCC__
b &= ~1; // 0
c &= ~d; // 0
#else
b &~= 1; // 0
c &~= 1; // 0
#endif
#ifdef __STD_FTEQCC__
f &~= e; // '0 0 0'
#else
f &= ~e; // '0 0 0'
#endif
#ifdef __STD_GMQCC__
e &= ~e; // '0 0 0'
#else
e &~= e; // '0 0 0'
#endif
print("a: ", ftos(a), "\nb: ",
ftos(b), "\nc: ",
ftos(c), "\n");
print("e: ", vtos(e), "\n");
print("f: ", vtos(f), "\n");
}

11
tests/bitnot.tmpl Normal file
View file

@ -0,0 +1,11 @@
# used to test the builtins
I: bitnot.qc
D: test bitwise not operators (fteqcc operators)
T: -execute
C: -std=fteqcc
E: $null
M: a: 0
M: b: 0
M: c: 0
M: e: '0 0 0'
M: f: '0 0 0'

11
tests/bitnotgmqcc.tmpl Normal file
View file

@ -0,0 +1,11 @@
# used to test the builtins
I: bitnot.qc
D: test bitwise not operators (gmqcc operators)
T: -execute
C: -std=gmqcc -fftepp
E: $null
M: a: 0
M: b: 0
M: c: 0
M: e: '0 0 0'
M: f: '0 0 0'

View file

@ -1,6 +1,3 @@
void print(...) = #1;
string ftos (float) = #2;
void test(float brkat, float contat) {
float i;

View file

@ -1,5 +1,3 @@
void(string) print = #1;
void() main = {
print("hello world");
}

View file

@ -4,6 +4,4 @@ D: test builtin functions
T: -execute
C: -std=gmqcc
E: $null
F: builtins failed
S: builtins worked
M: hello world

View file

@ -1,6 +1,3 @@
void(string, ...) print = #1;
string(float) ftos = #2;
float(float x, float y, float z) sum = {
return x + y + z;
};
@ -11,5 +8,5 @@ void(float a, float b, float c) main = {
sum(sum(sum(a, b, c), b, sum(a, b, c)), b, sum(a, b, sum(a, b, c))),
sum(sum(a, b, c), b, c));
print(ftos(f), "\n");
};

View file

@ -3,6 +3,4 @@ D: test calls
T: -execute
C: -std=gmqcc
E: -float 100 -float 200 -float 300
F: calls failed
S: calls worked
M: 4600

View file

@ -0,0 +1,12 @@
I: correct-logic.qc
D: vector logic flags
T: -execute
C: -std=fteqcc -fshort-logic
M: ! & | i N
M: 0, 0 -> 1 0 0 0 1
M: 0, x -> 1 0 1 0 1
M: x, 0 -> 0 0 1 1 0
M: x, x -> 0 1 1 1 0
M: 0, y -> 1 0 0 0 1
M: y, 0 -> 0 0 0 0 1
M: y, y -> 0 0 0 0 1

View file

@ -0,0 +1,12 @@
I: correct-logic.qc
D: vector logic flags
T: -execute
C: -std=fteqcc
M: ! & | i N
M: 0, 0 -> 1 0 0 0 1
M: 0, x -> 1 0 1 0 1
M: x, 0 -> 0 0 1 1 0
M: x, x -> 0 1 1 1 0
M: 0, y -> 1 0 0 0 1
M: y, 0 -> 0 0 0 0 1
M: y, y -> 0 0 0 0 1

View file

@ -0,0 +1,12 @@
I: correct-logic.qc
D: vector logic flags
T: -execute
C: -std=fteqcc -fcorrect-logic -fshort-logic
M: ! & | i N
M: 0, 0 -> 1 0 0 0 1
M: 0, x -> 1 0 1 0 1
M: x, 0 -> 0 0 1 1 0
M: x, x -> 0 1 1 1 0
M: 0, y -> 1 0 1 0 1
M: y, 0 -> 0 0 1 1 0
M: y, y -> 0 1 1 1 0

View file

@ -0,0 +1,12 @@
I: correct-logic.qc
D: vector logic flags
T: -execute
C: -std=fteqcc -fcorrect-logic
M: ! & | i N
M: 0, 0 -> 1 0 0 0 1
M: 0, x -> 1 0 1 0 1
M: x, 0 -> 0 0 1 1 0
M: x, x -> 0 1 1 1 0
M: 0, y -> 1 0 1 0 1
M: y, 0 -> 0 0 1 1 0
M: y, y -> 0 1 1 1 0

24
tests/correct-logic.qc Normal file
View file

@ -0,0 +1,24 @@
float test_s_not (vector s) { return !s; }
float test_s_and (vector s, vector t) { return s && t; }
float test_s_or (vector s, vector t) { return s || t; }
float test_s_if (vector s) { if (s) return 1; return 0; }
float test_s_ifnot(vector s) { if not (s) return 1; return 0; }
void test(vector s, vector t) {
print(ftos(!!test_s_not (s)), " ");
print(ftos(!!test_s_and (s, t)), " ");
print(ftos(!!test_s_or (s, t)), " ");
print(ftos(!!test_s_if (s)), " ");
print(ftos(!!test_s_ifnot(s)), "\n");
}
void main() {
print(" ! & | i N\n");
print("0, 0 -> "); test('0 0 0', '0 0 0');
print("0, x -> "); test('0 0 0', '1 0 0');
print("x, 0 -> "); test('1 0 0', '0 0 0');
print("x, x -> "); test('1 0 0', '1 0 0');
print("0, y -> "); test('0 0 0', '0 1 0');
print("y, 0 -> "); test('0 1 0', '0 0 0');
print("y, y -> "); test('0 1 0', '0 1 0');
}

View file

@ -0,0 +1,14 @@
I: correct-vs-short.qc
D: correct-logic vs short-logic without perl-logic
T: -execute
C: -std=fteqcc
M: X & | B
M: 0 0 0, 0 0 0 :: 0 0 0
M: 0 0 0, 5 0 0 :: 0 2 1
M: 5 0 0, 0 0 0 :: 0 2 1
M: 5 0 0, 5 0 0 :: 2 2 2
M: Y & | B
M: 0 0 0, 0 0 0 :: 0 0 0
M: 0 0 0, 0 5 0 :: 0 0 0
M: 0 5 0, 0 0 0 :: 0 0 0
M: 0 5 0, 0 5 0 :: 0 0 0

View file

@ -0,0 +1,14 @@
I: correct-vs-short.qc
D: correct-logic vs short-logic without perl-logic
T: -execute
C: -std=fteqcc -fcorrect-logic
M: X & | B
M: 0 0 0, 0 0 0 :: 0 0 0
M: 0 0 0, 5 0 0 :: 0 2 1
M: 5 0 0, 0 0 0 :: 0 2 1
M: 5 0 0, 5 0 0 :: 2 2 2
M: Y & | B
M: 0 0 0, 0 0 0 :: 0 0 0
M: 0 0 0, 0 5 0 :: 0 2 1
M: 0 5 0, 0 0 0 :: 0 2 1
M: 0 5 0, 0 5 0 :: 2 2 2

View file

@ -0,0 +1,14 @@
I: correct-vs-short.qc
D: correct-logic vs short-logic without perl-logic
T: -execute
C: -std=fteqcc -fcorrect-logic -fshort-logic
M: X & | B
M: 0 0 0, 0 0 0 :: 0 0 0
M: 0 0 0, 5 0 0 :: 0 2 1
M: 5 0 0, 0 0 0 :: 0 2 1
M: 5 0 0, 5 0 0 :: 2 2 2
M: Y & | B
M: 0 0 0, 0 0 0 :: 0 0 0
M: 0 0 0, 0 5 0 :: 0 2 1
M: 0 5 0, 0 0 0 :: 0 2 1
M: 0 5 0, 0 5 0 :: 2 2 2

18
tests/correct-vs-short.qc Normal file
View file

@ -0,0 +1,18 @@
void test(vector a, vector b) {
print(ftos((a && b) + (a && b)), " ");
print(ftos((a || b) + (a || b)), " ");
print(ftos((a && b) + (a || b)), "\n");
}
void main() {
print("X & | B\n");
print("0 0 0, 0 0 0 :: "); test('0 0 0', '0 0 0');
print("0 0 0, 5 0 0 :: "); test('0 0 0', '5 0 0');
print("5 0 0, 0 0 0 :: "); test('5 0 0', '0 0 0');
print("5 0 0, 5 0 0 :: "); test('5 0 0', '5 0 0');
print("Y & | B\n");
print("0 0 0, 0 0 0 :: "); test('0 0 0', '0 0 0');
print("0 0 0, 0 5 0 :: "); test('0 0 0', '0 5 0');
print("0 5 0, 0 0 0 :: "); test('0 5 0', '0 0 0');
print("0 5 0, 0 5 0 :: "); test('0 5 0', '0 5 0');
}

21
tests/defs.qh Normal file
View file

@ -0,0 +1,21 @@
// builtins for the standalone qcvm included with gmqcc
// in exec.c These should be updated to reflect the new
// builtins. I no event shall you even consider adding
// these individually per test.
void (string str, ...) print = #1;
string (float val) ftos = #2;
entity () spawn = #3;
void (entity ent) kill = #4;
string (vector vec) vtos = #5;
void (string str) error = #6;
float (vector vec) vlen = #7;
string (entity ent) etos = #8;
float (string str) stof = #9;
string (...) strcat = #10;
float (string str1, string str2) strcmp = #11;
vector (vector vec) normalize = #12;
float (float val) sqrt = #13;
float (float val) floor = #14;
float (float val1, float val2) pow = #15;
vector (string str) stov = #16;

27
tests/dots.qc Normal file
View file

@ -0,0 +1,27 @@
entity self;
.float f;
..float fp;
...float fpp;
void try(entity e, ...float pp) {
print("and: ", ftos( e.(e.(e.pp)) ), "\n");
}
typedef float Float;
void try2(entity e, ...Float pp) {
print("and: ", ftos( e.(e.(e.pp)) ), "\n");
}
// whereas the varargs are tested in vararg tests
void main() {
self = spawn();
self.f = 123;
self.fp = f;
self.fpp = fp;
print(ftos( self.(self.fp) ), "\n");
print(ftos( self.(self.(self.fpp)) ), "\n");
try(self, fpp);
try2(self, fpp);
}

8
tests/dots.tmpl Normal file
View file

@ -0,0 +1,8 @@
I: dots.qc
D: TOKEN_DOTS disambiguation
T: -execute
C: -std=fteqcc
M: 123
M: 123
M: and: 123
M: and: 123

68
tests/enum.qc Normal file
View file

@ -0,0 +1,68 @@
enum {
// this behaviour is confusing, but I like that
// we support it.
__ = (__ - 1),
A = (__ + 1),
B,
C
};
enum {
D = C + B,
E = C + C,
F = C + D,
};
enum {
G = (B + F), H = (C + F),
I = (D + F), J = (B + I)
};
enum {
K = A + B - C + D - E + F *
G - H + I - J + A - B -
J + A,
L,
M,
N
};
enum : flag {
F1, /* = 1 << 1 */
F2, /* = 1 << 2 */
F3 /* = 1 << 3 */
};
/* reversed enumeration */
enum : reverse {
R1, // 3
R2, // 2
R3, // 1
R4 // 0
};
void main() {
print(ftos(A), "\n");
print(ftos(B), "\n");
print(ftos(C), "\n");
print(ftos(D), "\n");
print(ftos(E), "\n");
print(ftos(F), "\n");
print(ftos(G), "\n");
print(ftos(H), "\n");
print(ftos(I), "\n");
print(ftos(J), "\n");
print(ftos(K), "\n");
print(ftos(L), "\n");
print(ftos(M), "\n");
print(ftos(N), "\n");
print(ftos(F1), "\n");
print(ftos(F2), "\n");
print(ftos(F3), "\n");
print(ftos(R1), "\n");
print(ftos(R2), "\n");
print(ftos(R3), "\n");
print(ftos(R4), "\n");
};

25
tests/enum.tmpl Normal file
View file

@ -0,0 +1,25 @@
I: enum.qc
D: enumerations
T: -execute
C: -std=fteqcc
M: 0
M: 1
M: 2
M: 3
M: 4
M: 5
M: 6
M: 7
M: 8
M: 9
M: 10
M: 11
M: 12
M: 13
M: 2
M: 4
M: 8
M: 3
M: 2
M: 1
M: 0

View file

@ -1,6 +1,3 @@
void(string, ...) print = #1;
string(float) ftos = #2;
void(float a, float b) main = {
if (a == b) print("eq,");
if (a != b) print("ne,");

View file

@ -3,6 +3,4 @@ D: test equality
T: -execute
C: -std=gmqcc
E: -float 100 -float 200
F: equality failed
S: equality worked
M: ne,lt,le,

14
tests/exponentiation.qc Normal file
View file

@ -0,0 +1,14 @@
void main() {
float hundy = __builtin_pow(10, 2); // 10^2 == 100
print(ftos(hundy), "\n"); // prints: 100
hundy = pow(10, 2);
print(ftos(hundy), "\n");
hundy -= 90; // 100-90 = 10
print(ftos(hundy ** 2), "\n"); // prints: 100
print(ftos(pow(hundy, 2)), "\n"); // prints: 100
hundy = 10.0f;
print(ftos(__builtin_exp(hundy)), "\n"); // prints: 22026.5
}

11
tests/exponentiation.tmpl Normal file
View file

@ -0,0 +1,11 @@
# used to test the builtins
I: exponentiation.qc
D: test exponentiation operator and __builtin_pow
T: -execute
C: -std=gmqcc
E: $null
M: 100
M: 100
M: 100
M: 100
M: 22026.5

7
tests/exprforbuiltins.qc Normal file
View file

@ -0,0 +1,7 @@
/* empty line required */
void print(string, ...) = #__LINE__ - 1;
void main(string input) {
print(input, "\n");
}

View file

@ -0,0 +1,7 @@
I: exprforbuiltins.qc
D: expressions for builtins
T: -execute
C: -std=gmqcc -fftepp -fftepp-predefs
F: -no-defs
E: -string test
M: test

13
tests/fieldfuncs.qc Normal file
View file

@ -0,0 +1,13 @@
.float field;
.float getfield() {
return field;
}
void() main = {
entity e = spawn();
e.field = 42;
print(ftos(e.(getfield())), "\n");
.float memptr = getfield();
print(ftos(e.memptr), "\n");
}

6
tests/fieldfuncs.tmpl Normal file
View file

@ -0,0 +1,6 @@
I: fieldfuncs.qc
D: test fields with functions
T: -execute
C: -std=fte
M: 42
M: 42

View file

@ -1,6 +1,3 @@
void(string, string) print = #1;
entity() spawn = #3;
.string a;
.string b;
..string ps;

View file

@ -3,7 +3,5 @@ D: test field paramaters
T: -execute
C: -std=qcc
E: $null
F: field paramaters fail
S: field paramaters work
M: bar
M: foo

13
tests/forloop.qc Normal file
View file

@ -0,0 +1,13 @@
void main() {
float j;
for (j = 0; j < 2; ++j)
print("+");
for (float i = 0; i < 5; ++i)
print("*");
for (;;) {
print("\n");
break;
}
}

5
tests/forloop.tmpl Normal file
View file

@ -0,0 +1,5 @@
I: forloop.qc
D: test for loops
T: -execute
C: -std=gmqcc
M: ++*****

20
tests/framemacro.qc Normal file
View file

@ -0,0 +1,20 @@
$frame frame1 frame2
float time;
entity self;
.float frame;
.float nextthink;
.void() think;
// Mixing syntax, = is optional.
void frame1_func_mixed_no_assign() [$frame1, frame2_func_mixed_no_assign] {}
void frame2_func_mixed_no_assign() [$frame2, frame2_func_mixed_no_assign] {}
void frame1_func_mixed() =[$frame1, frame2_func_mixed] {}
void frame2_func_mixed() =[$frame2, frame2_func_mixed] {}
void() frame1_func_old =[$frame1, frame2_func_old] {}
void() frame2_func_old =[$frame2, frame2_func_old] {}

4
tests/framemacro.tmpl Normal file
View file

@ -0,0 +1,4 @@
I: framemacro.qc
D: test frame macros
T: -compile
C: -std=gmqcc

View file

@ -1,5 +1,3 @@
void(string, string) print = #1;
string() getter = {
return "correct";
};

View file

@ -3,6 +3,4 @@ D: test functions as paramaters
T: -execute
C: -std=gmqcc
E: $null
F: functions as paramaters failed
S: functions as paramaters passed
M: correct

32
tests/goto.qc Normal file
View file

@ -0,0 +1,32 @@
// correct execution order:
// label_3
// label_2
// label_4
// label_3
// label_1
// label_5
void main() {
float x = 1;
float y = 2;
goto label_3;
:label_1; print("label_1", "\n"); goto label_5;
:label_2; print("label_2", "\n"); goto label_4;
:label_3; print("label_3", "\n");
// will goto label_2
goto (x == y) ? label_1 : label_2;
:label_4; print("label_4", "\n");
{
x = 1;
y = 1;
// will goto label_1
// then goes label_5
goto label_3;
}
:label_5; print("label_5", "\n");
}

10
tests/goto.tmpl Normal file
View file

@ -0,0 +1,10 @@
I: goto.qc
D: test goto (both normal and computed)
T: -execute
C: -std=gmqcc
M: label_3
M: label_2
M: label_4
M: label_3
M: label_1
M: label_5

View file

@ -1,5 +1,3 @@
void(string, ...) print = #1;
void(float c) main = {
if (c == 1)
print("One\n");

View file

@ -3,6 +3,4 @@ D: test if statement
T: -execute
C: -std=gmqcc
E: -float 2
F: if statement failed
S: if statement passed
M: Two

7
tests/inexact-local.qc Normal file
View file

@ -0,0 +1,7 @@
void main() {
const float a = 1.0 / 3.0;
const float b = 0.33333333333;
if (a == b) {
// Should trigger warning
}
}

4
tests/inexact-local.tmpl Normal file
View file

@ -0,0 +1,4 @@
I: inexact-local.qc
D: inexact comparisons
T: -fail
C: -std=gmqcc -Winexact-compares -Wall -Werror

8
tests/inexact.qc Normal file
View file

@ -0,0 +1,8 @@
const float a = 1.0 / 3.0;
const float b = 0.33333333333;
void main() {
if (a == b) {
// Should trigger warning
}
}

4
tests/inexact.tmpl Normal file
View file

@ -0,0 +1,4 @@
I: inexact.qc
D: inexact comparisons
T: -fail
C: -std=gmqcc -Winexact-compares -Wall -Werror

Some files were not shown because too many files have changed in this diff Show more