# endif /* !true */
# define false (0)
# define true (1)
-# define bool _Bool
-# if __STDC_VERSION__ < 199901L && __GNUC__ < 3
- typedef int _Bool
-# endif
-# endif /* !__cplusplus */
+# ifdef __STDC_VERSION__
+# if __STDC_VERSION__ < 199901L && __GNUC__ < 3
+ typedef int bool;
+# else
+ typedef _Bool bool;
+# endif
+# else
+ typedef int bool;
+# endif /* !__STDC_VERSION__ */
+#endif /* !__cplusplus */
/*
* Of some functions which are generated we want to make sure
* like gcc and clang might have an inline attribute we can
* use if present.
*/
-#if __STDC_VERSION__ < 199901L
-# if defined(__GNUC__) || defined (__CLANG__)
-# if __GNUC__ < 2
-# define GMQCC_INLINE
+#ifdef __STDC_VERSION__
+# if __STDC_VERSION__ < 199901L
+# if defined(__GNUC__) || defined (__CLANG__)
+# if __GNUC__ < 2
+# define GMQCC_INLINE
+# else
+# define GMQCC_INLINE __attribute__ ((always_inline))
+# endif
# else
-# define GMQCC_INLINE __attribute__ ((always_inline))
+# define GMQCC_INLINE
# endif
-# else
-# define GMQCC_INLINE
-# endif
+# else
+# define GMQCC_INLINE inline
+# endif
+#else
+# define GMQCC_INLINE
+#endif /* !__STDC_VERSION__ */
+
+/*
+ * noreturn is present in GCC and clang
+ * it's required for _ast_node_destory otherwise -Wmissing-noreturn
+ * in clang complains about there being no return since abort() is
+ * called.
+ */
+#if (defined(__GNUC__) && __GNUC__ >= 2) || defined(__CLANG__)
+# define GMQCC_NORETURN __attribute__ ((noreturn))
#else
-# define GMQCC_INLINE inline
+# define GMQCC_NORETURN
#endif
/*
* fail. There is no valid way to get a 64bit type at this point
* without making assumptions of too many things.
*/
- typedef char int64_t;
- typedef char uint64_t;
+ typedef struct { char _fail : 0; } int64_t;
+ typedef struct { char _fail : 0; } uint64_t;
# endif
#endif
#ifdef _LP64 /* long pointer == 64 */
#endif
/* Ensure type sizes are correct: */
typedef char uint8_size_is_correct [sizeof(uint8_t) == 1?1:-1];
-typedef char uint16_size_if_correct [sizeof(uint16_t) == 2?1:-1];
+typedef char uint16_size_is_correct [sizeof(uint16_t) == 2?1:-1];
typedef char uint32_size_is_correct [sizeof(uint32_t) == 4?1:-1];
typedef char uint64_size_is_correct [sizeof(uint64_t) == 8?1:-1];
typedef char int16_size_if_correct [sizeof(int16_t) == 2?1:-1];
bool util_strupper (const char *);
bool util_strdigit (const char *);
+bool util_strncmpexact (const char *, const char *, size_t);
char *util_strdup (const char *);
char *util_strrq (const char *);
char *util_strrnl (const char *);
/*===================================================================*/
/*=========================== code.c ================================*/
/*===================================================================*/
+
+/* Note: if you change the order, fix type_sizeof in ir.c */
enum {
TYPE_VOID ,
TYPE_STRING ,
TYPE_FUNCTION ,
TYPE_POINTER ,
/* TYPE_INTEGER , */
- TYPE_VARIANT
+ TYPE_VARIANT ,
+
+ TYPE_COUNT
};
+extern size_t type_sizeof[TYPE_COUNT];
+
/*
* Each paramater incerements by 3 since vector types hold
* 3 components (x,y,z).
INSTR_BITAND,
INSTR_BITOR,
- /* Virtual instructions used by the IR
+ /*
+ * Virtual instructions used by the assembler
+ * keep at the end but before virtual instructions
+ * for the IR below.
+ */
+ AINSTR_END,
+
+ /*
+ * Virtual instructions used by the IR
* Keep at the end!
*/
VINSTR_PHI,
* code_write -- writes out the compiled file
* code_init -- prepares the code file
*/
-void code_write ();
-void code_init ();
+bool code_write (const char *filename);
+void code_init ();
+uint32_t code_genstring (const char *string);
+uint32_t code_cachedstring(const char *string);
/*===================================================================*/
/*========================= assembler.c =============================*/
{ "NOT_FNC" , 0, 7 },
{ "IF" , 0, 2 },
{ "IFNOT" , 0, 5 },
- { "CALL0" , 0, 5 },
- { "CALL1" , 0, 5 },
- { "CALL2" , 0, 5 },
- { "CALL3" , 0, 5 },
- { "CALL4" , 0, 5 },
- { "CALL5" , 0, 5 },
- { "CALL6" , 0, 5 },
- { "CALL7" , 0, 5 },
- { "CALL8" , 0, 5 },
+ { "CALL0" , 1, 5 },
+ { "CALL1" , 2, 5 },
+ { "CALL2" , 3, 5 },
+ { "CALL3" , 4, 5 },
+ { "CALL4" , 5, 5 },
+ { "CALL5" , 6, 5 },
+ { "CALL6" , 7, 5 },
+ { "CALL7" , 8, 5 },
+ { "CALL8" , 9, 5 },
{ "STATE" , 0, 5 },
{ "GOTO" , 0, 4 },
{ "AND" , 0, 3 },
{ "OR" , 0, 2 },
{ "BITAND" , 0, 6 },
- { "BITOR" , 0, 5 }
+ { "BITOR" , 0, 5 },
+ { "END" , 0, 3 } /* virtual assembler instruction */
};
void asm_init (const char *, FILE **);