Write bf2c and add a little optimisation

This commit is contained in:
Melon 2021-04-18 22:13:13 +01:00
commit 33ae2d9598
5 changed files with 176 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
dist/
package/

27
Makefile Normal file
View File

@ -0,0 +1,27 @@
sourcefiles := $(shell find src/ -name *.c)
all:
make build-main
build-main:
mkdir -p dist/ && \
gcc -o dist/bf2c ${sourcefiles}
package:
./scripts/package-bf2c.sh
deb:
make clean && \
make all && \
make package
clean:
rm -rf dist/ && \
rm -rf package/
.PHONY: run
run:
cd ./dist/ && \
./bf2c

9
project.json Normal file
View File

@ -0,0 +1,9 @@
{
"Package": "bf2c",
"Version": "1.0-1",
"Section": "base",
"Priority": "optional",
"Architecture": "amd64",
"Maintainer": "MrMelon54 <github@onpointcoding.net>",
"Description": "bf2c - convert brainfuck to c"
}

43
scripts/package-bf2c.sh Executable file
View File

@ -0,0 +1,43 @@
#!/bin/bash
SCRIPT=$(readlink -f $0)
SCRIPTPATH=`dirname $SCRIPT`
PROJECT_DIR=`dirname $SCRIPTPATH`
PROJECT_DAT=`cat $PROJECT_DIR/project.json`
PROJECT_NAM=`echo $PROJECT_DAT | jq .Package -r`
PROJECT_VER=`echo $PROJECT_DAT | jq .Version -r`
echo
echo "Packaging $PROJECT_NAM v$PROJECT_VER"
echo
INSTALL_DIR="/usr/bin"
INSTALL_DIR=$(realpath -sm "$INSTALL_DIR")
echo "Using the following folders for install"
echo "PROJECT_DIR: $PROJECT_DIR"
echo "INSTALL_DIR: $INSTALL_DIR"
PACK="${PROJECT_DIR}/package/${PROJECT_NAM}_${PROJECT_VER}"
PACK_BIN=$(realpath -sm "$PACK/$INSTALL_DIR")
PACK_DEB=$(realpath -sm "$PACK/DEBIAN")
mkdir -p "$PACK"
mkdir -p "$PACK_BIN"
mkdir -p "$PACK_DEB"
# Copying files
echo "Copying binary files"
cp dist/bf2c "$PACK_BIN"
echo "Generating meta data"
PACK_CON=$(realpath -sm "$PACK_DEB/control")
echo "" > "$PACK_CON"
for row in $(echo "$PROJECT_DAT" | jq -r 'keys[]'); do
value=`echo "$PROJECT_DAT" | jq -r ".[\"$row\"]"`
echo "$row: $value" >> "$PACK_CON"
done
echo "Building package"
dpkg-deb --build "$PACK"
echo "Signing package"
dpkg-sig -k OnPointCoding --sign repo "$PACK.deb"
echo "Package complete:"

95
src/main.c Normal file
View File

@ -0,0 +1,95 @@
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
int is_arg(int ac, char **argv, char *arg) {
if (ac < 2) {
return 0;
}
for(int x=1; x < ac; x++) {
if (0 == strcmp(argv[x], arg)) {
return x; // return position of arg
}
}
return 0; // arg not present
}
void addValueChange(FILE *out, char *variable, bool increment, int value) {
if(increment) {
if(value==1) fprintf(out, "++%s;", variable);
else fprintf(out, "%s+=%d;", variable, value);
} else {
if(value==1) fprintf(out, "--%s;", variable);
else fprintf(out, "%s-=%d;", variable);
}
}
int main(int argc, char **argv)
{
FILE *in = stdin, *out = stdout;
int a;
int b;
int c;
int cellsize = 30000;
bool optimise = false;
if(is_arg(argc, argv, "-o")) optimise = true;
fprintf(out,
"#include <stdio.h>\n"
"#include <stdlib.h>\n\n"
"int main(int argc, char **argv) {\n"
"unsigned char *cell = calloc(%d, 1);\n"
"unsigned char *cells = cell;\n"
"if (!cell) {\n"
"fprintf(stderr, \"Error allocating memory.\\n\");\n"
"return 1;\n"
"}\n\n", cellsize
);
a=1;
while (b!=EOF) {
c = getc(in);
switch (c) {
case '>':
case '<':
case '+':
case '-':
case '.':
case ',':
case '[':
case ']':
case EOF:
if (c!=EOF && b==c && optimise) a++;
else {
switch (b) {
case '>': addValueChange(out, "cell", true, a); break;
case '<': addValueChange(out, "cell", false, a); break;
case '+': addValueChange(out, "*cell", true, a); break;
case '-': addValueChange(out, "*cell", false, a); break;
case '.':
for (int i = 0; i < a; i++) fprintf(out, "putchar(*cell);\n");
break;
case ',':
for (int i = 0; i < a; i++) fprintf(out, "*cell = getchar();\n");
break;
case '[':
for (int i = 0; i < a; i++) fprintf(out, "while (*cell) {\n");
break;
case ']':
for (int i = 0; i < a; i++) fprintf(out, "}\n");
break;
default: break;
}
// Reset for next loop
a=1;
b = c;
}
break;
}
}
fprintf(out, "\nfree(cells);\nreturn 0;\n}\n");
}