---------------------------------------------------------------------------
Usage: cc65 [options] file
Short options:
- -A Strict ANSI mode
-Cl Make local variables static
-Dsym[=defn] Define a symbol
-I dir Set an include directory search path
Long options:
--add-source Include source as comment
- --ansi Strict ANSI mode
--bss-name seg Set the name of the BSS segment
--check-stack Generate stack overflow checks
--code-name seg Set the name of the CODE segment
--register-vars Enable register variables
--rodata-name seg Set the name of the RODATA segment
--signed-chars Default characters are signed
+ --standard std Language standard (c89, c99, cc65)
--static-locals Make local variables static
--target sys Set the target system
--verbose Increase verbosity
<descrip>
- <label id="option-A">
- <tag><tt>-A, --ansi</tt></tag>
-
- This option disables any compiler exensions. Have a look at section 5
- for a discussion of compiler extensions. In addition, the macro
- <tt/__STRICT_ANSI__/ is defined, when using one of these options.
-
-
<tag><tt>--bss-name seg</tt></tag>
Set the name of the bss segment.
signedchars"></tt> for better control of this option.
+ <label id="option--standard">
+ <tag><tt>--standard std</tt></tag>
+
+ This option allows to set the language standard supported. The argument is
+ one of
+ <itemize>
+ <item>c89
+ <item>c99
+ <item>cc65
+ </itemize>
+
+
<tag><tt>-t target, --target target</tt></tag>
This option is used to set the target system. The target system
<itemize>
<item>none
<item>apple2
+ <item>apple2enh
<item>atari
<item>atmos
<item>c16 (works also for the c116 with memory up to 32K)
<item>c64
<item>c128
- <item>plus4
<item>cbm510 (CBM-II series with 40 column video)
<item>cbm610 (all CBM-II II computers with 80 column video)
- <item>pet (all CBM PET systems except the 2001)
<item>geos
+ <item>lunix
+ <item>nes
+ <item>pet (all CBM PET systems except the 2001)
+ <item>plus4
+ <item>supervision
</itemize>
<tag><tt>-v, --verbose</tt></tag>
<itemize>
-<item> The compiler allows single line comments that start with //. This
- feature is disabled in strict ANSI mode.
- <p>
<item> The compiler allows unnamed parameters in parameter lists. The
compiler will not issue warnings about unused parameters that don't
- have a name. This feature is disabled in strict ANSI mode.
+ have a name. This feature can be disabled with the <tt><ref
+ id="option--standard" name="--standard"></tt> command line option.
<p>
<item> The compiler has some additional keywords:
<p>
<item><tt/__attribute__/
</itemize>
<p>
- The keywords without the underlines are disabled in strict ANSI mode.
+ The keywords without the underlines can be disabled with the
+ <tt><ref id="option--standard" name="--standard"></tt> command line
+ option.
<p>
<item> The datatypes "float" and "double" are not available.
<p>
conventions (see below). This means, that you may not mix pointers to
those functions with pointers to user written functions.
<p>
-</itemize>
+</itemize>
There may be some more minor differences, I'm currently not aware off. The
biggest problem is the missing float data type. With this limitation in
<itemize>
-<item> The compiler allows // comments (like in C++ and in the proposed C9x
- standard). This feature is disabled by <tt><ref id="option-A"
- name="-A"></tt>.
- <p>
-
<item> The compiler allows to insert assembler statements into the output
file. The syntax is
<tscreen><verb>
void __fastcall__ f (unsigned char c)
</verb></tscreen>
- The first form of the fastcall keyword is in the user namespace and is
- therefore disabled in strict ANSI mode.
+ The first form of the fastcall keyword is in the user namespace and can
+ therefore be disabled with the <tt><ref id="option--standard"
+ name="--standard"></tt> command line option.
For functions declared as <tt/fastcall/, the rightmost parameter is not
pushed on the stack but left in the primary register when the function
<p>
<item> cc65 implements flexible array struct members as defined in the C99 ISO
- standard. As an extension, in non ANSI mode, these fields may be
- initialized. There are several exceptions, however (which is probably
- the reason why the standard does not define this feature, because it is
- highly unorthogonal). Flexible array members cannot be initialized...
+ standard. As an extension, these fields may be initialized. There are
+ several exceptions, however (which is probably the reason why the
+ standard does not define this feature, because it is highly
+ unorthogonal). Flexible array members cannot be initialized...
<itemize>
<item> ...when defining an array of structs with flexible members.
This macro expands to the current line number.
- <tag><tt>__STRICT_ANSI__</tt></tag>
+ <tag><tt>__CC65_STD__</tt></tag>
- This macro is defined to 1 if the <tt/-A/ compiler option was given, and
- undefined otherwise.
+ This macro is defined to one of the following depending on the <tt><ref
+ id="option--standard" name="--standard"></tt> command line option:
+ <itemize>
+ <item><tt/__CC65_STD_C89__/
+ <item><tt/__CC65_STD_C99__/
+ <item><tt/__CC65_STD_CCC65__/
+ </itemize>
<tag><tt>__OPT__</tt></tag>
<p>
The first form is in the user namespace and is disabled by <tt><ref
-id="option-A" name="-A"></tt>.
+id="option--standard" name="--standard"></tt> if the argument is not <tt/cc65/.
The asm statement may be used inside a function and on global file level. An
inline assembler statement is a primary expression, so it may also be used as
--------------------------------------------------------------------------
</verb></tscreen>
-In acknowledgment of this copyright, I will place my own changes to the
-compiler under the same copyright. Please note however, that the library
-and all binutils are covered by another copyright, and that I'm planning
-to do a complete rewrite of the compiler, after which the compiler
-copyright will also change.
-
-For the list of changes requested by this copyright see newvers.txt.
-
+Small parts of the compiler (parts of the preprocessor and main parser) are
+still covered by this copyright. The main portion is covered by the usual
+cc65 license, which reads:
+
+This software is provided 'as-is', without any expressed or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+<enum>
+<item> The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+<item> Altered source versions must be plainly marked as such, and must not
+ be misrepresented as being the original software.
+<item> This notice may not be removed or altered from any source
+ distribution.
+</enum>
</article>
-t sys Set the target system
-v Verbose mode
-vm Verbose map file
- -A Strict ANSI mode
-C name Use linker config file
-Cl Make local variables static
-D sym[=defn] Define a preprocessor symbol
Long options:
--add-source Include source as comment
- --ansi Strict ANSI mode
--asm-include-dir dir Set an assembler include directory
--bss-label name Define and export a BSS segment label
--bss-name seg Set the name of the BSS segment
--register-vars Enable register variables
--rodata-name seg Set the name of the RODATA segment
--signed-chars Default characters are signed
+ --standard std Language standard (c89, c99, cc65)
--start-addr addr Set the default start address
--static-locals Make local variables static
--target sys Set the target system
<sect>Copyright<p>
-cl65 (and all cc65 binutils) are (C) Copyright 1998-2000 Ullrich von
+cl65 (and all cc65 binutils) are (C) Copyright 1998-2004 Ullrich von
Bassewitz. For usage of the binaries and/or sources the following
conditions do apply:
/* */
/* */
/* */
-/* (C) 1998-2000 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 1998-2004 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
int __fastcall__ isspace (int c);
int __fastcall__ isupper (int c);
int __fastcall__ isxdigit (int c);
+#if __CC65_STD__ >= __CC65_STD_C99__
int __fastcall__ isblank (int c); /* New in C99 */
+#endif
-int __fastcall__ toupper (int c); /* Always external */
-int __fastcall__ tolower (int c); /* Always external */
+int __fastcall__ toupper (int c); /* Always external */
+int __fastcall__ tolower (int c); /* Always external */
#define isalnum(c) (__AX__ = (c), \
__asm__ ("tay"), \
- __asm__ ("lda %v,y", _ctype), \
- __asm__ ("and #%b", _CT_ALNUM), \
+ __asm__ ("lda %v,y", _ctype), \
+ __asm__ ("and #%b", _CT_ALNUM), \
__AX__)
#define isalpha(c) (__AX__ = (c), \
__asm__ ("tay"), \
- __asm__ ("lda %v,y", _ctype), \
- __asm__ ("and #%b", _CT_ALPHA), \
+ __asm__ ("lda %v,y", _ctype), \
+ __asm__ ("and #%b", _CT_ALPHA), \
__AX__)
+#if __CC65_STD__ >= __CC65_STD_C99__
#define isblank(c) (__AX__ = (c), \
__asm__ ("tay"), \
- __asm__ ("lda %v,y", _ctype), \
- __asm__ ("and #%b", _CT_SPACE_TAB), \
+ __asm__ ("lda %v,y", _ctype), \
+ __asm__ ("and #%b", _CT_SPACE_TAB), \
__AX__)
+#endif
#define iscntrl(c) (__AX__ = (c), \
__asm__ ("tay"), \
- __asm__ ("lda %v,y", _ctype), \
- __asm__ ("and #%b", _CT_CNTRL), \
+ __asm__ ("lda %v,y", _ctype), \
+ __asm__ ("and #%b", _CT_CNTRL), \
__AX__)
#define isdigit(c) (__AX__ = (c), \
__asm__ ("tay"), \
- __asm__ ("lda %v,y", _ctype), \
- __asm__ ("and #%b", _CT_DIGIT), \
+ __asm__ ("lda %v,y", _ctype), \
+ __asm__ ("and #%b", _CT_DIGIT), \
__AX__)
#define isgraph(c) (__AX__ = (c), \
int __fastcall__ vsscanf (const char* s, const char* format, va_list ap);
int __fastcall__ vfscanf (FILE* f, const char* format, va_list ap);
-#ifndef __STRICT_ANSI__
+#if __CC65_STD__ == __CC65_STD_CC65__
FILE* __fastcall__ fdopen (int fd, const char* mode); /* Unix */
int __fastcall__ fileno (FILE* f); /* Unix */
#endif
#define putc(c, f) fputc (c, f) /* ANSI */
/* Non-standard function like macros */
-#ifndef __STRICT_ANSI__
+#if __CC65_STD__ == __CC65_STD_CC65__
#define flushall() /* Unix */
#endif
-
/* */
/* */
/* */
-/* (C) 1998-2003 Ullrich von Bassewitz */
+/* (C) 1998-2004 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* Non-ANSI functions */
void __fastcall__ _swap (void* p, void* q, size_t size);
-#ifndef __STRICT_ANSI__
+#if __CC65_STD__ == __CC65_STD_CC65__
char* __fastcall__ itoa (int val, char* buf, int radix);
char* __fastcall__ utoa (unsigned val, char* buf, int radix);
char* __fastcall__ ltoa (long val, char* buf, int radix);
/* */
/* */
/* */
-/* (C) 1998-2000 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 1998-2004 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
void* __fastcall__ _bzero (void* ptr, size_t n);
/* Non standard: */
-#ifndef __STRICT_ANSI__
+#if __CC65_STD__ == __CC65_STD_CC65__
void __fastcall__ bzero (void* ptr, size_t n); /* BSD */
char* __fastcall__ strdup (const char* s); /* SYSV/BSD */
int __fastcall__ stricmp (const char* s1, const char* s2); /* DOS/Windows */
#include "asmlabel.h"
#include "asmstmt.h"
#include "codegen.h"
+#include "compile.h"
#include "declare.h"
#include "error.h"
#include "expr.h"
#include "litpool.h"
#include "macrotab.h"
#include "pragma.h"
+#include "standard.h"
#include "symtab.h"
-#include "compile.h"
/* Add macros that are always defined */
DefineNumericMacro ("__CC65__", VERSION);
- /* Strict ANSI macro */
- if (ANSI) {
- DefineNumericMacro ("__STRICT_ANSI__", 1);
- }
+ /* Language standard that is supported */
+ DefineNumericMacro ("__CC65_STD_C89__", STD_C89);
+ DefineNumericMacro ("__CC65_STD_C99__", STD_C99);
+ DefineNumericMacro ("__CC65_STD_CC65__", STD_CC65);
+ DefineNumericMacro ("__CC65_STD__", IS_Get (&Standard));
/* Optimization macros. Since no source code has been parsed for now, the
* IS_Get functions access the values in effect now, regardless of any
* changes using #pragma later.
*/
- if (IS_Get (&Optimize)) {
+ if (IS_Get (&Optimize)) {
long CodeSize = IS_Get (&CodeSizeFactor);
DefineNumericMacro ("__OPT__", 1);
if (CodeSize > 100) {
#include "litpool.h"
#include "pragma.h"
#include "scanner.h"
+#include "standard.h"
#include "symtab.h"
#include "typeconv.h"
/* Check if this is a function definition */
if (CurTok.Tok == TOK_LCURLY) {
- /* Print an error if in strict ANSI mode and we have unnamed
- * parameters.
+ /* Print an error if we have unnamed parameters and cc65 extensions
+ * are disabled.
*/
- if (ANSI && (F->Flags & FD_UNNAMED_PARAMS) != 0) {
+ if (IS_Get (&Standard) != STD_CC65 &&
+ (F->Flags & FD_UNNAMED_PARAMS) != 0) {
Error ("Parameter name omitted");
}
}
return ParseStructInit (T, AllowFlexibleMembers);
case T_VOID:
- if (!ANSI) {
+ if (IS_Get (&Standard) == STD_CC65) {
/* Special cc65 extension in non ANSI mode */
return ParseVoidInit ();
}
unsigned ParseInit (type* T)
/* Parse initialization of variables. Return the number of data bytes. */
{
- /* Parse the initialization */
- unsigned Size = ParseInitInternal (T, !ANSI);
+ /* Parse the initialization. Flexible array members can only be initialized
+ * in cc65 mode.
+ */
+ unsigned Size = ParseInitInternal (T, IS_Get (&Standard) == STD_CC65);
/* The initialization may not generate code on global level, because code
* outside function scope will never get executed.
+/* Options */
extern unsigned char AddSource; /* Add source lines as comments */
extern unsigned char DebugInfo; /* Add debug info to the obj */
extern unsigned char CreateDep; /* Create a dependency file */
#include "input.h"
#include "macrotab.h"
#include "scanner.h"
+#include "standard.h"
#include "segments.h"
fprintf (stderr,
"Usage: %s [options] file\n"
"Short options:\n"
- " -A\t\t\tStrict ANSI mode\n"
" -Cl\t\t\tMake local variables static\n"
" -Dsym[=defn]\t\tDefine a symbol\n"
" -I dir\t\tSet an include directory search path\n"
"\n"
"Long options:\n"
" --add-source\t\tInclude source as comment\n"
- " --ansi\t\tStrict ANSI mode\n"
" --bss-name seg\tSet the name of the BSS segment\n"
" --check-stack\t\tGenerate stack overflow checks\n"
" --code-name seg\tSet the name of the CODE segment\n"
" --register-vars\tEnable register variables\n"
" --rodata-name seg\tSet the name of the RODATA segment\n"
" --signed-chars\tDefault characters are signed\n"
+ " --standard std\tLanguage standard (c89, c99, cc65)\n"
" --static-locals\tMake local variables static\n"
" --target sys\t\tSet the target system\n"
" --verbose\t\tIncrease verbosity\n"
-static void OptAnsi (const char* Opt attribute ((unused)),
- const char* Arg attribute ((unused)))
-/* Compile in strict ANSI mode */
-{
- ANSI = 1;
-}
-
-
-
static void OptBssName (const char* Opt attribute ((unused)), const char* Arg)
/* Handle the --bss-name option */
{
+static void OptStandard (const char* Opt, const char* Arg)
+/* Handle the --standard option */
+{
+ /* Find the standard from the given name */
+ standard_t Std = FindStandard (Arg);
+ if (Std == STD_UNKNOWN) {
+ AbEnd ("Invalid argument for %s: `%s'", Opt, Arg);
+ } else if (IS_Get (&Standard) != STD_UNKNOWN) {
+ AbEnd ("Option %s given more than once", Opt);
+ } else {
+ IS_Set (&Standard, Std);
+ }
+}
+
+
+
static void OptStaticLocals (const char* Opt attribute ((unused)),
const char* Arg attribute ((unused)))
/* Place local variables in static storage */
/* Program long options */
static const LongOpt OptTab[] = {
{ "--add-source", 0, OptAddSource },
- { "--ansi", 0, OptAnsi },
{ "--bss-name", 1, OptBssName },
{ "--check-stack", 0, OptCheckStack },
{ "--code-name", 1, OptCodeName },
{ "--register-vars", 0, OptRegisterVars },
{ "--rodata-name", 1, OptRodataName },
{ "--signed-chars", 0, OptSignedChars },
+ { "--standard", 1, OptStandard },
{ "--static-locals", 0, OptStaticLocals },
{ "--target", 1, OptTarget },
{ "--verbose", 0, OptVerbose },
OptVerbose (Arg, 0);
break;
- case 'A':
- OptAnsi (Arg, 0);
- break;
-
case 'C':
P = Arg + 2;
while (*P) {
SetMemoryModel (MMODEL_NEAR);
}
+ /* If no language standard was given, use the default one */
+ if (IS_Get (&Standard) == STD_UNKNOWN) {
+ IS_Set (&Standard, STD_DEFAULT);
+ }
+
/* Go! */
Compile (InputFile);
scanstrbuf.o \
segments.o \
stackptr.o \
+ standard.o \
stdfunc.o \
stdnames.o \
stmt.o \
scanstrbuf.obj \
segments.obj \
stackptr.obj \
+ standard.obj \
stdfunc.obj \
stdnames.obj \
stmt.obj \
#include "input.h"
#include "lineinfo.h"
#include "macrotab.h"
+#include "preproc.h"
#include "scanner.h"
+#include "standard.h"
#include "util.h"
-#include "preproc.h"
} else if (CurC == '/' && NextC == '*') {
*B++ = ' ';
OldStyleComment ();
- } else if (ANSI == 0 && CurC == '/' && NextC == '/') {
+ } else if (IS_Get (&Standard) >= STD_C99 && CurC == '/' && NextC == '/') {
*B++ = ' ';
NewStyleComment ();
} else if (CurC == '\0') {
} else if (CurC == '/' && NextC == '*') {
KeepChar (' ');
OldStyleComment ();
- } else if (ANSI == 0 && CurC == '/' && NextC == '/') {
+ } else if (IS_Get (&Standard) >= STD_C99 && CurC == '/' && NextC == '/') {
KeepChar (' ');
NewStyleComment ();
} else {
static int DoIf (int Skip)
/* Process #if directive */
-{
+{
ExprDesc Expr;
char* S;
break;
case PP_LINE:
- /* Not allowed in strict ANSI mode */
- if (!Skip && ANSI) {
- PPError ("Preprocessor directive expected");
+ /* Should do something in C99 at least, but we ignore it */
+ if (!Skip) {
ClearLine ();
}
break;
/* */
/* */
/* */
-/* (C) 1998-2003 Ullrich von Bassewitz */
+/* (C) 1998-2004 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
#include "input.h"
#include "litpool.h"
#include "preproc.h"
+#include "scanner.h"
+#include "standard.h"
#include "symtab.h"
#include "util.h"
-#include "scanner.h"
/* Token types */
-#define TT_C 0 /* ANSI C token */
-#define TT_EXT 1 /* cc65 extension */
+enum {
+ TT_C89 = 0x01 << STD_C89, /* Token valid in C89 */
+ TT_C99 = 0x01 << STD_C99, /* Token valid in C99 */
+ TT_CC65 = 0x01 << STD_CC65 /* Token valid in cc65 */
+};
/* Token table */
static const struct Keyword {
char* Key; /* Keyword name */
unsigned char Tok; /* The token */
- unsigned char Type; /* Token type */
+ unsigned char Std; /* Token supported in which standards? */
} Keywords [] = {
- { "_Pragma", TOK_PRAGMA, TT_C },
- { "__AX__", TOK_AX, TT_C },
- { "__A__", TOK_A, TT_C },
- { "__EAX__", TOK_EAX, TT_C },
- { "__X__", TOK_X, TT_C },
- { "__Y__", TOK_Y, TT_C },
- { "__asm__", TOK_ASM, TT_C },
- { "__attribute__", TOK_ATTRIBUTE, TT_C },
- { "__far__", TOK_FAR, TT_C },
- { "__fastcall__", TOK_FASTCALL, TT_C },
- { "__near__", TOK_NEAR, TT_C },
- { "asm", TOK_ASM, TT_EXT },
- { "auto", TOK_AUTO, TT_C },
- { "break", TOK_BREAK, TT_C },
- { "case", TOK_CASE, TT_C },
- { "char", TOK_CHAR, TT_C },
- { "const", TOK_CONST, TT_C },
- { "continue", TOK_CONTINUE, TT_C },
- { "default", TOK_DEFAULT, TT_C },
- { "do", TOK_DO, TT_C },
- { "double", TOK_DOUBLE, TT_C },
- { "else", TOK_ELSE, TT_C },
- { "enum", TOK_ENUM, TT_C },
- { "extern", TOK_EXTERN, TT_C },
- { "far", TOK_FAR, TT_EXT },
- { "fastcall", TOK_FASTCALL, TT_EXT },
- { "float", TOK_FLOAT, TT_C },
- { "for", TOK_FOR, TT_C },
- { "goto", TOK_GOTO, TT_C },
- { "if", TOK_IF, TT_C },
- { "int", TOK_INT, TT_C },
- { "long", TOK_LONG, TT_C },
- { "near", TOK_NEAR, TT_EXT },
- { "register", TOK_REGISTER, TT_C },
- { "restrict", TOK_RESTRICT, TT_C },
- { "return", TOK_RETURN, TT_C },
- { "short", TOK_SHORT, TT_C },
- { "signed", TOK_SIGNED, TT_C },
- { "sizeof", TOK_SIZEOF, TT_C },
- { "static", TOK_STATIC, TT_C },
- { "struct", TOK_STRUCT, TT_C },
- { "switch", TOK_SWITCH, TT_C },
- { "typedef", TOK_TYPEDEF, TT_C },
- { "union", TOK_UNION, TT_C },
- { "unsigned", TOK_UNSIGNED, TT_C },
- { "void", TOK_VOID, TT_C },
- { "volatile", TOK_VOLATILE, TT_C },
- { "while", TOK_WHILE, TT_C },
+ { "_Pragma", TOK_PRAGMA, TT_C99 | TT_CC65 },
+ { "__AX__", TOK_AX, TT_C89 | TT_C99 | TT_CC65 },
+ { "__A__", TOK_A, TT_C89 | TT_C99 | TT_CC65 },
+ { "__EAX__", TOK_EAX, TT_C89 | TT_C99 | TT_CC65 },
+ { "__X__", TOK_X, TT_C89 | TT_C99 | TT_CC65 },
+ { "__Y__", TOK_Y, TT_C89 | TT_C99 | TT_CC65 },
+ { "__asm__", TOK_ASM, TT_C89 | TT_C99 | TT_CC65 },
+ { "__attribute__", TOK_ATTRIBUTE, TT_C89 | TT_C99 | TT_CC65 },
+ { "__far__", TOK_FAR, TT_C89 | TT_C99 | TT_CC65 },
+ { "__fastcall__", TOK_FASTCALL, TT_C89 | TT_C99 | TT_CC65 },
+ { "__near__", TOK_NEAR, TT_C89 | TT_C99 | TT_CC65 },
+ { "asm", TOK_ASM, TT_CC65 },
+ { "auto", TOK_AUTO, TT_C89 | TT_C99 | TT_CC65 },
+ { "break", TOK_BREAK, TT_C89 | TT_C99 | TT_CC65 },
+ { "case", TOK_CASE, TT_C89 | TT_C99 | TT_CC65 },
+ { "char", TOK_CHAR, TT_C89 | TT_C99 | TT_CC65 },
+ { "const", TOK_CONST, TT_C89 | TT_C99 | TT_CC65 },
+ { "continue", TOK_CONTINUE, TT_C89 | TT_C99 | TT_CC65 },
+ { "default", TOK_DEFAULT, TT_C89 | TT_C99 | TT_CC65 },
+ { "do", TOK_DO, TT_C89 | TT_C99 | TT_CC65 },
+ { "double", TOK_DOUBLE, TT_C89 | TT_C99 | TT_CC65 },
+ { "else", TOK_ELSE, TT_C89 | TT_C99 | TT_CC65 },
+ { "enum", TOK_ENUM, TT_C89 | TT_C99 | TT_CC65 },
+ { "extern", TOK_EXTERN, TT_C89 | TT_C99 | TT_CC65 },
+ { "far", TOK_FAR, TT_CC65 },
+ { "fastcall", TOK_FASTCALL, TT_CC65 },
+ { "float", TOK_FLOAT, TT_C89 | TT_C99 | TT_CC65 },
+ { "for", TOK_FOR, TT_C89 | TT_C99 | TT_CC65 },
+ { "goto", TOK_GOTO, TT_C89 | TT_C99 | TT_CC65 },
+ { "if", TOK_IF, TT_C89 | TT_C99 | TT_CC65 },
+ { "int", TOK_INT, TT_C89 | TT_C99 | TT_CC65 },
+ { "long", TOK_LONG, TT_C89 | TT_C99 | TT_CC65 },
+ { "near", TOK_NEAR, TT_CC65 },
+ { "register", TOK_REGISTER, TT_C89 | TT_C99 | TT_CC65 },
+ { "restrict", TOK_RESTRICT, TT_C99 | TT_CC65 },
+ { "return", TOK_RETURN, TT_C89 | TT_C99 | TT_CC65 },
+ { "short", TOK_SHORT, TT_C89 | TT_C99 | TT_CC65 },
+ { "signed", TOK_SIGNED, TT_C89 | TT_C99 | TT_CC65 },
+ { "sizeof", TOK_SIZEOF, TT_C89 | TT_C99 | TT_CC65 },
+ { "static", TOK_STATIC, TT_C89 | TT_C99 | TT_CC65 },
+ { "struct", TOK_STRUCT, TT_C89 | TT_C99 | TT_CC65 },
+ { "switch", TOK_SWITCH, TT_C89 | TT_C99 | TT_CC65 },
+ { "typedef", TOK_TYPEDEF, TT_C89 | TT_C99 | TT_CC65 },
+ { "union", TOK_UNION, TT_C89 | TT_C99 | TT_CC65 },
+ { "unsigned", TOK_UNSIGNED, TT_C89 | TT_C99 | TT_CC65 },
+ { "void", TOK_VOID, TT_C89 | TT_C99 | TT_CC65 },
+ { "volatile", TOK_VOLATILE, TT_C89 | TT_C99 | TT_CC65 },
+ { "while", TOK_WHILE, TT_C89 | TT_C99 | TT_CC65 },
};
#define KEY_COUNT (sizeof (Keywords) / sizeof (Keywords [0]))
/*****************************************************************************/
-/* code */
+/* code */
/*****************************************************************************/
-static int FindKey (const char* Key)
+static token_t FindKey (const char* Key)
/* Find a keyword and return the token. Return IDENT if the token is not a
* keyword.
*/
{
struct Keyword* K;
K = bsearch (Key, Keywords, KEY_COUNT, sizeof (Keywords [0]), CmpKey);
- if (K && (K->Type != TT_EXT || ANSI == 0)) {
+ if (K && (K->Std & (0x01 << IS_Get (&Standard))) != 0) {
return K->Tok;
} else {
return TOK_IDENT;
C = '\b';
break;
case 'f':
- C = '\f';
+ C = '\f';
break;
case 'r':
C = '\r';
}
break;
default:
- Error ("Illegal character constant");
+ Error ("Illegal character constant");
C = ' ';
/* Try to do error recovery, otherwise the compiler will spit
* out thousands of errors in this place and abort.
SB_Terminate (&S);
/* The following character tells us if we have an integer or floating
- * point constant.
+ * point constant. Note: Hexadecimal floating point constants aren't
+ * supported in C89.
*/
IsFloat = (CurC == '.' ||
(Base == 10 && toupper (CurC) == 'E') ||
- (Base == 16 && toupper (CurC) == 'P'));
+ (Base == 16 && toupper (CurC) == 'P' && IS_Get (&Standard) >= STD_C99));
/* If we don't have a floating point type, an octal prefix results in an
* octal base.
return;
}
/* No reserved word, check for special symbols */
- if (token [0] == '_') {
+ if (token[0] == '_' && token[1] == '_') {
/* Special symbols */
- if (strcmp (token, "__FILE__") == 0) {
+ if (strcmp (token+2, "FILE__") == 0) {
NextTok.IVal = AddLiteral (GetCurrentFile());
NextTok.Tok = TOK_SCONST;
return;
- } else if (strcmp (token, "__LINE__") == 0) {
+ } else if (strcmp (token+2, "LINE__") == 0) {
NextTok.Tok = TOK_ICONST;
NextTok.IVal = GetCurrentLine();
NextTok.Type = type_int;
return;
- } else if (strcmp (token, "__func__") == 0) {
+ } else if (strcmp (token+2, "func__") == 0) {
/* __func__ is only defined in functions */
if (CurrentFunc) {
NextTok.IVal = AddLiteral (F_GetFuncName (CurrentFunc));
--- /dev/null
+/*****************************************************************************/
+/* */
+/* standard.c */
+/* */
+/* Language standard definitions */
+/* */
+/* */
+/* */
+/* (C) 2004 Ullrich von Bassewitz */
+/* Römerstraße 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+#include <string.h>
+
+/* cc65 */
+#include "standard.h"
+
+
+
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+/* Current language standard, will be set to STD_DEFAULT on startup */
+IntStack Standard = INTSTACK(STD_UNKNOWN);
+
+/* Table mapping names to standards, sorted by standard. */
+static const char* StdNames[STD_COUNT] = {
+ "c89", "c99", "cc65"
+};
+
+
+
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
+
+
+standard_t FindStandard (const char* Name)
+/* Find a standard by name. Returns one of the constants defined above.
+ * STD_UNKNOWN is returned if Name doesn't match a standard.
+ */
+{
+ unsigned I;
+
+ /* Check for a standard string */
+ for (I = 0; I < STD_COUNT; ++I) {
+ if (strcmp (StdNames [I], Name) == 0) {
+ return (standard_t)I;
+ }
+ }
+
+ /* Not found */
+ return STD_UNKNOWN;
+}
+
+
+
--- /dev/null
+/*****************************************************************************/
+/* */
+/* standard.h */
+/* */
+/* Language standard definitions */
+/* */
+/* */
+/* */
+/* (C) 2004 Ullrich von Bassewitz */
+/* Römerstraße 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+#ifndef STANDARD_H
+#define STANDARD_H
+
+
+
+/* common */
+#include "intstack.h"
+
+
+
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+/* Supported standards. */
+typedef enum standard_t {
+ STD_UNKNOWN = -1,
+ STD_C89,
+ STD_C99,
+ STD_CC65,
+
+ /* Special constants */
+ STD_COUNT, /* Number of supported standards */
+ STD_DEFAULT = STD_CC65 /* Default standard if none given */
+} standard_t;
+
+/* Current language standard */
+extern IntStack Standard; /* Language standard */
+
+
+
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
+
+
+standard_t FindStandard (const char* Name);
+/* Find a standard by name. Returns one of the constants defined above.
+ * STD_UNKNOWN is returned if Name doesn't match a standard.
+ */
+
+
+
+/* End of standard.h */
+
+#endif
+
+
+
+
" -t sys\t\tSet the target system\n"
" -v\t\t\tVerbose mode\n"
" -vm\t\t\tVerbose map file\n"
- " -A\t\t\tStrict ANSI mode\n"
" -C name\t\tUse linker config file\n"
" -Cl\t\t\tMake local variables static\n"
" -D sym[=defn]\t\tDefine a preprocessor symbol\n"
"\n"
"Long options:\n"
" --add-source\t\tInclude source as comment\n"
- " --ansi\t\tStrict ANSI mode\n"
" --asm-define sym[=v]\tDefine an assembler symbol\n"
" --asm-include-dir dir\tSet an assembler include directory\n"
" --bss-label name\tDefine and export a BSS segment label\n"
" --register-vars\tEnable register variables\n"
" --rodata-name seg\tSet the name of the RODATA segment\n"
" --signed-chars\tDefault characters are signed\n"
+ " --standard std\tLanguage standard (c89, c99, cc65)\n"
" --start-addr addr\tSet the default start address\n"
" --static-locals\tMake local variables static\n"
" --target sys\t\tSet the target system\n"
-static void OptAnsi (const char* Opt attribute ((unused)),
- const char* Arg attribute ((unused)))
-/* Strict ANSI mode (compiler) */
-{
- CmdAddArg (&CC65, "-A");
-}
-
-
-
static void OptAsmDefine (const char* Opt attribute ((unused)), const char* Arg)
/* Define an assembler symbol (assembler) */
{
+static void OptStandard (const char* Opt attribute ((unused)), const char* Arg)
+/* Set the language standard */
+{
+ CmdAddArg2 (&CC65, "--standard", Arg);
+}
+
+
+
static void OptStartAddr (const char* Opt attribute ((unused)), const char* Arg)
/* Set the default start address */
{
/* Program long options */
static const LongOpt OptTab[] = {
{ "--add-source", 0, OptAddSource },
- { "--ansi", 0, OptAnsi },
{ "--asm-define", 1, OptAsmDefine },
{ "--asm-include-dir", 1, OptAsmIncludeDir },
{ "--bss-label", 1, OptBssLabel },
{ "--register-vars", 0, OptRegisterVars },
{ "--rodata-name", 1, OptRodataName },
{ "--signed-chars", 0, OptSignedChars },
+ { "--standard", 1, OptStandard },
{ "--start-addr", 1, OptStartAddr },
{ "--static-locals", 0, OptStaticLocals },
{ "--target", 1, OptTarget },
LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0]));
break;
- case 'A':
- /* Strict ANSI mode (compiler) */
- OptAnsi (Arg, 0);
- break;
-
case 'C':
if (Arg[2] == 'l' && Arg[3] == '\0') {
/* Make local variables static */