M4BASIC - m4basic
Not logged in
#!/usr/bin/env bash
#
# BASH frontend for M4Basic - Sept 2014, PvE - GPL v3.
#
#--------------------------------------------------------

# Make sure this is the correct BASH
if [[ ${BASH_VERSINFO[0]}$((${BASH_VERSINFO[1]}+0)) -lt 32 ]]
then
    echo "System error: this is BASH version ${BASH_VERSION}. M4Basic needs BASH 3.2 or higher to run!"
    exit 1
fi

# Set the extended globbing option in BASH
shopt -s extglob

# Set environment
export LC_ALL=C

# Disable filename expansion
set -f

# Set format of time
TIMEFORMAT='%3R'

# Check arguments
if [[ $# -eq 0 ]]
then
    echo "Usage: $0 <prog.m4b>"
    exit 1
fi

# Check if m4 is available
M4=`which m4 2>/dev/null`
if [[ -z ${M4} ]]
then
    echo "Cannot find 'm4' utility!"
    exit 1
fi

# Check if indent is available
INDENT=`which indent 2>/dev/null`
if [[ -z ${INDENT} ]]
then
    echo "Cannot find 'indent' utility!"
    exit 1
fi

# Check if gunzip is available
GUNZIP=`which gunzip 2>/dev/null`
if [[ -z ${GUNZIP} ]]
then
    echo "Cannot find 'gunzip' utility!"
    exit 1
fi

# Check if AWK is available
AWK=`which awk 2>/dev/null`
if [[ -z ${AWK} ]]
then
    echo "Cannot find 'awk' utility!"
    exit 1
fi

# Set some default variables
TEMPDIR=.
CCNAME=gcc
CCFLAGS=
INCFILES=
NO_COMPILE=0
TMP_PRESERVE=0
LIBFILES=

# Get arguments
while getopts ":c:d:i:l:o:npvh" OPT
do
    case $OPT in
	c) 
           CCNAME=$OPTARG;;
	d)
           if [[ ! -d $OPTARG ]]
	   then
		mkdir -p $OPTARG
	   fi
	   TEMPDIR=$OPTARG;;
	i) 
	   INCFILES="$INCFILES -include ${OPTARG}";;
	l) 
	   LIBFILES="$LIBFILES -l$OPTARG";;
	o) 
           CCFLAGS="$CCFLAGS $OPTARG";;
	n) 
           NO_COMPILE=1;;
	p) 
           TMP_PRESERVE=1;;
	v) 
           echo
	   echo "m4basic version 1.0 - (c) Peter van Eerten - GPL v3."
	   echo
	   exit 0;;
	\?|h)
            echo 
	    echo "USAGE: m4basic [options] program[.m4b]"
	    echo 
	    echo "OPTIONS:"
	    echo 
	    echo -e " -c <compiler>\tCompiler to use (default: gcc)"
	    echo -e " -d <tmpdir>\tTemporary directory (default: .)"
	    echo -e " -i <include>\tAdd include file to C code"
	    echo -e " -l <libraries>\tPass libraries to linker"
	    echo -e " -o <options>\tPass compiler options"
	    echo -e " -n \t\tDo not compile, only convert"
	    echo -e " -p \t\tPreserve temporary files"
	    echo -e " -v \t\tShow version"
	    echo -e " -h \t\tShow help"
            echo
            exit 0;;
    esac
done

shift $(($OPTIND-1))

# Check if compiler is available
GCC=`which ${CCNAME} 2>/dev/null`
if [[ -z ${GCC} ]]
then
    echo "Cannot find '${CCNAME}' C compiler!"
    exit 1
fi

# Cut off file extension
PROG=${1}
if [[ ${PROG} = +(*.m4b) ]]
then
    PROG=${PROG%%.*}
fi

# Check if file exists
if [[ ! -f ${PROG}.m4b ]]
then
    echo "Cannot find file '${PROG}'!"
    exit 1
fi

