scc

Simple C99 Compiler
Log | Files | Refs | README | LICENSE

commit 2d77075828c480d5cb0ad3ddb40199ccbbcc27b1
parent bd9c825b331e7f138ed8d7ba1b4878d2b09b8f74
Author: FRIGN <dev@frign.de>
Date:   Sat, 18 Jul 2015 23:40:28 +0200

Some grammar and spelling fixes in README

Diffstat:
README | 119++++++++++++++++++++++++++++++++++++++++---------------------------------------
1 file changed, 60 insertions(+), 59 deletions(-)

diff --git a/README b/README @@ -1,91 +1,92 @@ Introduction ============ -This is the kcc compiler, a one very stupid non retargetable compiler -for z80. This compiler is intended to be very simple and suitable for -running in small machines (like MSX for example), and let almost part -of optimizations to the programmer. - -After a lot of years seeing compilers for z80 I notice that it is very -hard for a C compiler generates a good code for a 8 bit processor like -z80, with an expensive indirect addressing mode, so the best solution -is to not try that compiler optimize the code and use C as a macro +This is the suckless C compiler, a very stupid non-retargetable compiler +for the Z80. It is intended to be very simple and suitable for running on +small machines (like MSX for example), and leaves almost all optimizations +to the programmer. + +After a lot of years seeing compilers for the Z80 I noticed that it is very +hard for a C compiler to generate good programs for 8 Bit processors like +the Z80, with an expensive indirect addressing mode, so the best solution +is not to try to make the compiler optimizing, but instead use C as a macro macro assembler. -In order to get this target, we need a compiler that does exactly the -things programmer want to do. For example is a variable is register it MUST be -register and fails in other case. If a variable is automatic try to -realize operations directly with the stack (for example use ADD -A,(IX+4), instead of allocate the variable into register add and store -again in memory). So if you declare an automatic variable you are a -big bullshit or you need it for recursion (static variables are your -friends). +In order to reach this target, we need a compiler that does exactly the +things the programmer wants to do. For example, if a variable is a register +it MUST be a register and should fail in any other case. +If a variable is automatic operations should be attempted to be realized +with the stack directly (for example use ADD A,(IX+4) instead of +allocating the variable into a register add and store it again in memory). +If you declare an automatic variable you are either doing it wrong or you +need it for recursion (static variables are you friends). This is the reason why I began to develop this compiler, and I hope it will be useful for you. -Changes from standard C -======================= -This compiler is near of being full compatible with C99 standard, but -it has some differences: +Derivations from standard C +=========================== +This compiler is near to being fully compatible with the C99 standard, but +there are some differences: - Type qualifiers are accepted but ignored. ----------------------------------------- -Type qualifers make the type system ugly, and the useless of them -add innecessary complexity to the compiler (with a bigger compilation -time): +Type qualifers make the type system ugly, and their uselessness add +unnecessary complexity to the compiler (and increased compilation time): - const: The definition of const is not clear in the standard. - If a const value is modified then the behaviour is implementation - defined. It seems that it was defined more in order to can - allocate variables in ROM than for the error detection. This + If a const value is modified the behaviour is implementation + defined. It seems it was defined in order to be able to + allocate variables in ROM rather than error detection. This implememtation will not warn about these modifications and - the code will use them as normal variables (standard specifies - that a diagnosis message must be printed). + the compiler will treat them like normal variables (the standard + specifies that a diagnosic message must be printed). - volatile: The definition of volatile is not concrete, because - it is defined as 'remove all the optimizations about the - variable', which of course depend of the kind of optimizations + it is defined as 'remove all optimizations applied to the + variable', which of course depends on the kind of optimizations applied to the variable. This qualifier was added to the standard - to can deal with longjmp (local variables that are not volatile - have undefined state), and for memory mapped registers or variables - whose value is modified asynchronous but this can achieved with - special pragma values. - In the first case, this is a a non portable code by definition - (depend of the register mapped), so it is better to deal with - it using another solution (compiler extensions or directly - assembler), and in the second case it generated a lot of - problems with moderm processors out of order and multiprocesor, - where not hold the value in a register is good enough (it is - needed a explicit memory barrier). - - - restrict: This qualifer can be only applied to pointers, to + to be able to deal with longjmp (local variables that are not + volatile have undefined state) and for memory mapped registers + or variables whose values are modified asynchronously. This can + be achieved with special pragma values though. + In the first case, this is non-portable code by definition + (depending on the register mapped), so it is better to deal with + it using another solution (compiler extensions or direct + assembler). + In the second case, it generates a lot of problems with modern + processors and multithreading, where not holding the value in a + register is good enough (an explicit memory barrier is needed). + + - restrict: This qualifer can only be applied to pointers to mark that the pointed object has no other alias. This qualifer - was introduced to can fix some performance problems in numerical - algorithm, where FORTRAN can achieve a better performance (and - in fact even with this specifier FORTRAN has a better performance - in this field). Ignores it doesn't make the code non standard - and in almost of the applications the performance will be the same. + was introduced to be able to fix some performance problems in + numerical algorithms, where FORTRAN could achieve a better + performance (and in fact even with this specifier FORTRAN has a + better performance in this field). Ignoring it doesn't make the + code non-standard and in almost all applications the performance + will be the same. - Function type names ------------------- -C99 allows to define type names of function types and write something like: +C99 allows you to define type names of function types and write something +like: int f(int (int)); Accepting function types in typenames (or abstract declarators) makes the -grammar ambiguous because it is impossible difference between: +grammar ambiguous because it is impossible to differentiate between: (int (f)) -> function returning int with one parameter of type f (int (f)) -> integer variable f Function type names are stupid, because they are used as an alias -of the function pointer types, but it makes stupid that something -like sizeof(int (int)) is not allowed (because here should be -understood as the size of a function), but it is allowed f(int (int)) -because it is understood as a parameter with function pointer type. - -This complexity is not needed at all, because function pointers fix -all these problems without this complexity (and they are the more usual -way of writing such codes). +of the function pointer types, but it is stupid that something +like sizeof(int (int)) is not allowed (because here it should be +understood as the size of a function), but is f(int (int)) is allowed +because it is understood as a parameter of function pointer type. + +This complexity is not needed at all as function pointers fix all these +problems without this complexity (and they are the more usual +way of writing such code).