types: missing 'long double' in psi_t_size() and psi_t_alignment()
[m6w6/ext-psi] / src / token.h
index c7ce75147cd127d097ac3ecd51d562236dc93293..65d37a2e635d6f8fdf69e7970dcb29450310917a 100644 (file)
@@ -1,10 +1,48 @@
-#ifndef _PSI_TOKEN_H
-#define _PSI_TOKEN_H
+/*******************************************************************************
+ Copyright (c) 2016, Michael Wallner <mike@php.net>.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+     * Redistributions of source code must retain the above copyright notice,
+       this list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*******************************************************************************/
+
+#ifndef PSI_TOKEN_H
+#define PSI_TOKEN_H
 
 #include <stddef.h>
 #include <stdarg.h>
 #include <stdint.h>
 #include <assert.h>
+#include <sys/param.h>
+
+static inline size_t psi_align(size_t s, size_t a) {
+       return ((s - 1) | (a - 1)) + 1;
+}
+
+static inline size_t psi_offset_padding(size_t diff, size_t alignment) {
+       if (diff && diff <= psi_align(diff, alignment)) {
+               diff = 0;
+       }
+
+       return diff;
+}
 
 #include "parser_proc.h"
 
 
 typedef int token_t;
 
+static inline int psi_num_exp_op_cmp(token_t op1, token_t op2)
+{
+       assert(!op1 || op1 == PSI_T_LPAREN || (op1 <= PSI_T_NOT && op1 >= PSI_T_PIPE));
+       assert(!op2 || op2 == PSI_T_LPAREN || (op2 <= PSI_T_NOT && op2 >= PSI_T_PIPE));
+
+       if (PSI_T_LPAREN == op2) {
+               return -1;
+       } else if (PSI_T_LPAREN == op1) {
+               return 1;
+       } else if (op1 == op2) {
+               return 0;
+       } else if (!op1) {
+               return 1;
+       } else if (!op2) {
+               return -1;
+       }
+
+       switch (op1) {
+       case PSI_T_PIPE:
+               return op2 > PSI_T_PIPE ? 1 : (op2 < PSI_T_PIPE ? -1 : 0);
+       case PSI_T_CARET:
+               return op2 > PSI_T_CARET ? 1 : (op2 < PSI_T_CARET ? -1 : 0);
+       case PSI_T_AMPERSAND:
+               return op2 > PSI_T_AMPERSAND ? 1 : (op2 < PSI_T_AMPERSAND ? -1 : 0);
+
+       case PSI_T_LSHIFT:
+       case PSI_T_RSHIFT:
+               return op2 > PSI_T_RSHIFT ? 1 : (op2 < PSI_T_LSHIFT ? -1 : 0);
+
+       case PSI_T_PLUS:
+       case PSI_T_MINUS:
+               return op2 > PSI_T_MINUS ? 1 : (op2 < PSI_T_PLUS ? -1 : 0);
+
+       case PSI_T_ASTERISK:
+       case PSI_T_SLASH:
+       case PSI_T_MODULO:
+               return op2 > PSI_T_MODULO ? 1 : (op2 < PSI_T_ASTERISK ? -1 : 0);
+
+       case PSI_T_NOT:
+       case PSI_T_TILDE:
+               return op2 > PSI_T_TILDE ? 1 : (op2 < PSI_T_NOT ? -1 : 0);
+       }
+
+       return 0;
+}
+
 static inline size_t psi_t_alignment(token_t t)
 {
 #define PSI_ALIGNOF(T) case PSI_T_## T: return ALIGNOF_## T ##_T;
@@ -34,6 +118,10 @@ static inline size_t psi_t_alignment(token_t t)
                return ALIGNOF_VOID_P;
        case PSI_T_ENUM:
                return ALIGNOF_INT;
+#ifdef HAVE_LONG_DOUBLE
+       case PSI_T_LONG_DOUBLE:
+               return ALIGNOF_LONG_DOUBLE;
+#endif
        default:
                assert(0);
        }
@@ -56,17 +144,33 @@ static inline size_t psi_t_size(token_t t)
                return SIZEOF_FLOAT;
        case PSI_T_DOUBLE:
                return SIZEOF_DOUBLE;
+       case PSI_T_VOID:
        case PSI_T_POINTER:
        case PSI_T_FUNCTION:
                return SIZEOF_VOID_P;
        case PSI_T_ENUM:
                return SIZEOF_INT;
+#ifdef HAVE_LONG_DOUBLE
+       case PSI_T_LONG_DOUBLE:
+               return SIZEOF_LONG_DOUBLE;
+#endif
        default:
-               assert(0);
+               assert(!t);
        }
        return 0;
 }
 
+static inline const char *psi_t_indent(unsigned level) {
+       static const char indent[] =
+                       "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
+       return &indent[32 - MIN(32, level)];
+}
+
+static inline const char *psi_t_indirection(unsigned pointer_level) {
+       static const char indir[] = "********************************";
+       return &indir[32 - MIN(32, pointer_level)];
+}
+
 struct psi_token {
        token_t type;
        unsigned size, line, col;