#!/bin/ksh # # KornShell BASIC-to-C converter --= BACON =-- # # Peter van Eerten - March 2009. # # Global variables should be preceded with a 'g_'. # #----------------------------------------------------------- # GLOBAL INITIALIZATONS #----------------------------------------------------------- # Version of BACON g_VERSION="0.26" # Link flags g_LDFLAGS="-lm" # Amount of string functions simultanously used in one line let g_MAX_DEPTH=32 # Find 'grep' and other coretools if [[ -z `which grep` || -z `which cat` || -z `which rm` || -z `which tr` ]] then print "ERROR: 'grep', 'cat', 'rm' or 'tr' not found on this system!" exit 1 fi # Find 'indent' if [[ -z `which indent` ]] then print "WARNING: 'indent' not found on this system!" print "Generated source code will not be beautified." fi #----------------------------------------------------------- function Handle_Print { typeset FORMAT EXP LEN DQ # If no argument, do nothing if [[ "$1" != "PRINT" && "$1" != "print" ]] then # Get expression without ; if [[ -z ${1##*;} ]] then let LEN="${#1}-1" typeset -L$LEN EXP="$1" else EXP=${1} fi typeset -R1 DQ="$EXP" # If there is FORMAT/format argument if [[ "$EXP" = +(* FORMAT *) || "$EXP" = +(* format *) ]] then FORMAT=${EXP##* FORMAT} if [[ "$FORMAT" = "${EXP}" ]] then FORMAT=${EXP##* format} print -r "fprintf(stdout, ${FORMAT%%;*}, ${EXP%%format *});" >> $g_CFILE else print -r "fprintf(stdout, ${FORMAT%%;*}, ${EXP%%FORMAT *});" >> $g_CFILE fi else # Check type of var, string? if [[ "$EXP" = +(*INSTR\(*) || "$EXP" = +(*VAL\(*) || "$EXP" = +(*instr\(*) || "$EXP" = +(*val\(*) || "$EXP" = +(*LEN\(*) || "$EXP" = +(*len\(*) ]] then print -r "fprintf(stdout, \"%g\", (double)($EXP));" >> $g_CFILE elif [[ "$EXP" = +(*\$*) ]] then print -r "fprintf(stdout, \"%s\", $EXP);" >> $g_CFILE # Check if it is a normal string - or'ing because of syntax highlighting elif [[ $DQ = "\"" || $DQ = "\"" ]] then print -r "fprintf(stdout, \"%s\", $EXP);" >> $g_CFILE # Other else print -r "fprintf(stdout, \"%g\", (double)($EXP));" >> $g_CFILE fi # If line ends with ';' then skip newline if [[ -n ${1##*;} ]] then print -r "fprintf(stdout, \"\n\");" >> $g_CFILE fi fi else print -r "fprintf(stdout, \"\n\");" >> $g_CFILE fi } #----------------------------------------------------------- function Handle_Input { # Local variables typeset CHECK VAR TARGET # Check if we have an argument at all if [[ "$1" = "INPUT" ]] then print "ERROR: empty INPUT at line $g_COUNTER in file $g_CURFILE!" exit 1 fi # Determine target if [[ -n $g_FUNCNAME ]] then TARGET=$g_CFILE else TARGET=$g_HFILE fi touch $TARGET # Get the variablename without surrounding spaces VAR=`print ${1}` # Translate function to C function print "fgets(__b2c__input__buffer, $g_MAX_STRING, stdin);" >> $g_CFILE # Check type of var, string? if [[ "${VAR##*$}" != "$1" ]] then CHECK=`grep -i "$VAR\[$g_MAX_STRING\]" $TARGET` if [[ -z $CHECK ]] then print "char $VAR[$g_MAX_STRING];" >> $TARGET fi # Make sure internal var is copied to var of program print "strncpy($VAR, __b2c__input__buffer, $g_MAX_STRING);" >> $g_CFILE # Get rid of the terminating newline print -r "$VAR[strlen($VAR)-1] = '\0';" >> $g_CFILE # Var is numeric else # Variable may not be array, these should be defined with DECLARE if [[ "$VAR" != +(*\[*\]*) ]] then # Not declared? Assume long CHECK=`grep "FILE\|int\|long\|float\|double\|char\|void" $TARGET | grep " $VAR,\| $VAR;\|,$VAR,\|,$VAR;"` if [[ -z $CHECK ]] then print "long $VAR;" >> $TARGET fi else if [[ -z `grep -i " ${VAR%%\[*}\[" $TARGET` && -z `grep -i ",${VAR%%\[*}\[" $TARGET` ]] then print "ERROR: cannot declare implicit array in INPUT statement at $g_COUNTER in file $g_CURFILE!" exit 1 else CHECK=`grep -i " ${VAR%%\[*}" $TARGET` fi fi # Make sure internal var is copied to var of program if [[ "$CHECK" = +(double *) ]] then print "$VAR = atof(__b2c__input__buffer);" >> $g_CFILE else print "$VAR = atoi(__b2c__input__buffer);" >> $g_CFILE fi fi } #----------------------------------------------------------- function Handle_For { # Local variables typeset FROM TO TMP VAR STEP CHECK TARGET # Get the variablename without surrounding spaces VAR=`print ${1%%=*}`; TMP=`print ${1#*=}` # Do we have a STRING var? if [[ "${VAR##*$}" != "$VAR" ]] then print "ERROR: variable in FOR statement at line $g_COUNTER in file $g_CURFILE cannot be string!" exit 1 fi # Check if TO is available if [[ "$TMP" != +(* TO *) ]] then if [[ "$TMP" != +(* to *) ]] then print "ERROR: missing TO in FOR statement at line $g_COUNTER in file $g_CURFILE!" exit 1 fi fi # Get the starting and ending value if [[ "$TMP" = +(* TO *) ]] then FROM=`print ${TMP%% TO *}` TO=`print ${TMP##* TO }` else FROM=`print ${TMP%% to *}` TO=`print ${TMP##* to }` fi # Check if there is a STEP if [[ "$TO" = +(* STEP *) ]] then STEP=${TO##* STEP } TO=${TO%% STEP *} elif [[ "$TO" = +(* step *) ]] then STEP=${TO##* step } TO=${TO%% step *} else STEP=1 fi # Translate function to C function if [[ $STEP -lt 0 ]] then print "for($VAR=$FROM; $VAR >= $TO; $VAR+=$STEP){" >> $g_CFILE else print "for($VAR=$FROM; $VAR <= $TO; $VAR+=$STEP){" >> $g_CFILE fi # Determine target if [[ -n $g_FUNCNAME ]] then TARGET=$g_CFILE else TARGET=$g_HFILE fi touch $TARGET # Variable may not be array, these should be defined with DECLARE if [[ "$VAR" = +(*\[*\]*) ]] then if [[ -z `grep -i " ${VAR%%\[*}\[" $TARGET` && -z `grep -i ",${VAR%%\[*}\[" $TARGET` ]] then print "ERROR: cannot declare implicit array in FOR statement at $g_COUNTER in file $g_CURFILE!" exit 1 fi else # Declare variable if not done yet, assuming long CHECK=`grep "FILE\|int\|long\|float\|double\|char\|void" $TARGET | grep " $VAR,\| $VAR;\|,$VAR,\|,$VAR;\| ${VAR%%\[*}\[\|,${VAR%%\[*}\["` if [[ -z $CHECK ]] then print "long $VAR;" >> $TARGET fi fi } #----------------------------------------------------------- function Handle_If { # Check if THEN is available if [[ "$1" != +(* THEN) ]] then if [[ "$1" != +(* then) ]] then print "ERROR: Missing THEN in IF statement at line $g_COUNTER in file $g_CURFILE!" exit 1 fi fi # Translate function to C function print "if(${1% *}){" >> $g_CFILE } #----------------------------------------------------------- function Handle_Elif { # Check if THEN is available if [[ "$1" != +(* THEN) ]] then if [[ "$1" != +(* then) ]] then print "ERROR: Missing THEN in ELIF statement at line $g_COUNTER in file $g_CURFILE!" exit 1 fi fi # Translate function to C function print "} else if(${1% *}){" >> $g_CFILE } #----------------------------------------------------------- function Handle_While { # Check if DO is available if [[ "$1" != +(* DO) ]] then if [[ "$1" != +(* do) ]] then print "ERROR: Missing DO in WHILE statement at line $g_COUNTER in file $g_CURFILE!" exit 1 fi fi # Translate function to C function print "while(${1% *}){" >> $g_CFILE } #----------------------------------------------------------- function Handle_Let { # Local variables typeset VAR CHECK TMP TARGET # Check if there is an asignment at all, if not exit if [[ "$1" != +(*=*) ]] then print "ERROR: could not parse line $g_COUNTER in file $g_CURFILE!" exit 1 fi # Determine target if [[ -n $g_FUNCNAME ]] then TARGET=$g_CFILE else TARGET=$g_HFILE fi touch $TARGET # Get the variablename without surrounding spaces VAR=`print ${1%%=*}`; TMP=${1#*=} # Check if var is string var if [[ "${VAR}" = +(*\$) ]] then CHECK=`grep -i " $VAR\[$g_MAX_STRING\]" $TARGET` if [[ -z $CHECK ]] then print "static char $VAR[$g_MAX_STRING];" >> $TARGET fi # Variable may not be array, these should be defined with DECLARE elif [[ "$VAR" = +(*\[*\]*) ]] then if [[ -z `grep -i " ${VAR%%\[*}\[" $TARGET` && -z `grep -i ",${VAR%%\[*}\[" $TARGET` ]] then print "ERROR: cannot declare implicit array in FOR statement at $g_COUNTER in file $g_CURFILE!" exit 1 fi # Assume Integer else CHECK=`grep "FILE\|int\|long\|float\|double\|char\|void" $TARGET | grep " $VAR,\| $VAR;\|,$VAR,\|,$VAR;\| ${VAR%%\[*}\[\|,${VAR%%\[*}\["` if [[ -z $CHECK ]] then print "long $VAR;" >> $TARGET fi fi # Do we have a STRING var? if [[ "${VAR}" = +(*\$) ]] then print "__b2c__strncpy($VAR, $TMP, $g_MAX_STRING);" >> $g_CFILE else print "$1;" >> $g_CFILE fi } #----------------------------------------------------------- function Handle_Open { # Local variables typeset FILE MODE HANDLE TMP CHECK TARGET # Check if FOR is available if [[ "$1" != +(* FOR *) ]] then if [[ "$1" != +(* for *) ]] then print "ERROR: Missing FOR in OPEN statement at line $g_COUNTER in file $g_CURFILE!" exit 1 fi fi # Check if AS is available if [[ "$1" != +(* AS *) ]] then if [[ "$1" != +(* as *) ]] then print "ERROR: Missing AS in OPEN statement at line $g_COUNTER in file $g_CURFILE!" exit 1 fi fi # Get the file, mode and handle if [[ "$1" = +(* FOR *) ]] then FILE=`print ${1%% FOR *}` TMP=`print ${1##* FOR }` else FILE=`print ${1%% for *}` TMP=`print ${1##* for }` fi if [[ "$1" = +(* AS *) ]] then MODE=`print ${TMP%% AS *}` HANDLE=`print ${TMP##* AS }` else MODE=`print ${TMP%% as *}` HANDLE=`print ${TMP##* as }` fi # Check if var is string var if [[ "${HANDLE}" = +(*\$) ]] then print "ERROR: Variable for OPEN at line $g_COUNTER in file $g_CURFILE cannot be string!" exit 1 fi # Determine target if [[ -n $g_FUNCNAME ]] then TARGET=$g_CFILE else TARGET=$g_HFILE fi touch $TARGET # Check if variable was declared CHECK=`grep "FILE\|int\|long\|float\|double\|char\|void" $TARGET | grep " $HANDLE,\| $HANDLE;\|,$HANDLE,\|,$HANDLE;\| ${HANDLE%%\[*}\[\|,${HANDLE%%\[*}\["` if [[ -z $CHECK ]] then print "FILE* $HANDLE;" >> $TARGET fi # Convert to C syntax case $MODE in @(READING|reading) ) print "$HANDLE = fopen($FILE, \"r\");" >> $g_CFILE;; @(WRITING|writing) ) print "$HANDLE = fopen($FILE, \"w\");" >> $g_CFILE;; @(APPENDING|appending) ) print "$HANDLE = fopen($FILE, \"a\");" >> $g_CFILE;; @(READWRITE|readwrite) ) print "$HANDLE = fopen($FILE, \"r+\");" >> $g_CFILE;; esac # Error handling print "if($HANDLE == NULL){fprintf(stderr, \"ERROR: %s in OPEN statement!\\\\n\", strerror(errno)); exit(EXIT_FAILURE);}" >> $g_CFILE } #----------------------------------------------------------- function Handle_Readln { # Local variables typeset CHECK VAR FROM TARGET # Check if FROM is available if [[ "$1" != +(* FROM *) ]] then if [[ "$1" != +(* from *) ]] then print "ERROR: Missing FROM in READLN statement at line $g_COUNTER in file $g_CURFILE!" exit 1 fi fi # Get the variablename without surrounding spaces if [[ "$1" = +(* FROM *) ]] then VAR=`print ${1%% FROM *}` # Get filedescriptor FROM=`print ${1##* FROM }` else VAR=`print ${1%% from *}` # Get filedescriptor FROM=`print ${1##* from }` fi # Check if var is string var if [[ "${VAR}" != +(*\$) ]] then print "ERROR: Variable for READLN at line $g_COUNTER in file $g_CURFILE must be string!" exit 1 fi # Determine target if [[ -n $g_FUNCNAME ]] then TARGET=$g_CFILE else TARGET=$g_HFILE fi touch $TARGET # Translate function to C function print "fgets(__b2c__input__buffer, $g_MAX_STRING, $FROM);" >> $g_CFILE # Check if variable is declared CHECK=`grep -i " $VAR\[$g_MAX_STRING\]" $TARGET` if [[ -z $CHECK ]] then print "char $VAR[$g_MAX_STRING];" >> $TARGET fi # Make sure internal var is copied to var of program print "strncpy($VAR, __b2c__input__buffer, $g_MAX_STRING);" >> $g_CFILE # Make sure to end the string print -r "$VAR[strlen(__b2c__input__buffer)-1] = '\0';" >> $g_CFILE } #----------------------------------------------------------- function Handle_Writeln { # Local variables typeset VAR TO # Check if TO is available if [[ "$1" != +(* TO *) ]] then if [[ "$1" != +(* to *) ]] then print "ERROR: Missing TO in WRITELN statement at line $g_COUNTER in file $g_CURFILE!" exit 1 fi fi # Get the variablename without surrounding spaces if [[ "$1" = +(* TO *) ]] then VAR=`print ${1%% TO *}`; # Get filedescriptor TO=`print ${1##* TO }` else VAR=`print ${1%% to *}`; # Get filedescriptor TO=`print ${1##* to }` fi # Check if var is string var if [[ "${VAR}" != +(*\$) && "$VAR" = `print "$VAR" | tr -d "\042"` ]] then print "ERROR: Variable for WRITELN at line $g_COUNTER in file $g_CURFILE must be string!" exit 1 fi # Translate function to C function print "fprintf($TO, \"%s\\\\n\", $VAR);" >> $g_CFILE } #----------------------------------------------------------- function Handle_Getbyte { # Local variables typeset POS FROM SIZE # Check if FROM is available if [[ "$1" != +(* FROM *) ]] then if [[ "$1" != +(* from *) ]] then print "ERROR: Missing FROM in GETBYTE statement at line $g_COUNTER in file $g_CURFILE!" exit 1 fi fi # Get the variablename without surrounding spaces if [[ "$1" = +(* FROM *) ]] then POS=`print ${1%% FROM *}` # Get filedescriptor FROM=`print ${1##* FROM }` else POS=`print ${1%% from *}` # Get filedescriptor FROM=`print ${1##* from }` fi SIZE= # Check if SIZE is available if [[ "$1" = +(* SIZE *) ]] then SIZE=${FROM##* SIZE } FROM=${FROM%% SIZE *} elif [[ "$1" = +(* size *) ]] then SIZE=${FROM##* size } FROM=${FROM%% size *} else SIZE=1 fi # Translate function to C function print "__b2c__memory__check((char *)$POS, \"GETBYTE\");" >> $g_CFILE print "fread($POS, sizeof(char), $SIZE, $FROM);" >> $g_CFILE } #----------------------------------------------------------- function Handle_Putbyte { # Local variables typeset VAR TO SIZE POS # Check if TO is available if [[ "$1" != +(* TO *) ]] then if [[ "$1" != +(* to *) ]] then print "ERROR: Missing TO in PUTBYTE statement at line $g_COUNTER in file $g_CURFILE!" exit 1 fi fi # Get the variablename without surrounding spaces if [[ "$1" = +(* TO *) ]] then POS=`print ${1%% TO *}`; # Get filedescriptor TO=`print ${1##* TO }` else POS=`print ${1%% to *}`; # Get filedescriptor TO=`print ${1##* to }` fi SIZE= # Check if SIZE is available if [[ "$1" = +(* SIZE *) ]] then SIZE=${TO##* SIZE } TO=${TO%% SIZE *} elif [[ "$1" = +(* size *) ]] then SIZE=${TO##* size } TO=${TO%% size *} else SIZE=1 fi # Translate function to C function print "__b2c__memory__check((char *)$POS, \"PUTBYTE\");" >> $g_CFILE print "fwrite($POS, sizeof(char), $SIZE, $TO);" >> $g_CFILE } #----------------------------------------------------------- function Handle_Import { # Local variables typeset TMP SYM LIB CHECK TOKEN PTR TARGET typeset -l TYPE # Check if FROM is available if [[ "$1" != +(* FROM *) ]] then if [[ "$1" != +(* from *) ]] then print "ERROR: missing FROM in IMPORT statement at line $g_COUNTER in file $g_CURFILE!" exit 1 fi fi # Get the symbolname without surrounding spaces and doublequotes if [[ "$1" = +(* FROM *) ]] then SYM=`print ${1%% FROM *}`; TMP=${1#* FROM } TOKEN=`print $SYM | tr -d "\042"` else SYM=`print ${1%% from *}`; TMP=${1#* from } TOKEN=`print $SYM | tr -d "\042"` fi # Check if TYPE is available if [[ "$1" != +(* TYPE *) ]] then if [[ "$1" != +(* type *) ]] then print "ERROR: missing TYPE in IMPORT statement at line $g_COUNTER in file $g_CURFILE!" exit 1 fi fi # Get library and type if [[ "$1" = +(* TYPE *) ]] then LIB=`print ${TMP%% TYPE *}` TYPE=`print ${TMP##* TYPE }` else LIB=`print ${TMP%% type *}` TYPE=`print ${TMP##* type }` fi # Determine target if [[ -n $g_FUNCNAME ]] then TARGET=$g_CFILE else TARGET=$g_HFILE fi touch $TARGET # If library is libm or libc, skip dlopen as we're linking with those anyway if [[ $LIB != +(*libc.so*) && $LIB != +(*libm.so*) ]] then # Create name from libname PTR=`print $LIB | tr -d [:punct:]` # Check if variable was declared CHECK=`grep -i "void\* __b2c__dlopen__pointer_$PTR;" $TARGET` if [[ -z $CHECK ]] then print "void* __b2c__dlopen__pointer_$PTR;" >> $TARGET print "__b2c__dlopen__pointer_$PTR = dlopen($LIB, RTLD_GLOBAL|RTLD_LAZY);" >> $g_CFILE print "if(__b2c__dlopen__pointer_$PTR == NULL) {" >> $g_CFILE print "fprintf(stderr, \"ERROR: %s\\\\n\", dlerror()); exit(EXIT_FAILURE);}" >> $g_CFILE fi # Check if token was declared CHECK=`grep -i "$TYPE (\*$TOKEN)();" $TARGET` if [[ -z $CHECK ]] then print "$TYPE (*$TOKEN)();" >> $TARGET fi # Translate to C function print "*($TYPE **) (&$TOKEN) = dlsym(__b2c__dlopen__pointer_$PTR, $SYM);" >> $g_CFILE print "if($TOKEN == NULL) {fprintf(stderr, \"ERROR: could not find symbol '$TOKEN' in library!\\\\n\"); exit(EXIT_FAILURE);}" >> $g_CFILE # Add link flag if [[ $g_LDFLAGS != +(* -ldl *) ]] then g_LDFLAGS="$g_LDFLAGS -ldl" fi fi # Make symbol known to parser g_IMPORTED="$TOKEN $g_IMPORTED" } #----------------------------------------------------------- function Handle_Declare { # Local variables typeset VAR TYPE CHECK TARGET # Check if TYPE is available if [[ "$1" != +(* TYPE *) ]] then if [[ "$1" != +(* type *) ]] then print "ERROR: Missing TYPE in DECLARE statement at line $g_COUNTER in file $g_CURFILE!" exit 1 fi fi # Get the variablename and type if [[ "$1" = +(* TYPE *) ]] then VAR=`print ${1%% TYPE *}` TYPE=`print ${1##* TYPE }` else VAR=`print ${1%% type *}` TYPE=`print ${1##* type }` fi # Determine target if [[ -n $g_FUNCNAME ]] then TARGET=$g_CFILE else TARGET=$g_HFILE fi touch $TARGET # Check if variable was already declared CHECK=`grep "FILE\|int\|long\|float\|double\|char\|void" $TARGET | grep " $VAR,\| $VAR;\|,$VAR,\|,$VAR;\| ${VAR%%\[*}\[\|,${VAR%%\[*}\["` if [[ -n $CHECK ]] then print "ERROR: variable in DECLARE statement at line $g_COUNTER in file $g_CURFILE was defined previously!" exit 1 fi # Translate function to C function print "$TYPE $VAR;" >> $TARGET } #----------------------------------------------------------- function Handle_Read { # Local variables typeset CHECK TARGET # Check if we have an argument at all if [[ "$1" = "READ" ]] then print "ERROR: empty READ at line $g_COUNTER in file $g_CURFILE!" exit 1 fi # Determine target if [[ -n $g_FUNCNAME ]] then TARGET=$g_CFILE else TARGET=$g_HFILE fi touch $TARGET # Check type of var, string? if [[ "${1##*$}" != "$1" ]] then CHECK=`grep -i "$1\[$g_MAX_STRING\];" $TARGET` if [[ -z $CHECK ]] then print "char $1[$g_MAX_STRING];" >> $TARGET fi # Convert to C print "strncpy(${1#* }, __b2c__stringarray[__b2c__stringarray_ptr], $g_MAX_STRING);" >> $g_CFILE print "__b2c__stringarray_ptr++;" >> $g_CFILE else # Variable may not be array, these should be defined with DECLARE if [[ "$1" != +(*\[*\]*) ]] then # Not declared? Assume long CHECK=`grep "FILE\|int\|long\|float\|double\|char\|void" $TARGET | grep " $1,\| $1;\|,$1,\|,$1;\| ${1%%\[*}\[\|,${1%%\[*}\["` if [[ -z $CHECK ]] then print "long $1;" >> $TARGET fi else if [[ -z `grep -i " ${1%%\[*}\[" $TARGET` && -z `grep -i ",${1%%\[*}\[" $TARGET` ]] then print "ERROR: cannot declare implicit array in READ statement at $g_COUNTER in file $g_CURFILE!" exit 1 else # See how var was declared CHECK=`grep -i " ${1%%\[*}" $TARGET` if [[ -z $CHECK ]] then CHECK=`grep -i ",${1%%\[*}" $TARGET` fi fi fi # Convert to C if [[ "$CHECK" = +(double *) ]] then print "${1#* } = __b2c__floatarray[__b2c__floatarray_ptr];" >> $g_CFILE print "__b2c__floatarray_ptr++;" >> $g_CFILE else print "${1#* } = __b2c__intarray[__b2c__intarray_ptr];" >> $g_CFILE print "__b2c__intarray_ptr++;" >> $g_CFILE fi fi } #----------------------------------------------------------- function Handle_Function { # Check if we have an argument at all if [[ "$1" = "FUNCTION" ]] then print "ERROR: empty FUNCTION at line $g_COUNTER in file $g_CURFILE!" exit 1 fi # Check if we are in a function already if [[ -n $g_FUNCNAME ]] then print "ERROR: cannot define FUNCTION within FUNCTION at line $g_COUNTER in file $g_CURFILE!" exit 1 fi # Get the funcname g_ORIGFUNCNAME=`print ${1}` if [[ "$g_ORIGFUNCNAME" = +(*\(*\)*) ]] then g_FUNCNAME=`print ${g_ORIGFUNCNAME%%\(*}` else g_FUNCNAME=`print ${g_ORIGFUNCNAME}` fi # Switch to header file g_COPY_CFILE=$g_CFILE g_CFILE=$g_CFILE.$g_FUNCNAME.tmp touch $g_CFILE } #----------------------------------------------------------- function Handle_Endfunction { # Check if return was found if [[ -z $g_FUNCTYPE ]] then print "ERROR: function '$g_FUNCNAME' was defined without returning a value or string!" exit 1 fi # Now setup function in main program if [[ $g_ORIGFUNCNAME != +(*\(*\)*) ]] then print "$g_FUNCTYPE __b2c__function__$g_ORIGFUNCNAME(void) {" > ${g_COPY_CFILE%.*}.$g_FUNCNAME.h else print "$g_FUNCTYPE __b2c__function__$g_ORIGFUNCNAME {" > ${g_COPY_CFILE%.*}.$g_FUNCNAME.h fi # Add function body cat $g_CFILE >> ${g_COPY_CFILE%.*}.$g_FUNCNAME.h print "}" >> ${g_COPY_CFILE%.*}.$g_FUNCNAME.h # Include header file print "#include \"${g_COPY_CFILE%\.*}.$g_FUNCNAME.h\"" >> $g_HFILE # Add to total filelist g_TMP_FILES="$g_TMP_FILES ${g_COPY_CFILE%.*}.$g_FUNCNAME.h" # Delete temp funcfile rm $g_CFILE # Restore mainfile g_CFILE=$g_COPY_CFILE # Create macro if [[ $g_ORIGFUNCNAME != +(*\(*\)*) ]] then print "#define $g_FUNCNAME __b2c__function__$g_FUNCNAME()" >> $g_HFILE else print "#define $g_FUNCNAME(...) __b2c__function__$g_FUNCNAME(__VA_ARGS__)" >> $g_HFILE fi # Make symbol known to parser g_IMPORTED="$g_FUNCNAME $g_IMPORTED" # Clear function variables g_ORIGFUNCNAME= g_FUNCNAME= g_FUNCTYPE= } #----------------------------------------------------------- function Handle_Return { # Local variables typeset CHECK # Check if we have an argument at all if [[ "$1" = "RETURN" ]] then print "ERROR: empty RETURN at line $g_COUNTER in file $g_CURFILE!" exit 1 fi CHECK=`grep "FILE\|int\|long\|float\|double\|char\|void" $g_CFILE | grep " $1,\| $1;\|,$1,\|,$1;\| ${1%%\[*}\[\|,${1%%\[*}\["` # Check type of var, string? if [[ "${1}" = +(*\$*) ]] then g_FUNCTYPE="char * " # Check if it is a normal string elif [[ "$1" != `print "$1" | tr -d "\042"` ]] then g_FUNCTYPE="char * " # Check if float elif [[ "$1" = +(*.*) ]] then g_FUNCTYPE="double " # Check if no alpha chars (then integer value) elif [[ "$1" = +(![a-zA-Z]) ]] then g_FUNCTYPE="long " # Assume variable, check if declared before elif [[ -n $CHECK ]] then if [[ $CHECK = +(double*) ]] then g_FUNCTYPE="double " else g_FUNCTYPE="long " fi # Not declared, assume integer variable else g_FUNCTYPE="long " fi print "return (${1});" >> $g_CFILE } #----------------------------------------------------------- function Handle_Push { # Local variables typeset CHECK TARGET # Check if we have an argument at all if [[ "$1" = "PUSH" ]] then print "ERROR: empty PUSH at line $g_COUNTER in file $g_CURFILE!" exit 1 fi # Determine target if [[ -n $g_FUNCNAME ]] then TARGET=$g_CFILE else TARGET=$g_HFILE fi touch $TARGET CHECK=`grep "FILE\|int\|long\|float\|double\|char\|void" $TARGET | grep " $1,\| $1;\|,$1,\|,$1;\| ${1%%\[*}\[\|,${1%%\[*}\["` # Check type of var, string? if [[ "${1}" = +(*\$*) ]] then print "strncpy(__b2c__stringstack[__b2c__stackptr], $1, $g_MAX_STRING);" >> $g_CFILE print "__b2c__typestack[__b2c__stackptr] = 1;" >> $g_CFILE # Check if it is a normal string elif [[ "$1" != `print "$1" | tr -d "\042"` ]] then print "strncpy(__b2c__stringstack[__b2c__stackptr], $1, $g_MAX_STRING);" >> $g_CFILE print "__b2c__typestack[__b2c__stackptr] = 1;" >> $g_CFILE # Check if float elif [[ "$1" = +(*.*) ]] then print "__b2c__doublestack[__b2c__stackptr] = $1;" >> $g_CFILE print "__b2c__typestack[__b2c__stackptr] = 2;" >> $g_CFILE # Check if no alpha chars (then integer value) elif [[ "$1" = +(![a-zA-Z]) ]] then print "__b2c__longstack[__b2c__stackptr] = $1;" >> $g_CFILE print "__b2c__typestack[__b2c__stackptr] = 3;" >> $g_CFILE # Assume variable, check if declared before elif [[ -n $CHECK ]] then if [[ $CHECK = +(double*) ]] then print "__b2c__doublestack[__b2c__stackptr] = $1;" >> $g_CFILE print "__b2c__typestack[__b2c__stackptr] = 2;" >> $g_CFILE else print "__b2c__longstack[__b2c__stackptr] = $1;" >> $g_CFILE print "__b2c__typestack[__b2c__stackptr] = 3;" >> $g_CFILE fi # Not declared, assume integer variable else print "__b2c__longstack[__b2c__stackptr] = $1;" >> $g_CFILE print "__b2c__typestack[__b2c__stackptr] = 3;" >> $g_CFILE fi # Increase stackpointer print "__b2c__stackptr++;" >> $g_CFILE print "if(__b2c__stackptr == $g_STACK_DEPTH) __b2c__stackptr=$g_STACK_DEPTH-1;" >> $g_CFILE } #----------------------------------------------------------- function Handle_Pull { typeset CHECK TARGET # Check if we have an argument at all if [[ "$1" = "PULL" ]] then print "ERROR: empty PULL at line $g_COUNTER in file $g_CURFILE!" exit 1 fi # Argument must be a variable if [[ "$1" = +(![a-zA-Z]) ]] then print "ERROR: argument in PULL statement at line $g_COUNTER in file $g_CURFILE is not a variable!" exit 1 fi # Determine target if [[ -n $g_FUNCNAME ]] then TARGET=$g_CFILE else TARGET=$g_HFILE fi touch $TARGET # Decrease stackpointer again print "__b2c__stackptr--;" >> $g_CFILE print "if(__b2c__stackptr < 0) __b2c__stackptr=0;" >> $g_CFILE # Get the last value from stack if [[ "${1##*$}" != "$1" ]] then CHECK=`grep -i "$1\[$g_MAX_STRING\];" $TARGET` if [[ -z $CHECK ]] then print "char $1[$g_MAX_STRING];" >> $TARGET fi print "if(__b2c__typestack[__b2c__stackptr] == 1) strncpy($1, __b2c__stringstack[__b2c__stackptr], $g_MAX_STRING);" >> $g_CFILE else # Variable may not be array, these should be defined with DECLARE if [[ "$1" != +(*\[*\]*) ]] then # Not declared? Assume long CHECK=`grep "FILE\|int\|long\|float\|double\|char\|void" $TARGET | grep " $1,\| $1;\|,$1,\|,$1;\| ${1%%\[*}\[\|,${1%%\[*}\["` if [[ -z $CHECK ]] then print "long $1;" >> $TARGET fi else if [[ -z `grep -i " ${1%%\[*}\[" $TARGET` && -z `grep -i ",${1%%\[*}\[" $TARGET` ]] then print "ERROR: cannot declare implicit array in INPUT statement at $g_COUNTER in file $g_CURFILE!" exit 1 else # See how var was declared CHECK=`grep -i " ${1%%\[*}" $TARGET` if [[ -z $CHECK ]] then CHECK=`grep -i ",${1%%\[*}" $TARGET` fi fi fi # Make sure internal var is copied to var of program if [[ "$CHECK" = +(double *) ]] then print "if(__b2c__typestack[__b2c__stackptr] == 2) $1=__b2c__doublestack[__b2c__stackptr];" >> $g_CFILE else print "if(__b2c__typestack[__b2c__stackptr] == 3) $1=__b2c__longstack[__b2c__stackptr];" >> $g_CFILE fi fi } #----------------------------------------------------------- function Handle_Endsub { # Finalize sub print "}" >> $g_CFILE # Include header file print "#include \"${g_CFILE}\"" >> $g_HFILE # Reset variables g_FUNCNAME= g_ORIGFUNCNAME= g_CFILE=$g_COPY_CFILE } #----------------------------------------------------------- function Handle_Const { typeset CHECK TARGET # Check if we have an argument at all if [[ "$1" = "CONST" ]] then print "ERROR: empty CONST at line $g_COUNTER in file $g_CURFILE!" exit 1 fi # Determine target if [[ -n $g_FUNCNAME ]] then TARGET=$g_CFILE else TARGET=$g_HFILE fi touch $TARGET CHECK=`grep "FILE\|int\|long\|float\|double\|char\|void" $TARGET | grep " $1,\| $1;\|,$1,\|,$1;\| ${1%%\[*}\[\|,${1%%\[*}\["` if [[ -n $CHECK ]] then print "ERROR: variable for CONST at line $g_COUNTER in file $g_CURFILE already defined!" exit 1 fi # Check type of var, string? if [[ "${1}" = +(*\$*) ]] then print "const char ${1%%=*}[$g_MAX_STRING]=${1#*=};" >> $g_CFILE # Check if it is a normal string elif [[ "$1" != `print "$1" | tr -d "\042"` ]] then print "const char ${1%%=*}[$g_MAX_STRING]=${1#*=};" >> $g_CFILE # Check if float elif [[ "$1" = +(*.*) ]] then print "const double ${1%%=*}=${1#*=};" >> $g_CFILE # Check if no alpha chars (then integer value) elif [[ "$1" = +(![a-zA-Z]) ]] then print "const long ${1%%=*}=${1#*=};" >> $g_CFILE # Assume integer variable else print "const long ${1%%=*}=${1#*=};" >> $g_CFILE fi } #----------------------------------------------------------- function Handle_Seek { typeset FILE OFFSET WHENCE # Check if we have an argument at all if [[ "$1" = "SEEK" ]] then print "ERROR: empty SEEK at line $g_COUNTER in file $g_CURFILE!" exit 1 fi # Check if TO is available if [[ "$1" != +(* OFFSET *) ]] then if [[ "$1" != +(* offset *) ]] then print "ERROR: Missing OFFSET in SEEK statement at line $g_COUNTER in file $g_CURFILE!" exit 1 fi fi # Get the variablename without surrounding spaces if [[ "$1" = +(* OFFSET *) ]] then FILE=`print ${1%% OFFSET *}`; # Get filedescriptor OFFSET=`print ${1##* OFFSET }` else FILE=`print ${1%% offset *}`; # Get filedescriptor OFFSET=`print ${1##* offset }` fi WHENCE= # Check if WHENCE is available if [[ "$1" = +(* WHENCE *) || "$1" = +(* whence *) ]] then WHENCE=${OFFSET##* WHENCE } OFFSET=${OFFSET%% WHENCE *} if [[ -z $WHENCE ]] then WHENCE=${OFFSET##* whence } OFFSET=${OFFSET%% whence *} fi fi # Convert to C function case $WHENCE in +(START|start) ) print "fseek($FILE, $OFFSET, SEEK_SET);" >> $g_CFILE;; +(CURRENT|current) ) print "fseek($FILE, $OFFSET, SEEK_CUR);" >> $g_CFILE;; +(END|end) ) print "fseek($FILE, $OFFSET, SEEK_END);" >> $g_CFILE;; *) print "fseek($FILE, $OFFSET, SEEK_SET);" >> $g_CFILE;; esac } #----------------------------------------------------------- function Handle_Copy { typeset FROM TO # Check if we have an argument at all if [[ "$1" = "COPY" ]] then print "ERROR: empty COPY at line $g_COUNTER in file $g_CURFILE!" exit 1 fi # Check if TO is available if [[ "$1" != +(* TO *) ]] then if [[ "$1" != +(* to *) ]] then print "ERROR: Missing TO in COPY statement at line $g_COUNTER in file $g_CURFILE!" exit 1 fi fi # Get the filename and copyname if [[ "$1" = +(* TO *) ]] then FROM=`print ${1%% TO *}` TO=`print ${1##* TO }` else FROM=`print ${1%% to *}` TO=`print ${1##* to }` fi #translate to C function print "FILE *__b2c__inFile; FILE *__b2c__outFile; int __b2c__Byte = 0;" >> $g_CFILE print "__b2c__inFile = fopen($FROM, \"r\"); __b2c__outFile = fopen($TO, \"w\");" >> $g_CFILE print "if (__b2c__inFile != NULL && __b2c__outFile != NULL){while(__b2c__Byte!=EOF){" >> $g_CFILE print "__b2c__Byte=fgetc(__b2c__inFile); if(__b2c__Byte!=EOF){" >> $g_CFILE print "fputc(__b2c__Byte,__b2c__outFile); }}}" >> $g_CFILE print "fclose(__b2c__inFile); fclose(__b2c__outFile);" >> $g_CFILE } #----------------------------------------------------------- function Handle_Copymem { typeset FROM TO SIZE # Check if we have an argument at all if [[ "$1" = "COPYMEM" ]] then print "ERROR: empty COPYMEM at line $g_COUNTER in file $g_CURFILE!" exit 1 fi # Check if TO is available if [[ "$1" != +(* TO *) ]] then if [[ "$1" != +(* to *) ]] then print "ERROR: Missing TO in COPYMEM statement at line $g_COUNTER in file $g_CURFILE!" exit 1 fi fi # Get the filename and copyname if [[ "$1" = +(* TO *) ]] then FROM=`print ${1%% TO *}` TO=`print ${1##* TO }` else FROM=`print ${1%% to *}` TO=`print ${1##* to }` fi SIZE= # Check if SIZE is available if [[ "$1" = +(* SIZE *) ]] then SIZE=${TO##* SIZE } TO=${TO%% SIZE *} elif [[ "$1" = +(* size *) ]] then SIZE=${TO##* size } TO=${TO%% size *} else SIZE=1 fi #translate to C function print "__b2c__memory__check((char *)$FROM, \"COPYMEM\");" >> $g_CFILE print "__b2c__memory__check((char *)$TO, \"COPYMEM\");" >> $g_CFILE print "memcpy((void*)$TO, (void*)$FROM, $SIZE);" >> $g_CFILE } #----------------------------------------------------------- # # Simple parser to tokenize line. # # Each line should begin with a statement. # The rest of the line may contain functions, these are # converted using C macros. # #----------------------------------------------------------- function Parse_Line { typeset FOUND SYM INC COPY_COUNTER COPY_CURFILE typeset -u STATEMENT # Get statement without spaces STATEMENT=`print "${1%% *}"` case "$STATEMENT" in "PRINT") Handle_Print "${1#* }";; "INPUT") Handle_Input "${1#* }";; "FOR") Handle_For "${1#* }";; "NEXT") print "}" >> $g_CFILE;; "IF") Handle_If "${1#* }";; "ELIF") Handle_Elif "${1#* }";; "ELSE") print "} else {" >> $g_CFILE;; "ENDIF") print "}" >> $g_CFILE;; "WHILE") Handle_While "${1#* }";; "WEND") print "}" >> $g_CFILE;; "BREAK") print "break;" >> $g_CFILE;; "REPEAT") print "do{" >> $g_CFILE;; "UNTIL") # Check argument if [[ "${1%% *}" = "${1#* }" ]] then print "ERROR: empty AS at line $g_COUNTER in file $g_CURFILE!" exit 1 else print "} while(!(${1#* }));" >> $g_CFILE fi;; "LET") Handle_Let "${1#* }";; +(REM*) ) ;; "SYSTEM") # Check argument if [[ "${1%% *}" = "${1#* }" ]] then print "ERROR: empty SYSTEM at line $g_COUNTER in file $g_CURFILE!" exit 1 else print "SYSTEM (${1#* });" >> $g_CFILE fi;; "SLEEP") # Check argument if [[ "${1%% *}" = "${1#* }" ]] then print "ERROR: empty SLEEP at line $g_COUNTER in file $g_CURFILE!" exit 1 else print "usleep(${1#* }*1000);" >> $g_CFILE fi;; "OPEN") Handle_Open "${1#* }";; "CLOSE") # Check argument if [[ "${1%% *}" = "${1#* }" ]] then print "ERROR: empty CLOSE at line $g_COUNTER in file $g_CURFILE!" exit 1 else print "fclose(${1#* });" >> $g_CFILE fi;; "REWIND") # Check argument if [[ "${1%% *}" = "${1#* }" ]] then print "ERROR: empty REWIND at line $g_COUNTER in file $g_CURFILE!" exit 1 else print "rewind(${1#* });" >> $g_CFILE fi;; "SEEK") Handle_Seek "${1#* }";; "READLN") Handle_Readln "${1#* }";; "WRITELN") Handle_Writeln "${1#* }";; "GETBYTE") Handle_Getbyte "${1#* }";; "PUTBYTE") Handle_Putbyte "${1#* }";; "END") if [[ "${1#* }" = +(*IF*) ]] then print "}" >> $g_CFILE elif [[ "${1#* }" = +(*FUNCTION*) ]] then Handle_Endfunction elif [[ "${1#* }" = +(*SUB*) ]] then Handle_Endsub else print "exit(EXIT_SUCCESS);" >> $g_CFILE fi;; "SUB") # Check argument if [[ "${1%% *}" = "${1#* }" ]] then print "ERROR: empty SUB at line $g_COUNTER in file $g_CURFILE!" exit 1 else g_ORIGFUNCNAME="${1#* }" if [[ "$g_ORIGFUNCNAME" = +(*\(*\)*) ]] then g_FUNCNAME="${g_ORIGFUNCNAME%%\(*}" else g_FUNCNAME="$g_ORIGFUNCNAME" fi g_COPY_CFILE=$g_CFILE g_CFILE=${g_CFILE%.*}.$g_FUNCNAME.h if [[ "$g_ORIGFUNCNAME" = +(*\(*\)*) ]] then print "void ${g_ORIGFUNCNAME} {" > $g_CFILE else print "void ${g_FUNCNAME}(void) {" > $g_CFILE fi # Add to total filelist g_TMP_FILES="$g_TMP_FILES $g_CFILE" # Make symbol known to parser g_IMPORTED="$g_FUNCNAME $g_IMPORTED" fi;; "ENDSUB") Handle_Endsub;; "CALL") # Check argument if [[ "${1%% *}" = "${1#* }" ]] then print "ERROR: empty CALL at line $g_COUNTER in file $g_CURFILE!" exit 1 else if [[ "${1#* }" = +(*\(*\)*) ]] then print "${1#* };" >> $g_CFILE else print "${1#* }();" >> $g_CFILE fi fi;; "FUNCTION") Handle_Function "${1#* }";; "ENDFUNCTION") Handle_Endfunction;; "RETURN") Handle_Return "${1#* }";; "IMPORT") Handle_Import "${1#* }";; "DECLARE") Handle_Declare "${1#* }";; "DATA") # Check argument if [[ "${1%% *}" = "${1#* }" ]] then print "ERROR: empty DATA at line $g_COUNTER in file $g_CURFILE!" exit 1 else if [[ "${1#* }" != `print "${1#* }" | tr -d "\042"` ]] then print -r "${1#* }, " >> $STRINGARRAYFILE else # Check if float if [[ "${1#* }" = +(*.*) ]] then print -r "${1#* }, " >> $FLOATARRAYFILE else print -r "${1#* }, " >> $INTARRAYFILE fi fi fi;; "RESTORE") print "if(__b2c__intarray_ptr > 0) __b2c__intarray_ptr = 0;" >> $g_CFILE print "if(__b2c__floatarray_ptr > 0) __b2c__floatarray_ptr = 0;" >> $g_CFILE print "if(__b2c__stringarray_ptr > 0) __b2c__stringarray_ptr = 0;" >> $g_CFILE;; "READ") Handle_Read "${1#* }";; "PUSH") Handle_Push "${1#* }";; "PULL") Handle_Pull "${1#* }";; "SEED") print "srandom((unsigned int)${1#* });" >> $g_CFILE;; "DEF") if [[ "${1%% *}" = "${1#* }" ]] then print "ERROR: empty DEF FN at line $g_COUNTER in file $g_CURFILE!" exit 1 else SYM=${1#* FN} if [[ -z $SYM ]] then SYM=${1#* fn} fi print "#define ${SYM%%=*} ${SYM#*=}" >> $g_CFILE fi;; "CONST") Handle_Const "${1#* }";; "INCLUDE") # Get rid of doublequotes if they are there INC=`print ${1#* } | tr -d "\042"` # Check argument if [[ ! -f $INC || "${1%% *}" = "${1#* }" ]] then print "ERROR: missing file for INCLUDE at line $g_COUNTER in file $g_CURFILE!" exit 1 else # Start walking through program COPY_COUNTER=$g_COUNTER g_COUNTER=1 # Assign new file COPY_CURFILE=$g_CURFILE g_CURFILE=$INC while read -r LINE do # Line is not empty? if [[ -n "$LINE" ]] then Parse_Line "$LINE" fi ((g_COUNTER+=1)) done < $INC # Restore original counter g_COUNTER=$COPY_COUNTER # Restore original file g_CURFILE=$COPY_CURFILE fi;; "POKE") # Check argument if [[ "${1%% *}" = "${1#* }" ]] then print "ERROR: empty POKE at line $g_COUNTER in file $g_CURFILE!" exit 1 else # Resolve this with C macro because of casting to (char) print "POKE(${1#* });" >> $g_CFILE fi;; "COPY") Handle_Copy "${1#* }";; "DELETE") # Check argument if [[ "${1%% *}" = "${1#* }" ]] then print "ERROR: empty DELETE at line $g_COUNTER in file $g_CURFILE!" exit 1 else # Translate to C function print "unlink(${1#* });" >> $g_CFILE fi;; "FREE") # Check argument if [[ "${1%% *}" = "${1#* }" ]] then print "ERROR: empty FREE at line $g_COUNTER in file $g_CURFILE!" exit 1 else # Translate to C function print "__b2c__memory__check((char *)${1#* }, \"FREE\");" >> $g_CFILE print "free((void*)${1#* });" >> $g_CFILE fi;; "COPYMEM") Handle_Copymem "${1#* }";; "GOTO") # Check argument if [[ "${1%% *}" = "${1#* }" ]] then print "ERROR: empty GOTO at line $g_COUNTER in file $g_CURFILE!" exit 1 else # Translate to C label print "goto ${1#* };" >> $g_CFILE fi;; "LABEL") # Check argument if [[ "${1%% *}" = "${1#* }" ]] then print "ERROR: empty LABEL at line $g_COUNTER in file $g_CURFILE!" exit 1 else # Translate to C label print "${1#* }:" >> $g_CFILE fi;; *) # Check on imported symbols first FOUND=0 for SYM in $g_IMPORTED do if [[ "$1" = +($SYM*) ]] then FOUND=1 if [[ "$1" != ${1#*\(} ]] then print -r "$SYM(${1#*\(};" >> $g_CFILE else print -r "$SYM();" >> $g_CFILE fi fi done # Not an imported symbol? Check if assignment if [[ $FOUND -eq 0 ]] then Handle_Let "$1" fi;; esac } #----------------------------------------------------------- # # Main program # #----------------------------------------------------------- # Default BACON settings let g_MAX_STRING=256 let g_NO_COMPILE=0 let g_STACK_DEPTH=8 let g_TMP_PRESERVE=0 g_TEMPDIR=. g_CCNAME=gcc CCFLAGS= # Some global declarations g_CURFILE= g_FUNCNAME= g_FUNCTYPE= g_TMP_FILES= # Get arguments while getopts ":m:c:s:d:wgnpv" OPT do case $OPT in m) g_MAX_STRING=$OPTARG;; c) g_CCNAME=$OPTARG;; s) g_STACK_DEPTH=$OPTARG;; d) g_TEMPDIR=$OPTARG;; n) g_NO_COMPILE=1;; g) CCFLAGS="$CCFLAGS -g";; w) CCFLAGS="$CCFLAGS -Wall";; p) let g_TMP_PRESERVE=1;; v) print print "BACON version $g_VERSION - (c) Peter van Eerten - GPL." print exit 0;; \?) print print "USAGE: bacon [options] program[.bac]" print print "OPTIONS:" print print " -m \tMax string length (default: 256)" print " -c \tCompiler to use (default: gcc)" print " -s \tDepth of stack (default: 8)" print " -d \tTemporary directory (default: .)" print " -n \t\tDo not compile automatically" print " -p \t\tPreserve temporary files" print " -g \t\tCompile with debug info" print " -w \t\tCompile with all warnings" print " -v \t\tShow version" print exit 0;; esac done shift $(($OPTIND-1)) # Check if a filename was entered, if so get it if [[ $# -eq 0 ]] then print "ERROR: no filename? Run with '-?' to see usage." exit 1 elif [[ "$@" != +(*.bac) ]] then SOURCEFILE="$@.bac" else SOURCEFILE="$@" fi # Check if file exists if [[ ! -f $SOURCEFILE ]] then print "ERROR: file not found!" exit 1 fi print -n "Starting conversion... " # Now create the global filenames where to write to g_CFILE=$g_TEMPDIR/${SOURCEFILE%.*}.c g_HFILE=$g_TEMPDIR/${SOURCEFILE%.*}.h STRINGARRAYFILE=$g_TEMPDIR/${SOURCEFILE%.*}.string INTARRAYFILE=$g_TEMPDIR/${SOURCEFILE%.*}.int FLOATARRAYFILE=$g_TEMPDIR/${SOURCEFILE%.*}.float # Add to total file list g_TMP_FILES="$g_CFILE $g_HFILE $STRINGARRAYFILE $INTARRAYFILE $FLOATARRAYFILE" # Create basic C file print "/* Created with BACON - PvE 2009 */" > $g_CFILE print "#include \"$g_HFILE\"" >> $g_CFILE print "int main(int argc, const char **argv)" >> $g_CFILE print "{" >> $g_CFILE print "memset(__b2c__stringbuffer, 0, $g_MAX_STRING*$g_MAX_DEPTH);" >> $g_CFILE # Put arguments into reserved variable ARGUMENT print "/* Setup the reserved variable 'ARGUMENT' */" >> $g_CFILE print "for(__b2c__counter=1; __b2c__counter < argc; __b2c__counter++)" >> $g_CFILE print "{strncat(ARGUMENT\$, argv[__b2c__counter], $g_MAX_STRING); if(__b2c__counter != argc - 1) strcat(ARGUMENT\$, \" \");" >> $g_CFILE print "strncat(argument\$, argv[__b2c__counter], $g_MAX_STRING); if(__b2c__counter != argc - 1) strcat(argument\$, \" \");}" >> $g_CFILE print "/* Rest of the program */" >> $g_CFILE # Create basic H file, functions are converted using macros print "/* Created with BACON - PvE 2009 */" > $g_HFILE print >> $g_HFILE print "#include " >> $g_HFILE print "#include " >> $g_HFILE print >> $g_HFILE print "/* Math functions */" >> $g_HFILE print "#include " >> $g_HFILE print "#define sqr(x) sqrt(x)" >> $g_HFILE print "#define SQR(x) sqrt(x)" >> $g_HFILE print "#define POW(x, y) pow(x, y)" >> $g_HFILE print "#define SIN(x) sin(x)" >> $g_HFILE print "#define COS(x) cos(x)" >> $g_HFILE print "#define TAN(x) tan(x)" >> $g_HFILE print "#define round(x) lrint(x)" >> $g_HFILE print "#define ROUND(x) lrint(x)" >> $g_HFILE print "#define mod(x,y) (x%y)" >> $g_HFILE print "#define MOD(x,y) (x%y)" >> $g_HFILE print "#define EVEN(x) ((x%2 == 0) ? 1 : 0)" >> $g_HFILE print "#define ODD(x) ((x%2 != 0) ? 1 : 0)" >> $g_HFILE print "#define FLOOR(x) floor(x)" >> $g_HFILE print "#define rnd random()" >> $g_HFILE print "#define RND random()" >> $g_HFILE print "#define maxrandom RAND_MAX" >> $g_HFILE print "#define MAXRANDOM RAND_MAX" >> $g_HFILE print >> $g_HFILE print "/* Other functions */" >> $g_HFILE print "#include " >> $g_HFILE print "#define val(x) ((x != NULL) ? atol(x) : 0)" >> $g_HFILE print "#define VAL(x) ((x != NULL) ? atol(x) : 0)" >> $g_HFILE print >> $g_HFILE print "/* Unix functions */" >> $g_HFILE print "#include " >> $g_HFILE print "#define SYSTEM(x) ((x != NULL) ? system(x) : 0)" >> $g_HFILE print >> $g_HFILE print "/* String functions */" >> $g_HFILE print "#include " >> $g_HFILE print "char __b2c__input__buffer[$g_MAX_STRING];" >> $g_HFILE print "char __b2c__stringbuffer[$g_MAX_STRING*$g_MAX_DEPTH];" >> $g_HFILE print "int __b2c__stringbuffer_ptr = 0;" >> $g_HFILE print "char* __b2c__strncpy(char *__b2c__dest, const char *__b2c__src, size_t __b2c__n){" >> $g_HFILE print "size_t __b2c__i; memset(__b2c__dest, 0, $g_MAX_STRING); for (__b2c__i = 0; __b2c__i < __b2c__n && __b2c__src[__b2c__i] != '\\\\0';" >> $g_HFILE print "__b2c__i++) __b2c__dest[__b2c__i] = __b2c__src[__b2c__i]; __b2c__dest[__b2c__i] = '\\\\0'; __b2c__stringbuffer_ptr+=$g_MAX_STRING;" >> $g_HFILE print "if(__b2c__stringbuffer_ptr >= $g_MAX_STRING*$g_MAX_DEPTH) __b2c__stringbuffer_ptr = 0; return __b2c__dest;}" >> $g_HFILE print "char* __b2c__reverse(char *__b2c__s){int __b2c__i; char *__b2c__tmp; __b2c__tmp = __b2c__stringbuffer + __b2c__stringbuffer_ptr; memset(__b2c__tmp, 0, $g_MAX_STRING);" >> $g_HFILE print "for(__b2c__i=0;__b2c__i> $g_HFILE print "if(__b2c__stringbuffer_ptr >= $g_MAX_STRING*$g_MAX_DEPTH) __b2c__stringbuffer_ptr = 0;" >> $g_HFILE print "return(__b2c__tmp);}" >> $g_HFILE print "#define reverse\$(x) ((x != NULL) ? __b2c__reverse(x) : \"null\")" >> $g_HFILE print "#define REVERSE\$(x) ((x != NULL) ? __b2c__reverse(x) : \"null\")" >> $g_HFILE print "char* __b2c__str(double d){char *__b2c__tmp; __b2c__tmp = __b2c__stringbuffer + __b2c__stringbuffer_ptr;" >> $g_HFILE print "memset(__b2c__tmp, 0, $g_MAX_STRING); snprintf(__b2c__tmp, $g_MAX_STRING, \"%g\", d); __b2c__stringbuffer_ptr+=$g_MAX_STRING;" >> $g_HFILE print "if(__b2c__stringbuffer_ptr >= $g_MAX_STRING*$g_MAX_DEPTH) __b2c__stringbuffer_ptr = 0;return(__b2c__tmp);}" >> $g_HFILE print "#define str\$(x) __b2c__str(x)" >> $g_HFILE print "#define STR\$(x) __b2c__str(x)" >> $g_HFILE print "char* __b2c__concat(char *__b2c__first, ...){ char *__b2c__tmp; char *__b2c__retbuffer; va_list __b2c__ap;" >> $g_HFILE print " __b2c__retbuffer = __b2c__stringbuffer + __b2c__stringbuffer_ptr; if(__b2c__first == NULL) return (\"null\");" >> $g_HFILE print "(void)__b2c__strncpy(__b2c__retbuffer, __b2c__first, $g_MAX_STRING); va_start(__b2c__ap, __b2c__first);" >> $g_HFILE print "while((__b2c__tmp = va_arg(__b2c__ap, char *)) != NULL) (void)strncat(__b2c__retbuffer, __b2c__tmp, $g_MAX_STRING);" >> $g_HFILE print "va_end(__b2c__ap); return(__b2c__retbuffer);}" >> $g_HFILE print "#define concat\$(...) __b2c__concat(__VA_ARGS__, (char*)NULL)" >> $g_HFILE print "#define CONCAT\$(...) __b2c__concat(__VA_ARGS__, (char*)NULL)" >> $g_HFILE print "#define left\$(__b2c__x, __b2c__y) ((__b2c__x != NULL && __b2c__y < strlen(__b2c__x) && __b2c__y >= 0) ? __b2c__strncpy(__b2c__stringbuffer + __b2c__stringbuffer_ptr, __b2c__x, (__b2c__y)) : __b2c__x)" >> $g_HFILE print "#define LEFT\$(__b2c__x, __b2c__y) ((__b2c__x != NULL && __b2c__y < strlen(__b2c__x) && __b2c__y >= 0) ? __b2c__strncpy(__b2c__stringbuffer + __b2c__stringbuffer_ptr, __b2c__x, (__b2c__y)) : __b2c__x)" >> $g_HFILE print "#define right\$(__b2c__x, __b2c__y) ((__b2c__x != NULL && __b2c__y < strlen(__b2c__x) && __b2c__y >= 0) ? __b2c__strncpy(__b2c__stringbuffer + __b2c__stringbuffer_ptr, __b2c__x+strlen(__b2c__x)-(int)(__b2c__y), (__b2c__y)) : \"\")" >> $g_HFILE print "#define RIGHT\$(__b2c__x, __b2c__y) ((__b2c__x != NULL && __b2c__y < strlen(__b2c__x) && __b2c__y >= 0) ? __b2c__strncpy(__b2c__stringbuffer + __b2c__stringbuffer_ptr, __b2c__x+strlen(__b2c__x)-(int)(__b2c__y), (__b2c__y)) : \"\")" >> $g_HFILE print "#define mid\$(__b2c__x, __b2c__y, z) ((__b2c__x != NULL && __b2c__y <= strlen(__b2c__x) && __b2c__y > 0) ? __b2c__strncpy(__b2c__stringbuffer + __b2c__stringbuffer_ptr, __b2c__x+(int)(__b2c__y)-1, (z)) : \"\")" >> $g_HFILE print "#define MID\$(__b2c__x, __b2c__y, z) ((__b2c__x != NULL && __b2c__y <= strlen(__b2c__x) && __b2c__y > 0) ? __b2c__strncpy(__b2c__stringbuffer + __b2c__stringbuffer_ptr, __b2c__x+(int)(__b2c__y)-1, (z)) : \"\")" >> $g_HFILE print "long __b2c__instr (char *__b2c__x, char *__b2c__y, int z){char* __b2c__tmp;" >> $g_HFILE print "__b2c__tmp = strstr(__b2c__x+z-1, __b2c__y); if(__b2c__tmp == NULL) return (0); return (__b2c__tmp - __b2c__x + 1);}" >> $g_HFILE print "#define instr(__b2c__x, __b2c__y, z) ((__b2c__x != NULL && __b2c__y != NULL && strstr(__b2c__x, __b2c__y) != NULL && z > 0 && z <= strlen(__b2c__x)) ? __b2c__instr(__b2c__x, __b2c__y, z) : 0)" >> $g_HFILE print "#define INSTR(__b2c__x, __b2c__y, z) ((__b2c__x != NULL && __b2c__y != NULL && strstr(__b2c__x, __b2c__y) != NULL && z > 0 && z <= strlen(__b2c__x)) ? __b2c__instr(__b2c__x, __b2c__y, z) : 0)" >> $g_HFILE print "#define len(x) ((x != NULL) ? strlen(x) : 0)" >> $g_HFILE print "#define LEN(x) ((x != NULL) ? strlen(x) : 0)" >> $g_HFILE print "#define equal(__b2c__x, __b2c__y) ((__b2c__x != NULL && __b2c__y != NULL) ? !strncmp(__b2c__x, __b2c__y, $g_MAX_STRING) : 0)" >> $g_HFILE print "#define EQUAL(__b2c__x, __b2c__y) ((__b2c__x != NULL && __b2c__y != NULL) ? !strncmp(__b2c__x, __b2c__y, $g_MAX_STRING) : 0)" >> $g_HFILE print "#define getenviron\$(x) ((x != NULL) ? getenv(x) : \"null\")" >> $g_HFILE print "#define GETENVIRON\$(x) ((x != NULL) ? getenv(x) : \"null\")" >> $g_HFILE print >> $g_HFILE print "/* CHAR functions */" >> $g_HFILE print "#include " >> $g_HFILE print "char* __b2c__ucase(char *s){int __b2c__i; char *__b2c__tmp; __b2c__tmp = __b2c__stringbuffer + __b2c__stringbuffer_ptr; memset(__b2c__tmp, 0, $g_MAX_STRING);" >> $g_HFILE print "for(__b2c__i=0; __b2c__i < strlen(s); __b2c__i++){__b2c__tmp[__b2c__i]=toupper(s[__b2c__i]);} __b2c__stringbuffer_ptr+=$g_MAX_STRING;" >> $g_HFILE print "if(__b2c__stringbuffer_ptr >= $g_MAX_STRING*$g_MAX_DEPTH) __b2c__stringbuffer_ptr = 0;" >> $g_HFILE print "return(__b2c__tmp);}" >> $g_HFILE print "#define ucase\$(x) ((x != NULL) ? __b2c__ucase(x) : \"null\")" >> $g_HFILE print "#define UCASE\$(x) ((x != NULL) ? __b2c__ucase(x) : \"null\")" >> $g_HFILE print "char* __b2c__lcase(char *__b2c__s){int __b2c__i; char *__b2c__tmp; __b2c__tmp = __b2c__stringbuffer + __b2c__stringbuffer_ptr; memset(__b2c__tmp, 0, $g_MAX_STRING);" >> $g_HFILE print "for(__b2c__i=0; __b2c__i < strlen(__b2c__s); __b2c__i++){__b2c__tmp[__b2c__i]=tolower(__b2c__s[__b2c__i]);} __b2c__stringbuffer_ptr+=$g_MAX_STRING;" >> $g_HFILE print "if(__b2c__stringbuffer_ptr >= $g_MAX_STRING*$g_MAX_DEPTH) __b2c__stringbuffer_ptr = 0;" >> $g_HFILE print "return(__b2c__tmp);}" >> $g_HFILE print "#define lcase\$(x) ((x != NULL) ? __b2c__lcase(x) : \"null\")" >> $g_HFILE print "#define LCASE\$(x) ((x != NULL) ? __b2c__lcase(x) : \"null\")" >> $g_HFILE print >> $g_HFILE print "/* I/O functions */" >> $g_HFILE print "char* __b2c__dec2hex(int __b2c__i){char *__b2c__tmp; __b2c__tmp=__b2c__stringbuffer + __b2c__stringbuffer_ptr;" >> $g_HFILE print "memset(__b2c__tmp, 0, $g_MAX_STRING); snprintf(__b2c__tmp, $g_MAX_STRING, \"%X\", __b2c__i); __b2c__stringbuffer_ptr+=$g_MAX_STRING;" >> $g_HFILE print "if(__b2c__stringbuffer_ptr >= $g_MAX_STRING*$g_MAX_DEPTH) __b2c__stringbuffer_ptr = 0; return(__b2c__tmp);}" >> $g_HFILE print "long __b2c__hex2dec(char *__b2c__h){int __b2c__i; if(sscanf(__b2c__h, \"%X\", &__b2c__i) == EOF){" >> $g_HFILE print "fprintf(stderr, \"ERROR: wrong value in DEC!\\\\n\"); exit(EXIT_FAILURE);}; return(long)(__b2c__i);}" >> $g_HFILE print "unsigned char __b2c__char2asc(char *__b2c__c){return (unsigned char)*__b2c__c;}" >> $g_HFILE print "char* __b2c__asc2char(int __b2c__i){char *__b2c__tmp; __b2c__tmp=__b2c__stringbuffer + __b2c__stringbuffer_ptr;" >> $g_HFILE print "memset(__b2c__tmp, 0, $g_MAX_STRING); sprintf(__b2c__tmp, \"%c\", __b2c__i); __b2c__stringbuffer_ptr+=$g_MAX_STRING;" >> $g_HFILE print "if(__b2c__stringbuffer_ptr >= $g_MAX_STRING*$g_MAX_DEPTH) __b2c__stringbuffer_ptr = 0; return(__b2c__tmp);}" >> $g_HFILE print "#define endfile(x) feof(x)" >> $g_HFILE print "#define ENDFILE(x) feof(x)" >> $g_HFILE print "#define tell(x) ftell(x)" >> $g_HFILE print "#define TELL(x) ftell(x)" >> $g_HFILE print "#define hex\$(x) __b2c__dec2hex(x)" >> $g_HFILE print "#define HEX\$(x) __b2c__dec2hex(x)" >> $g_HFILE print "#define dec(x) __b2c__hex2dec(x)" >> $g_HFILE print "#define DEC(x) __b2c__hex2dec(x)" >> $g_HFILE print "#define asc(x) __b2c__char2asc(x)" >> $g_HFILE print "#define ASC(x) __b2c__char2asc(x)" >> $g_HFILE print "#define chr\$(__b2c__x) ((__b2c__x < 256 && __b2c__x >= 0) ? __b2c__asc2char(__b2c__x) : \"\")" >> $g_HFILE print "#define CHR\$(__b2c__x) ((__b2c__x < 256 && __b2c__x >= 0) ? __b2c__asc2char(__b2c__x) : \"\")" >> $g_HFILE print >> $g_HFILE print "/* Dynamic loading, errors */" >> $g_HFILE print "#include " >> $g_HFILE print "#include " >> $g_HFILE print >> $g_HFILE print "/* GETKEY */" >> $g_HFILE print "#include " >> $g_HFILE print "long __b2c__getch(){long __b2c__ch; struct termios __b2c__oldt, __b2c__newt; tcgetattr(0, &__b2c__oldt);" >> $g_HFILE print "__b2c__newt = __b2c__oldt; __b2c__newt.c_lflag &= ~(ICANON | ECHO); tcsetattr(0, TCSANOW, &__b2c__newt);" >> $g_HFILE print "__b2c__ch = getchar(); tcsetattr(0, TCSANOW, &__b2c__oldt); return __b2c__ch;} " >> $g_HFILE print "#define getkey __b2c__getch()" >> $g_HFILE print "#define GETKEY __b2c__getch()" >> $g_HFILE print >> $g_HFILE print "/* Constants, logical stuff */" >> $g_HFILE print "#define pi 3.14159265" >> $g_HFILE print "#define PI 3.14159265" >> $g_HFILE print "#define not(x) (!(x))" >> $g_HFILE print "#define NOT(x) (!(x))" >> $g_HFILE print "#define and &&" >> $g_HFILE print "#define AND &&" >> $g_HFILE print "#define or ||" >> $g_HFILE print "#define OR ||" >> $g_HFILE print "#define eq ==" >> $g_HFILE print "#define EQ ==" >> $g_HFILE print "#define true 1" >> $g_HFILE print "#define TRUE 1" >> $g_HFILE print "#define false 0" >> $g_HFILE print "#define FALSE 0" >> $g_HFILE print "#define string char*" >> $g_HFILE print "#define STRING char*" >> $g_HFILE print "#define integer long" >> $g_HFILE print "#define INTEGER long" >> $g_HFILE print "#define floating double" >> $g_HFILE print "#define FLOATING double" >> $g_HFILE print "#define ISTRUE(x) (x!=0)" >> $g_HFILE print "#define ISFALSE(x) (x==0)" >> $g_HFILE print >> $g_HFILE print "/* Date and time */" >> $g_HFILE print "#include " >> $g_HFILE print "#define now (long)time(NULL)" >> $g_HFILE print "#define NOW (long)time(NULL)" >> $g_HFILE print "long __b2c__time(long __b2c__now, int __b2c__which){struct tm *ts; char *__b2c__tmp; __b2c__tmp=__b2c__stringbuffer + __b2c__stringbuffer_ptr;" >> $g_HFILE print "memset(__b2c__tmp, 0, $g_MAX_STRING); ts = localtime(&__b2c__now); switch(__b2c__which) { case 1: strftime(__b2c__tmp, $g_MAX_STRING, \"%d\", ts); break;" >> $g_HFILE print "case 2: strftime(__b2c__tmp, $g_MAX_STRING, \"%m\", ts); break; case 3: strftime(__b2c__tmp, $g_MAX_STRING, \"%Y\", ts); break;" >> $g_HFILE print "case 4: strftime(__b2c__tmp, $g_MAX_STRING, \"%H\", ts); break; case 5: strftime(__b2c__tmp, $g_MAX_STRING, \"%M\", ts); break;" >> $g_HFILE print "case 6: strftime(__b2c__tmp, $g_MAX_STRING, \"%S\", ts); break; case 7: strftime(__b2c__tmp, $g_MAX_STRING, \"%W\", ts); break;} __b2c__stringbuffer_ptr+=$g_MAX_STRING;" >> $g_HFILE print "if(__b2c__stringbuffer_ptr >= $g_MAX_STRING*$g_MAX_DEPTH) __b2c__stringbuffer_ptr = 0; return(atol(__b2c__tmp));}" >> $g_HFILE print "#define day(x) __b2c__time(x, 1)" >> $g_HFILE print "#define DAY(x) __b2c__time(x, 1)" >> $g_HFILE print "#define month(x) __b2c__time(x, 2)" >> $g_HFILE print "#define MONTH(x) __b2c__time(x, 2)" >> $g_HFILE print "#define year(x) __b2c__time(x, 3)" >> $g_HFILE print "#define YEAR(x) __b2c__time(x, 3)" >> $g_HFILE print "#define hour(x) __b2c__time(x, 4)" >> $g_HFILE print "#define HOUR(x) __b2c__time(x, 4)" >> $g_HFILE print "#define minute(x) __b2c__time(x, 5)" >> $g_HFILE print "#define MINUTE(x) __b2c__time(x, 5)" >> $g_HFILE print "#define second(x) __b2c__time(x, 6)" >> $g_HFILE print "#define SECOND(x) __b2c__time(x, 6)" >> $g_HFILE print "#define week(x) __b2c__time(x, 7)" >> $g_HFILE print "#define WEEK(x) __b2c__time(x, 7)" >> $g_HFILE print "char * __b2c__datename(long __b2c__now, int __b2c__which){struct tm *ts; char *__b2c__tmp; __b2c__tmp=__b2c__stringbuffer + __b2c__stringbuffer_ptr;" >> $g_HFILE print "memset(__b2c__tmp, 0, $g_MAX_STRING); ts = localtime(&__b2c__now); switch(__b2c__which){case 1: strftime(__b2c__tmp, $g_MAX_STRING, \"%A\", ts); break;" >> $g_HFILE print "case 2: strftime(__b2c__tmp, $g_MAX_STRING, \"%B\", ts); break;} __b2c__stringbuffer_ptr+=$g_MAX_STRING;" >> $g_HFILE print "if(__b2c__stringbuffer_ptr >= $g_MAX_STRING*$g_MAX_DEPTH) __b2c__stringbuffer_ptr = 0; return(__b2c__tmp);}" >> $g_HFILE print "#define weekday\$(x) __b2c__datename(x, 1)" >> $g_HFILE print "#define WEEKDAY\$(x) __b2c__datename(x, 1)" >> $g_HFILE print "#define month\$(x) __b2c__datename(x, 2)" >> $g_HFILE print "#define MONTH\$(x) __b2c__datename(x, 2)" >> $g_HFILE print "unsigned long __b2c__epoch(int __b2c__year, int __b2c__month, int __b2c__day, int __b2c__hour, int __b2c__minute, int __b2c__second){" >> $g_HFILE print "struct tm tm; time_t __b2c__t; tm.tm_year = __b2c__year - 1900; tm.tm_mon = __b2c__month - 1; tm.tm_mday = __b2c__day;" >> $g_HFILE print "tm.tm_hour = __b2c__hour; tm.tm_min = __b2c__minute; tm.tm_sec = __b2c__second;" >> $g_HFILE print "tm.tm_isdst = -1; __b2c__t = mktime(&tm); if (__b2c__t == -1) return (0); return(long) __b2c__t; }" >> $g_HFILE print "#define timeval(x,y,z,a,b,c) __b2c__epoch(x,y,z,a,b,c)" >> $g_HFILE print "#define TIMEVAL(x,y,z,a,b,c) __b2c__epoch(x,y,z,a,b,c)" >> $g_HFILE print >> $g_HFILE print "/* Peek and Poke */" >> $g_HFILE print "#include " >> $g_HFILE print "void __b2c__memory__check(char* __b2c__x, char *__b2c__com) {struct stat __b2c__sb; if (stat(__b2c__x, &__b2c__sb) == -1 && errno == EFAULT) {" >> $g_HFILE print "fprintf(stderr, \"ERROR: Trying to access illegal memory with %s at line %d!\\\\n\", __b2c__com, __LINE__); exit(EXIT_FAILURE);} }" >> $g_HFILE print "void __b2c__poke(char* __b2c__x, long __b2c__y) {__b2c__memory__check(__b2c__x, \"POKE\"); memset(__b2c__x, __b2c__y, sizeof(char));}" >> $g_HFILE print "#define poke(__b2c__x, __b2c__y) __b2c__poke((char*)__b2c__x, __b2c__y)" >> $g_HFILE print "#define POKE(__b2c__x, __b2c__y) __b2c__poke((char*)__b2c__x, __b2c__y)" >> $g_HFILE print "#define memory(__b2c__x) (long)malloc(sizeof(char)*__b2c__x);" >> $g_HFILE print "#define MEMORY(__b2c__x) (long)malloc(sizeof(char)*__b2c__x);" >> $g_HFILE print "long __b2c__peek(char* __b2c__x) {__b2c__memory__check(__b2c__x, \"PEEK\"); return(*__b2c__x);}" >> $g_HFILE print "#define peek(__b2c__x) __b2c__peek((char*)__b2c__x)" >> $g_HFILE print "#define PEEK(__b2c__x) __b2c__peek((char*)__b2c__x)" >> $g_HFILE print >> $g_HFILE print "/* Declare reserved variable 'ARGUMENT\$' */" >> $g_HFILE print "int __b2c__counter;" >> $g_HFILE print "char argument\$[$g_MAX_STRING];" >> $g_HFILE print "char ARGUMENT\$[$g_MAX_STRING];" >> $g_HFILE print >> $g_HFILE print "/* Initialize stack arrays and pointer */" >> $g_HFILE print "char __b2c__stringstack[$g_STACK_DEPTH][$g_MAX_STRING];" >> $g_HFILE print "double __b2c__doublestack[$g_STACK_DEPTH];" >> $g_HFILE print "long __b2c__longstack[$g_STACK_DEPTH];" >> $g_HFILE print "int __b2c__typestack[$g_STACK_DEPTH];" >> $g_HFILE print "int __b2c__stackptr;" >> $g_HFILE print >> $g_HFILE print "/* User program definitions */" >> $g_HFILE # Initialize the arrayfiles print "char __b2c__stringarray[][$g_MAX_STRING] = {" > $STRINGARRAYFILE print "int __b2c__intarray[] = {" > $INTARRAYFILE print "double __b2c__floatarray[] = {" > $FLOATARRAYFILE # There are no imported symbols yet g_IMPORTED= # This is the current file we are parsing g_CURFILE=$SOURCEFILE # Start walking through program g_COUNTER=1 while read -r LINE do # Line is not empty? if [[ -n "$LINE" ]] then Parse_Line "$LINE" fi ((g_COUNTER+=1)) done < $SOURCEFILE # Finalize main C-file print "return 0;" >> $g_CFILE print "}" >> $g_CFILE # Finalize INT ARRAY file for DATA print " \"\" };" >> $STRINGARRAYFILE print >> $g_HFILE print "/* DATA definitions (string) */" >> $g_HFILE cat $STRINGARRAYFILE >> $g_HFILE print "int __b2c__stringarray_ptr = 0;" >> $g_HFILE # Finalize STRING ARRAY file for DATA print " 0};" >> $INTARRAYFILE print >> $g_HFILE print "/* DATA definitions (long) */" >> $g_HFILE cat $INTARRAYFILE >> $g_HFILE print "int __b2c__intarray_ptr = 0;" >> $g_HFILE # Finalize FLOAT ARRAY file for DATA print " 0.0};" >> $FLOATARRAYFILE print >> $g_HFILE print "/* DATA definitions (double) */" >> $g_HFILE cat $FLOATARRAYFILE >> $g_HFILE print "int __b2c__floatarray_ptr = 0;" >> $g_HFILE print "done." # Start indentation if [[ -n `which indent` ]] then print -n "Applying indentation... " for i in $g_TMP_FILES do indent $i rm $i~ done print "done." fi # Start compilation if [[ $g_NO_COMPILE -eq 0 ]] then print -n "Starting compilation... " $g_CCNAME $CCFLAGS -o ${SOURCEFILE%.*} $g_CFILE $g_LDFLAGS > $g_TEMPDIR/${SOURCEFILE%.*}.log 2>&1 g_TMP_FILES="$g_TMP_FILES $g_TEMPDIR/${SOURCEFILE%.*}.log" if [[ -z `cat $g_TEMPDIR/${SOURCEFILE%.*}.log` ]] then print "done." print "Program '${SOURCEFILE%.*}' ready." else cat $g_TEMPDIR/${SOURCEFILE%.*}.log fi fi # Cleanup if [[ $g_TMP_PRESERVE -eq 0 ]] then for i in $g_TMP_FILES do rm $i done fi exit 0