# Dump payload to m4 script
LINE=$(grep -n "^BASIC" $0)
tail -n +${LINE%%:*} $0 | ${AWK} '{if ($0 != "BASIC"){split($0, byte); for(i=1; i <= NF; i++) printf("%c", byte[i]);} }' > ${TEMPDIR}/basic.m4.gz
${GUNZIP} -f ${TEMPDIR}/basic.m4.gz

# Count lines of source file
LINES=`wc -l ${PROG}.m4b`

# Convert to C
SECS="$(time (${M4} ${TEMPDIR}/basic.m4 ${PROG}.m4b | ${INDENT} > ${TEMPDIR}/${PROG}.c) 2>&1 1>/dev/null)"
echo "Converting '${PROG}.m4b'... done, ${LINES%% *} lines were processed in ${SECS} seconds."

if [[ $NO_COMPILE -eq 1 ]]
then
    exit 0
fi

# Compile program
echo -n "Compiling '${PROG}.c'... "
${GCC} ${INCFILES} ${CCFLAGS} -o ${TEMPDIR}/${PROG} ${TEMPDIR}/${PROG}.c -lm -lgc ${LIBFILES} >${TEMPDIR}/${PROG}.log 2>&1
if [[ -z `cat ${TEMPDIR}/${PROG}.log` ]]
then
    echo "done."
    echo "Program '${PROG}' ready."
else
    echo "error."
    cat ${TEMPDIR}/${PROG}.log
fi

# Cleanup
if [[ $TMP_PRESERVE -eq 0 ]]
then
    rm ${TEMPDIR}/${PROG}.c ${TEMPDIR}/${PROG}.log ${TEMPDIR}/basic.m4
fi

# All done.
exit 0

