davidph / gdcc Goto Github PK
View Code? Open in Web Editor NEWGame Data Compiler Collection
License: Other
Game Data Compiler Collection
License: Other
While support for complex types is optional in C11, it would be nice and shouldn't be too difficult with the right method of implementation.
Platform has a header-only dependency on IR for a couple enums and a small class. Since IR has Platform as a dependency, and using
exists, there is no reason those types cannot just be moved to Platform to avoid the dependency cycle.
Since I use Embedded C's fixed point semantics, that should include implementing _Sat
/sat
. Finding ways to do so efficiently might be a challenge, though.
Similar to C++'s noexcept
, it would be useful to be able to mark functions are not generating/propagating long jumps so that callers can omit the post-call check. There should also be a way to set this in bulk. Possibly a pragma and/or option.
Current system is insufficiently expressive, specifically with regards to compound assignment. Also, the current structure property names are inconsistent with C/C++. Instead, it should use a syntax like C++'s operators. Additionally, __arg
should be replaced with some other token, so that the only non-C/C++ keyword in use is __prop
.
Tentative grammar changes:
struct-property-name:
<default>
<operator> struct-property-operator
<__operator> struct-property-operator
struct-property-operator:
()
assignment-operator
struct-property-argument:
<this>
<__this>
* <this>
* <__this>
-> identifier
...
constant-expression
The constraints will remain the same, only allowing each operator to appear once and only allowing this
once per operator.
Higher level codegen sometimes generates unconditional branches to what ends up being the next code. These branches should be translated out during an opt phase. Alternatively, their generation could be avoided, but this would likely be much more complicated to do at the higher level.
I keep kicking this idea around of adding a chunk to ACSE for GDCC to read external definitions from so that users can pass a bytecode library to gdcc-ld to automatically handle allocation offsets and such. This is a good idea and every day that GDCC does not have this is a sad day.
These are actually needed now for DGE, though they should also work for ZDACS.
Would be nice to have subnormal support in the softfloat implementation. Should be possible, but I would want to ensure it doesn't negatively affect the performance of normalized numbers. Possibly a compile-time option to enable/disable subnormal support?
This would allow a proper fix for ACC needing different implicit conversion rules than CC by having that handled as a virtual. It would also be a good opportunity to clean up the slightly different methods of expression/statement creation into a uniform style. Just need a good name for such a class. Creator
seems too generic, but might be the most sensible.
As it says in the title, because of the case-forcing in ACC
, macros defined by command line with uppercase letters are inaccessible. Barring a total rework of how case insensitivity is handled under ACS, the best solution probably involved splitting up CPP::MacroMap::reset
so that CC
and ACC
can invoke the needed parts. This would also help resolve the quirk that standard C macros get defined for ACS.
In addition to the name lookup, the macro contents must also be addressed. The more pressing issue being the case insensitivity requirement of ACS, but the possibility of different tokenizing rules should also be accounted for. Maybe the macro bodies should be stored as text instead of pre-tokenized? The cost of tokenizing command line macro bodies for each source file is not greatly concerning.
Currently, compound literals work by generating an object, then making a *(obj = init, &obj)
expression with it. This has several unfortunate consequences. Particularly the fact that it takes the object's address, meaning that it has to have automatic storage even if the compound literal's address is not otherwise used. It also means that it initializes an object even when it is only used for its value. The solution is, I think, to have a dedicated compound literal expression class that can defer object creation.
Currently, multiword map register objects only export/import a single word, silently causing incorrect codegen.
Hi, I came across GDCC looking for an ACS compiler that would fit the needs for a total conversion I'm working on. I noted that specials were defined in the .acs/.h files for GDCC, which was perfect for me since I just want to keep the language to be able to carry across engine familiarity, and just redefine what functions it has.
My only concern is if it'd be possible to add redefining script types/flags (OPEN, ENTER, NET, etc)? I think it's the only thing that I'm worried about. My options without that are:
#define
to remap to less misleading names for the ACS version, but either way, would be kind of a gross hack.I think I have a vague idea how to implement it in the ACS version of the compiler, but the C compiler part is a bit beyond me 😅
Thanks in advance 🙇♀️
This is a long-standing compliance issue and something that can be very disruptive when it comes up.
Everything that converts to a hard boolean value uses a pair of LNot
instructions. This is both a nuisance to do and potentially less efficient, since it forces the value onto the stack in the IR. A unified instruction would be easy to implement and used frequently. (Might be better as part of the Tr**
set, though.)
In practice, there is no reason to catch exceptions below Core::Exception
. They should probably be hidden behind static functions. Furthermore, there remain many places which still directly print an error and throw EXIT_FAILURE
. While embedding GDCC is not a priority use case, these are nevertheless an unfortunate inconsistency.
These types limit the pointer size of the target, and therefore should be at least 64 bits. The only reason they are still only long
is lack of conversion from mpz_class
, which should not be too difficult to implement in a satisfactory way.
Currently, all float ops truncate rather than round in a controlled manner. This results in the accumulation of single ULP errors. Not a huge problem, but something to address eventually.
Using C with __asm
blocks would allow handling minor platform variations much easier.
The following results in an incomplete type error, but should be allowed. (Obviously it can't be called until X is defined, but the declaration is wholesome.)
struct X;
void fn(struct X x);
Being able to reference labels defined in C from inline assembly would be a useful and likely easily added feature. Unless an alternative is proposed, the syntax will probably be : identifier :
.
This code:
int a[] = {};
Produces this error:
ERROR: SR::TypeError
It needs to produce a proper error, instead.
The ACS front currently has a fixed set of keywords it accepts for script types/flags. This creates an extra step to adding ACS script types and makes the feature useless for non-ACS targets.
Replacing script-type
and script-flag-sequence
with identifier-sequence
in script-declaration
is grammatically unambiguous, so that seems like the best route. This would need to be accompanied by a warning/error in the ZDACS bytecode module for unrecognized script types, however. Also it would require the bytecode module to be case insensitive about type names or for the canonical names to be made lowercase. I am inclined to the latter, but it would break existing C code. (Although, it would produce a compile-time error rather than silently breaking code and would be a minor syntactic fix.)
The big question is whether to make this change in the base grammar or the extension grammar. Most likely the former, though, as it would be easy enough to justify acc's stricter requirements as a note.
Code which reads an object which could not have been initialized prior to being read should issue a warning. Such as:
int i = i;
int i;
int j + i + 10;
int i;
if(i) {}
Tracking and warning for potentially uninitialized reads would be nice, but there would certainly be false positives. Still, if it proves reasonably simple, these should also issue a warning at high warn level:
int i;
if(cond())
i = 10;
int j = i * 7;
The following, however, should not issue any warning:
void *p = &p; // Valid and well-defined.
int i, k;
int j = cond();
if(j)
i = 10;
if(j)
k = i + 6; // Has the same condition as the initialization.
else
k = 42;
int i; // GDCC is not advanced enough to second-guess labels and goto usage.
label: if(i) {}
Need support for the float formats in printf (%e, %f, %g). The absence of which is becoming increasingly conspicuous.
Need to implement strftime
.
There is not presently support for the %lc
and %ls
formats in printf
/scanf
, and there should be.
[ 7%] Building CXX object src/IR/CMakeFiles/gdcc-ir-lib.dir/Addr.cpp.o
In file included from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:0:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:69:39: error: declaration of ‘operator>>’ as non-function
IArchive &operator >> (Core::Float &out);
^
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:69:29: error: expected ‘;’ at end of member declaration
IArchive &operator >> (Core::Float &out);
^
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:69:45: error: expected ‘)’ before ‘&’ token
IArchive &operator >> (Core::Float &out);
^
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:70:39: error: declaration of ‘operator>>’ as non-function
IArchive &operator >> (Core::Integ &out);
^
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:70:29: error: expected ‘;’ at end of member declaration
IArchive &operator >> (Core::Integ &out);
^
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:70:45: error: expected ‘)’ before ‘&’ token
IArchive &operator >> (Core::Integ &out);
^
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp: In member function ‘bool GDCC::IR::IArchive::getBool()’:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:79:21: error: ‘strcmp’ is not a member of ‘std’
return !std::strcmp(get(), "1");
^
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp: In member function ‘GDCC::IR::IArchive& GDCC::IR::IArchive::getNumber(T&)’:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:94:41: error: ‘strlen’ is not a member of ‘std’
Core::StringStream in{s, std::strlen(s)};
^
In file included from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:16:0:
/home/prophessor/tmp/GDCC/inc/IR/OArchive.hpp: At global scope:
/home/prophessor/tmp/GDCC/inc/IR/OArchive.hpp:65:45: error: declaration of ‘operator<<’ as non-function
OArchive &operator << (Core::Float const &in) {return putNumber(in);}
^
/home/prophessor/tmp/GDCC/inc/IR/OArchive.hpp:65:29: error: expected ‘;’ at end of member declaration
OArchive &operator << (Core::Float const &in) {return putNumber(in);}
^
/home/prophessor/tmp/GDCC/inc/IR/OArchive.hpp:65:45: error: expected ‘)’ before ‘const’
OArchive &operator << (Core::Float const &in) {return putNumber(in);}
^
/home/prophessor/tmp/GDCC/inc/IR/OArchive.hpp:66:45: error: declaration of ‘operator<<’ as non-function
OArchive &operator << (Core::Integ const &in) {return putNumber(in);}
^
/home/prophessor/tmp/GDCC/inc/IR/OArchive.hpp:66:29: error: expected ‘;’ at end of member declaration
OArchive &operator << (Core::Integ const &in) {return putNumber(in);}
^
/home/prophessor/tmp/GDCC/inc/IR/OArchive.hpp:66:45: error: expected ‘)’ before ‘const’
OArchive &operator << (Core::Integ const &in) {return putNumber(in);}
^
In file included from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:0:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp: In instantiation of ‘GDCC::IR::IArchive& GDCC::IR::IArchive::getNumber(T&) [with T = signed char]’:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:53:82: required from here
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:94:55: error: no matching function for call to ‘GDCC::Core::StringStream::StringStream(<brace-enclosed initializer list>)’
Core::StringStream in{s, std::strlen(s)};
^
In file included from /home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:18:0,
from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: candidate: GDCC::Core::StringStream::StringStream(const char*, std::size_t)
StringStream(char const *str, std::size_t len) :
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: conversion of argument 2 would be ill-formed:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate: GDCC::Core::StringStream::StringStream(GDCC::Core::String)
explicit StringStream(String src) : std::istream{&buf}, buf{src} {}
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate expects 1 argument, 2 provided
In file included from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:0:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp: In instantiation of ‘GDCC::IR::IArchive& GDCC::IR::IArchive::getNumber(T&) [with T = short int]’:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:54:82: required from here
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:94:55: error: no matching function for call to ‘GDCC::Core::StringStream::StringStream(<brace-enclosed initializer list>)’
Core::StringStream in{s, std::strlen(s)};
^
In file included from /home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:18:0,
from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: candidate: GDCC::Core::StringStream::StringStream(const char*, std::size_t)
StringStream(char const *str, std::size_t len) :
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: conversion of argument 2 would be ill-formed:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate: GDCC::Core::StringStream::StringStream(GDCC::Core::String)
explicit StringStream(String src) : std::istream{&buf}, buf{src} {}
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate expects 1 argument, 2 provided
In file included from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:0:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp: In instantiation of ‘GDCC::IR::IArchive& GDCC::IR::IArchive::getNumber(T&) [with T = int]’:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:55:82: required from here
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:94:55: error: no matching function for call to ‘GDCC::Core::StringStream::StringStream(<brace-enclosed initializer list>)’
Core::StringStream in{s, std::strlen(s)};
^
In file included from /home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:18:0,
from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: candidate: GDCC::Core::StringStream::StringStream(const char*, std::size_t)
StringStream(char const *str, std::size_t len) :
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: conversion of argument 2 would be ill-formed:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate: GDCC::Core::StringStream::StringStream(GDCC::Core::String)
explicit StringStream(String src) : std::istream{&buf}, buf{src} {}
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate expects 1 argument, 2 provided
In file included from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:0:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp: In instantiation of ‘GDCC::IR::IArchive& GDCC::IR::IArchive::getNumber(T&) [with T = long int]’:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:56:82: required from here
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:94:55: error: no matching function for call to ‘GDCC::Core::StringStream::StringStream(<brace-enclosed initializer list>)’
Core::StringStream in{s, std::strlen(s)};
^
In file included from /home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:18:0,
from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: candidate: GDCC::Core::StringStream::StringStream(const char*, std::size_t)
StringStream(char const *str, std::size_t len) :
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: conversion of argument 2 would be ill-formed:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate: GDCC::Core::StringStream::StringStream(GDCC::Core::String)
explicit StringStream(String src) : std::istream{&buf}, buf{src} {}
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate expects 1 argument, 2 provided
In file included from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:0:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp: In instantiation of ‘GDCC::IR::IArchive& GDCC::IR::IArchive::getNumber(T&) [with T = long long int]’:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:57:82: required from here
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:94:55: error: no matching function for call to ‘GDCC::Core::StringStream::StringStream(<brace-enclosed initializer list>)’
Core::StringStream in{s, std::strlen(s)};
^
In file included from /home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:18:0,
from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: candidate: GDCC::Core::StringStream::StringStream(const char*, std::size_t)
StringStream(char const *str, std::size_t len) :
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: conversion of argument 2 would be ill-formed:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate: GDCC::Core::StringStream::StringStream(GDCC::Core::String)
explicit StringStream(String src) : std::istream{&buf}, buf{src} {}
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate expects 1 argument, 2 provided
In file included from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:0:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp: In instantiation of ‘GDCC::IR::IArchive& GDCC::IR::IArchive::getNumber(T&) [with T = unsigned char]’:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:59:84: required from here
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:94:55: error: no matching function for call to ‘GDCC::Core::StringStream::StringStream(<brace-enclosed initializer list>)’
Core::StringStream in{s, std::strlen(s)};
^
In file included from /home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:18:0,
from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: candidate: GDCC::Core::StringStream::StringStream(const char*, std::size_t)
StringStream(char const *str, std::size_t len) :
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: conversion of argument 2 would be ill-formed:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate: GDCC::Core::StringStream::StringStream(GDCC::Core::String)
explicit StringStream(String src) : std::istream{&buf}, buf{src} {}
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate expects 1 argument, 2 provided
In file included from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:0:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp: In instantiation of ‘GDCC::IR::IArchive& GDCC::IR::IArchive::getNumber(T&) [with T = short unsigned int]’:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:60:84: required from here
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:94:55: error: no matching function for call to ‘GDCC::Core::StringStream::StringStream(<brace-enclosed initializer list>)’
Core::StringStream in{s, std::strlen(s)};
^
In file included from /home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:18:0,
from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: candidate: GDCC::Core::StringStream::StringStream(const char*, std::size_t)
StringStream(char const *str, std::size_t len) :
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: conversion of argument 2 would be ill-formed:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate: GDCC::Core::StringStream::StringStream(GDCC::Core::String)
explicit StringStream(String src) : std::istream{&buf}, buf{src} {}
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate expects 1 argument, 2 provided
In file included from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:0:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp: In instantiation of ‘GDCC::IR::IArchive& GDCC::IR::IArchive::getNumber(T&) [with T = unsigned int]’:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:61:84: required from here
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:94:55: error: no matching function for call to ‘GDCC::Core::StringStream::StringStream(<brace-enclosed initializer list>)’
Core::StringStream in{s, std::strlen(s)};
^
In file included from /home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:18:0,
from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: candidate: GDCC::Core::StringStream::StringStream(const char*, std::size_t)
StringStream(char const *str, std::size_t len) :
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: conversion of argument 2 would be ill-formed:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate: GDCC::Core::StringStream::StringStream(GDCC::Core::String)
explicit StringStream(String src) : std::istream{&buf}, buf{src} {}
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate expects 1 argument, 2 provided
In file included from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:0:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp: In instantiation of ‘GDCC::IR::IArchive& GDCC::IR::IArchive::getNumber(T&) [with T = long unsigned int]’:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:62:84: required from here
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:94:55: error: no matching function for call to ‘GDCC::Core::StringStream::StringStream(<brace-enclosed initializer list>)’
Core::StringStream in{s, std::strlen(s)};
^
In file included from /home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:18:0,
from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: candidate: GDCC::Core::StringStream::StringStream(const char*, std::size_t)
StringStream(char const *str, std::size_t len) :
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: conversion of argument 2 would be ill-formed:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate: GDCC::Core::StringStream::StringStream(GDCC::Core::String)
explicit StringStream(String src) : std::istream{&buf}, buf{src} {}
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate expects 1 argument, 2 provided
In file included from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:0:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp: In instantiation of ‘GDCC::IR::IArchive& GDCC::IR::IArchive::getNumber(T&) [with T = long long unsigned int]’:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:63:84: required from here
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:94:55: error: no matching function for call to ‘GDCC::Core::StringStream::StringStream(<brace-enclosed initializer list>)’
Core::StringStream in{s, std::strlen(s)};
^
In file included from /home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:18:0,
from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: candidate: GDCC::Core::StringStream::StringStream(const char*, std::size_t)
StringStream(char const *str, std::size_t len) :
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: conversion of argument 2 would be ill-formed:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate: GDCC::Core::StringStream::StringStream(GDCC::Core::String)
explicit StringStream(String src) : std::istream{&buf}, buf{src} {}
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate expects 1 argument, 2 provided
In file included from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:0:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp: In instantiation of ‘GDCC::IR::IArchive& GDCC::IR::IArchive::getNumber(T&) [with T = float]’:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:65:72: required from here
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:94:55: error: no matching function for call to ‘GDCC::Core::StringStream::StringStream(<brace-enclosed initializer list>)’
Core::StringStream in{s, std::strlen(s)};
^
In file included from /home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:18:0,
from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: candidate: GDCC::Core::StringStream::StringStream(const char*, std::size_t)
StringStream(char const *str, std::size_t len) :
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: conversion of argument 2 would be ill-formed:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate: GDCC::Core::StringStream::StringStream(GDCC::Core::String)
explicit StringStream(String src) : std::istream{&buf}, buf{src} {}
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate expects 1 argument, 2 provided
In file included from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:0:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp: In instantiation of ‘GDCC::IR::IArchive& GDCC::IR::IArchive::getNumber(T&) [with T = double]’:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:66:72: required from here
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:94:55: error: no matching function for call to ‘GDCC::Core::StringStream::StringStream(<brace-enclosed initializer list>)’
Core::StringStream in{s, std::strlen(s)};
^
In file included from /home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:18:0,
from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: candidate: GDCC::Core::StringStream::StringStream(const char*, std::size_t)
StringStream(char const *str, std::size_t len) :
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: conversion of argument 2 would be ill-formed:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate: GDCC::Core::StringStream::StringStream(GDCC::Core::String)
explicit StringStream(String src) : std::istream{&buf}, buf{src} {}
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate expects 1 argument, 2 provided
In file included from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:0:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp: In instantiation of ‘GDCC::IR::IArchive& GDCC::IR::IArchive::getNumber(T&) [with T = long double]’:
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:67:72: required from here
/home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:94:55: error: no matching function for call to ‘GDCC::Core::StringStream::StringStream(<brace-enclosed initializer list>)’
Core::StringStream in{s, std::strlen(s)};
^
In file included from /home/prophessor/tmp/GDCC/inc/IR/IArchive.hpp:18:0,
from /home/prophessor/tmp/GDCC/src/IR/Addr.cpp:15:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: candidate: GDCC::Core::StringStream::StringStream(const char*, std::size_t)
StringStream(char const *str, std::size_t len) :
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:61:10: note: conversion of argument 2 would be ill-formed:
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate: GDCC::Core::StringStream::StringStream(GDCC::Core::String)
explicit StringStream(String src) : std::istream{&buf}, buf{src} {}
^
/home/prophessor/tmp/GDCC/inc/IR/../Core/StringBuf.hpp:60:19: note: candidate expects 1 argument, 2 provided
cc1plus: warning: unrecognized command line option ‘-Wno-implicit-fallthrough’
cc1plus: warning: unrecognized command line option ‘-Wno-misleading-indentation’
src/IR/CMakeFiles/gdcc-ir-lib.dir/build.make:62: ошибка выполнения рецепта для цели «src/IR/CMakeFiles/gdcc-ir-lib.dir/Addr.cpp.o»
make[2]: *** [src/IR/CMakeFiles/gdcc-ir-lib.dir/Addr.cpp.o] Ошибка 1
CMakeFiles/Makefile2:970: ошибка выполнения рецепта для цели «src/IR/CMakeFiles/gdcc-ir-lib.dir/all»
make[1]: *** [src/IR/CMakeFiles/gdcc-ir-lib.dir/all] Ошибка 2
Makefile:127: ошибка выполнения рецепта для цели «all»
make: *** [all] Error 2```
Casting an array to int is a little unusual, but equally well-defined as casting a pointer to int, and should have the same result. This may end up being a case where any conversion from __aut*
to integer has to convert to __sta*
first.
Doing so currently silently generates invalid code, corrupting the containing structure. Whereas compound assignment on bitfields is well-defined and should work. A good solution here may tie into a solution for compound assignment on properties, but most likely it will come down to an extra version of the arithmetic op codegen.
It would really help to have a few examples. This compiler sounds really great but the documentation is a little dense.
ACS front is missing StrCpy, which is needed for compliance. (And because it's potentially useful.) This should be done using a header declaration like Print or CreateTranslation.
Current behavior when there are no input files is to output no data, which is very problematic if the source file was interpreted as the output file. Having no input files should probably be an error.
Currently, gdcc-acc
accepts calling latent functions (such as delay
) in user-defined functions (which is disallowed in ZDoom's acc
):
function void foo(void) {
delay(1);
}
The compiled ACS code can make Zandronum 2.1.2 and 3.0-alpha to crash when run.
Compiler version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
Error message:
[ 45%] Building CXX object src/CPP/CMakeFiles/gdcc-cpp-lib.dir/IncludeDTBuf.cpp.o
In file included from /home/hdek/build/GDCC/inc/CPP/../CPP/PragmaDTBuf.hpp:17:0,
from /home/hdek/build/GDCC/inc/CPP/TStream.hpp:23,
from /home/hdek/build/GDCC/src/CPP/IncludeDTBuf.cpp:16:
/home/hdek/build/GDCC/inc/CPP/../CPP/../CPP/Pragma.hpp: In constructor ‘GDCC::CPP::PragmaParserACS::PragmaParserACS(GDCC::CPP::PragmaData&)’:
/home/hdek/build/GDCC/inc/CPP/../CPP/../CPP/Pragma.hpp:119:57: error: invalid initialization of non-const reference of type ‘GDCC::CPP::PragmaData&’ from an rvalue of type ‘<brace-enclosed initializer list>’
PragmaParserACS(PragmaData &data_) : data{data_} {}
^
/home/hdek/build/GDCC/inc/CPP/../CPP/../CPP/Pragma.hpp: In constructor ‘GDCC::CPP::PragmaParserGDCC::PragmaParserGDCC(GDCC::CPP::PragmaData&)’:
/home/hdek/build/GDCC/inc/CPP/../CPP/../CPP/Pragma.hpp:135:58: error: invalid initialization of non-const reference of type ‘GDCC::CPP::PragmaData&’ from an rvalue of type ‘<brace-enclosed initializer list>’
PragmaParserGDCC(PragmaData &data_) : data{data_} {}
^
/home/hdek/build/GDCC/inc/CPP/../CPP/../CPP/Pragma.hpp: In constructor ‘GDCC::CPP::PragmaParserSTDC::PragmaParserSTDC(GDCC::CPP::PragmaData&)’:
/home/hdek/build/GDCC/inc/CPP/../CPP/../CPP/Pragma.hpp:151:58: error: invalid initialization of non-const reference of type ‘GDCC::CPP::PragmaData&’ from an rvalue of type ‘<brace-enclosed initializer list>’
PragmaParserSTDC(PragmaData &data_) : data{data_} {}
^
make[2]: *** [src/CPP/CMakeFiles/gdcc-cpp-lib.dir/IncludeDTBuf.cpp.o] Error 1
make[1]: *** [src/CPP/CMakeFiles/gdcc-cpp-lib.dir/all] Error 2
make: *** [all] Error 2
The time conversion functions, mktime
, gmtime
, and localtime
need to be implemented, even if their use would probably be extremely limited.
Rather than checking constraints and such over and over in every phase, these checks should be done in its own phase. This will make it easier to ensure the fullness of those checks and of course simplify the rest of the code. It will also be an opportunity to add a number of consistency checks that are currently missing after the arg size rewrite.
Having an expression equivalent to the assembly statement would be useful where data can be passed to/from the stack in the inline assembly. Syntax would be something like:
asm-expression:
<__asm> ( type , string-literal )
<__asm> ( type , string-literal , expression-list )
Would probably be good to use a different keyword, so as to avoid grammatical ambiguity with the assembly statement.
Current implementation can't represent special float values (NaN/infinity/subnormals), which is an unfortunate limitation. Will require replacing use of mpf_class for IR::Value_Float's value.
Being able to have a pointer type that crosses address spaces would be potentially useful in edge cases. Currently planning on doing a three-word solution. One word for type, one for the array/string number, and one for the index. Ideally, the index should be pushed last in order to simplify codegen. Overflowing the index will be considered UB.
One issue that stands is the inability to address module arrays, as their addresses are module-specific. A solution to that would be interesting, as it would open up a __mod_ars
address space to go with __hub_ars
and __gbl_ars
. At present, however, I can think of no general solution. Ideas would be appreciated.
Operations mixing fixed-point and integer types convert their operands to the promoted type before the operation. For addition and subtraction, this is fine, but multiplication and division with fract types is almost impossible. Therefore, conversion should happen after the operation for multiplication and division. This will make fract types much more useful as well as optimize accum-integer operations.
Given:
struct foo { int a; str b; }
If you want to return such a structure, you currently have to write:
function foo f(void) {
foo ret = { 42, "" };
return ret;
}
It would be ideal if you can just write:
function foo f(void) {
return { 42, "" };
}
Once fract ops are in, the Embedded C %R
/%r
fract formats should also be supported. Implementing the strtofxr
functions would be part of this.
This would allow use of the return statement in scripts which yield a value, as otherwise they internally have a return type of void. Should be grammatically unambiguous to simply insert immediately following the script
keyword as it is for functions.
A sixth, boolean argument was added to SetHudClipRect to control it's odd aspect ratio handling. Can you update GDCC to include that parameter, please?
There currently exists no syntax in the special
declaration to declare natives without a number. This is a problem for targets which reference natives by name in the bytecode, or if the number is otherwise provided externally. One syntactic solution is to make the special-address optional to declare line specials, use -
for natives, and {}
for assembly functions. As in:
special int LineSpecial(int, int);
special int -:Native(int);
special int {}:AssemblyFunction(int, int, int);
This is not a very refined syntax for natives and assembly functions, but such declarations only need to be so clean. New keywords could be introduced, but that is undesirable from a compatibility perspective. A sort of contextual keyword, where the integer-constant in special-address is replaced with an identifier is also possible, but would likely introduce undesired syntactic restraints later.
It really is time to replace all those global functions in Platform/Platform.hpp. Platform::Info should be a pared down analogue to Bytecode::Info, and the latter should probably be constructed with a pointer to the former.
Current method of doing member access involves literally doing pointer casts to manipulate pointer arithmetic operations internally. It also generates inefficient code for member-member and first-member access. All of this would probably be best served with a separate Exp class to handle the unusual nature of the operation, even if it would have some overlap with the currently appropriated classes.
Use of -I rather than -i is convention among major vendors, and there is no compelling reason for GDCC not to. Will need to be aliased for gdcc-acc, as acc does use -i.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.