#-------------------------------------------------#
# Data created with: od -An -tu1 -w32 basic.m4.gz #
#-------------------------------------------------#
BASIC
  31 139   8   8 204 171 128  84   0   3  98  97 115 105  99  46 109  52   0 181  25 107 119 218  58 242  59 191  66 165 121 216
  65 164  64 146 238 217  82 110  75 192  16 182 128 185 216  52 233 237 246 128  99   4 241 185 198 102 109 147 180 155 246 191
 239  72 126  72 114  32  73  79 187  61 109  65 163 153 209 188  53  35 230 206  45   9  34 165  92  85 231 158  91 120 137 202
 191 242   7 232 155  30 178 162 136 172 214  17 138 124 100   7 196 138   8 178 208 202 241 156 149 229 162 243 166 209 107 209
 157  22 178 125 143  30  77   2 180   9  29 111 137   6 167 199  64 175 216  42  26  17  10 189 181  60 164  81   4  15 163 230
 102 185   9  35  84  70 109  98 147 213  53 236 214  42 213  83  88 119  71 125 116 123   2 132  64  58  36 100  30 162 232 134
 160 115 159 220 172  80 215  10 174 173  37  65  45 223 117 137  29 249   1  82  92 231 122 105 171  49 250  36 132 205  55 104
 117 138 174 173 208 177 143 225 203  58 240 151 199 176  66 223 145 227 205 137  23 161  63  98 152 205  40  90 254 106 237 184
  86 228 248 222  27 180 180 109  84 246 217 118 130 131 202 238  10 254  45  99 228  95  53 100 207   3  35 120  96 178 149 101
   7  62  53 217 194 221 132  55 200 114  93  52 167  78  11  65 140 176  48  39  11 199  35 202 180 211 194  51   6 142 208 198
 139 191  28 170   5 224  99  68 224 129  21 232  18 162 165 143 110  72  64  82 154 209 184  55  52 241  12  72  81   2 233 232
 227  65 211  76  25 209 160 200 152  41  53  21 241 111  51 124 152 174 170 234 161 138  22 235 192 241 162 133  18  70 115 127
  19 225 116 239  84  85 235 156 170 184  31  22 179 173  19  32  75   5 233  13  71 147  84 144 148 233  98  73 162  80 225 216
 141 110 107  10   1 228 250 182  50 189 222  44  66 231 191  68 197 233  55  12 231  58 158 120  22 103  62 236 199 156 115  34
  22 255 237  21 213  58  71 187 188 232 245  53 201  24 109 157  45  65 187 187  27 199  37  10 103 174 222 139 202 103  28 180
  97  59 102 240 131   3 199 218  72 107 166 186 249  91 233  38  67 179 151 200 248  67  56 131 107  83  85  99   1  94  40 156
   8  60  21 147 128 127  98 200 204 212  65 212 100  97 130 236 124 199  48 181  17 223 163 171 237  46  62 203  92 124  70 157
 154 217  94  88 156 169 213 244 235 107 201  14  11  63  16  44  52 237  52   5  97  97 133 103 123 213 122  22  21 245 112 115
  29  70 129 178  87 197  21  76  51 237  43 253 218  80 213  82 131 159 186  11 231 109  67 112 174 118 101 230  76  87  22 109
 123  62 214 154  31  98 132 107  40  69 127  11  14 111 233  96 247 225  36 241  57  20 163 200 241  54  68  64 232 107 114  76
 214  68 143 112  52  35  69  91  67 118   2  76  97  65 131 103  42  71  70 137  42 211 206 121 166  11 253  14 202  32  26 215
 176  55 223 172  21  17 141 220  90 174  34  98 150 170 128  12  18 172 253 117 118   8 245  11 247  50 224 113  39  83  34  46
  99  91 107 245 155  99  57 188 205  79  35 109 123  24  84  85  41 183  51 135   8 234 187  62  20 236  45 201 102 152  80  83
 186  59 236  33 137 142 224 239 212 144 162 196 128  40 113  22 196  13  73 162 249 108 239  61  16 130  30 184  92 197 246 141
  21  28  33  10  18 109  86 132  36  78 182  18 235  49 162 212 202  25   7  53  79 132 102 244 244 240 198  89  68 202 222 123
   8 113  68  69 226  21 201 212 186 218 248 185 138   8  78 160 102  21 220 192 172  76 173   5 218 126  20 181 237 244 245 230
 174 192 249  89 254  80 208 174  93 146  63   1  86 143 217 147 145  50 123  54  42 117 140 226 229 227  54   4  68  48 219 199
 221 102 203  42  96  22  26 165 138  24  54 228 171  19   9  18 246  58 114  68  94 104 195 180 228  58 139  39 235 173 214 127
 132 254   7  85 251 121  92 140  36  47  24 201 189 164  76 122 128  80 208  59 189   7 160 222 176 245 172  72 145  29   9  84
  50 192 152  12   4 199 194  54 158 149  74   2   4 246   1 210 160 121 211  19 253  12 201 253 127  58 190  92 206  31  95 126
 120  60 172  30  11  51  22  97 148  29 196 216  19  25  74 143 144 112 132  34 152 161 177  58  88  23  28 216 213  77 125 119
 157  94 250 208  56   9  53 189 121 174 245 115 216 111 182 150 245  86 179 159  71 220  94 254  63 193 125  58 200  53  47  99
 205 252 216 236  55 194 111  33 180  94  66  19 163 214  33  34  47 123  29 237 170 103 106 109  37  70  83  83 244  75  10  54
 204 166  57  49 210 173 250 150  26 171 143 146  48 231 254 134 110 224  48 171 229  39  42 230 110 107  26 120 150  70   1 197
 218  90 218 229  54 173 177 240 215 196  19  60 220 234 235 105 142  44 108 215  15 165  86 104 171  81 224 214 109 247 135 114
 107  57 214   7 153 136 167 170  40 200 207 181 122 188  19 217 222 239  93 142 193 182 233 225 187 187 163 109 221 235  54 123
 128  53  89 223  42  42 119 217  75 235  92  64 238  32  62 159 180 135 161 105  31  36 107 232 157  14 237  27  50 178  25  22
  47  90  88  81 138  41 160 136 252  22  33  33 127  11 126  49 250  26 237 228 152 158 161  75 200  90 144 227 168  90 169  84
 182  11   3 141 143 241 172 155   7  68 154  21  94 198  84 135 104 218  50 197 172 111   1 139 180  67 123 207  59 180 247 120
 214 160 185 204 183 132  36  78 118 105  10 139 229 171 211   1 111  49 169  56 116 164 127 208 158  41 227 116 164 139 130 141
 192 185  71 202 116 160  13 216 141 118 164  42  79 148  29 104  13  80 134  47  99 239  42  64  80 129 132  27  97 172 105 185
  74  33  26  30 130 121  17  16 162  40 183 190  51  63  18 131  98 114 158  35  19  46  40 138  44  95 172  25 186 120  25  77
 104 153 254 165 166  78  56  19 114  96  91  66 193 217 252  28 105 180  49  39 227 225 163 247 125  64 162  77  32 151  18 173
  57 222  49 143  85  78  78  62 215 254 197  62  42 245 202   2 122 180   5 155 120  19  12 113  88 163  53 255 234 211 115 227
 163  43 197  71  23 226  35  63 174 198 135 239 207 235 251 243 139  34   6 143  71 207 140 131  45 184  15  35  76 125  68 147
 150 222 127 122 146 227 113 149 156 199 183 199  26 155  63 120  33 169 164  56 149  67 105 132 123  32 131  80  87 182 121  98
 127 190  63  95  21 179 243  82 121 147  52  97  18  23  94  50 145  81 154  59 105 173 200   0  98 172  12 114 129 114 244 170
 144   9 240 234 168  16 191  85 116  54 158  77  95  87  30  60  85  52 207  13 172  40  48   0 170 232  45 170 168 232  29  42
 179 197  27  68  63  32 135  51 196 118  27  76   2 200 172 231  86  14 232 110 182  71 171 246 193   1 151 170  57  26 209  38
  15   6 150 162  85  42 114 176 209  74 233  55  94 232  44  61  50  71 116 196  80 143 128  91  54  89  54  91  31 186  99 125
   2  60  79  57 176  15  80  92  17 214  48  95 158  10 206  54 176 237 135 138 146  52 236  57 217  91 159 154  67 252  90 202
  59 250  38 177  32 254  66  17 245 208 254 156  52 161  55  73  68 100 118 104  52 208 112 210 239 163 131   3  48  72 141 175
 223 161  42 181 145 132 243 253 123  30 167   2  56  47  32 128 237 213 154 206 216 123 244 245  65 200 255 143 208 111 128 241
 227 227  40 167 125  84 163 212 204  15 148 127  69  80  66 187  26  97 242 117 157 233  40  10 222 105 210 102 155 155 135 170
   7  61 143  97 130 191 246 170 232  69  38 208  11 203 182  73  24  82  97  80 103 170 127  80 217  33  18 221 200  28  99 250
 121  36  78  84 144  74 177 152  11 215 247   3 201 104 208 252 104 137 191  78 120  29 209  76 109 248  17 199 246 225 199  43
 208 144  16 239  54   7 229 243  35 223 166 130 193  52 153 252 207 249 194 149  48 196  53  97  66 128 193  24 103  22 204 152
 130 187 246 106 226 193 112  64 242 230   1  78  40 195   1 165 188 125 233 147 157  75 243 117  87  20 245 140 216 204 153 211
   5 195 129 169 199  19 141 235  43 108 245 181  14 212  17 133 141 210 121  25  89 184 188 109  32  16 205 133 206 144  18 191
 163  11 207  94 127  83 120 179 198 183 161  54 226  88   7 144 126  79 108  62 250  44 150 100 195  10 108  37  55 247 245  46
 140 206 203  93 138  14 154  93 109 104  54 241 153  88 156 244 241 167  52  51 184  96 148 240 136  54 143 144  72 217  69  47
   8  53 232 181  31  81 189 180 119 242 243 218 179  79 106  55  24 129  40  61  75 194 237  86 124 220 136 165 189  90 185 154
 152  81  20  89 111  99  57  37 211  69  77 180 209  80  55 177 242  34 103  56 189 221 126 152 207  47 118 228  51 189 157 190
 127  23  26  51 218 202 242 254 234  72 149 178 108 212 195  39 199 213 211 234 217  63 107 175 207  78 120  45  27 233 151 120
 237 223  73 174 196 124  33 201  60 134  58  13 179   2  15  82 144  42 176 188 185 191  82 212  87 108 119  58 104  94 189  74
 211  79  20 150 206  29 172 156   7  69   9 198 102   2  92 188  43 137 224  54 230 213 124 220 235  94 252 238 240  47 113  64
 153 178 216 150  14 113  65 122  52 159 141 238  80 200 229 164  90 103  87  33 189   9 169 203 100 146 222  16 135 142 183 147
  99 239  47  77 239 224  36  33  68 247  25 127 142 113 248 159  96 167  44  38  92  80 145 181 147  49 204  93 125 188 136 136
 235  74  92  89 205 225 182 134 185 246  65   9 176 162  88 146 156  63  47  47 168 223 254  33 205 118 204 191 119 220 145 159
 224  80 136 174  19 214  64 152  55  36  36  48  13  17 246  51  80 119  56  65 228  43 212 106 250  83   9  58  12 211  95  66
   0 184  14 224 126   1 232  97 118 249  94  64 160  43 247 210 133 143 166 209 106  13 211  65 169  52  93  71  65 125  26 194
  12 250 153 194 190   8  35 106  98 198 184  65 168 169 245 208  75 218  41   1  29 203  72  48  81 218 105 107  69  13  37 114
 174 255 144  70 181 254 100  48  52 168  96  16  76  27  59  66  48 110  82  94  76 178 186 227 219 145 171  24 102  91 159 152
  83 122  25  14 117 108 246 244  86  23   6  84 227  47 124  64 145 128  57 252 127 124  23  78 109 223 205  49  31 182 232  19
 228 227  74 163 237  90  87 129 111  75 167  79 128  59 133 135 125 250  48  36  36 147 122 159  99  22 144 100 204  23  77  21
 103 141   0  82  75  82 106 213 105 205 180  34 137   8 118 234  63  80 242  10 181 247  18  87  49 180 155  32 159 240  80  41
 190  83 182 181 150 164  55 157 124  98 139  66  23  28 218 150 183  96   1  10 131 193 254  85  17 163 216 144  52 255  32 111
  84 134 217 168  48 187  74  10  95 104  87 191  33 132   0 248 117 238  44 157 104  71  40 101 251 152   9 167 136  74  60  17
  78  99 253 242  55 197  82 224 223  73 156 105 123 243  91  85  87 178  14 142 154  29  66   8  42 238  83 214 112 231  69 222
  99 177 187 225  73 146 101  17  75 181 108 139 237 232 111 218 108  26  31 156  82 181 188  37 253 173  58 130 178   2   6 167
 183   0  93 186  78  68   2 203  13  11  12 129 216 112  85 205 138  48 253  21  41 125  50 230  84 226  31 216  29 207 118  55
 115 130 222 194 180 229  58 215 199  55 127 200  48 199 151  65  27 207   1 104  30 141 158  42 195  86  86 116  35  67  34 103
  69 114 116 223 194  87 204 207  50 120 105 179 117 110 120  99  62 228 208 212 104 232 164 198 129 201 155  28 170 157 189  46
 208  28  90  89 112 235 208  47  86 176 180  49 138 127 151 129 239 183 159 191 168 247  12  35 126 215 172  23 114 145   2   1
   2 145  82 169  23 216 242  40 118   2 112 253   2 208 251 248 146 248  81  47  64 216 244 134  61  83  81 235 133  48 233   8
 228 240 167  42  43 172 210   0 202 234 244  46 176 214  74 242  78 199  30  34  42  80  37  14 153  31 254   7 242  33  38  32
 247  32   0   0

Return to M4BASIC