cake
/
libg1m
Archived
1
0
Fork 0

Added FONTCHARACTER tools and Basic instruction decoding draft

This commit is contained in:
Thomas Touhey 2017-01-09 16:27:41 +01:00
parent 8933be944c
commit 4a809826a4
13 changed files with 373 additions and 13 deletions

2
.gitignore vendored
View File

@ -3,3 +3,5 @@
/libg1m.so*
/libg1m.dll
/man
.*.swp

6
.gitmodules vendored Normal file
View File

@ -0,0 +1,6 @@
[submodule "tools/fontcharacter"]
path = tools/fontcharacter
url = https://forge.touhey.fr/casio/python3-modules/fontcharacter
[submodule "tools/fontcharacter_reference"]
path = tools/fontcharacter_reference
url = https://forge.touhey.fr/casio/casiowin/fontcharacter_reference

View File

@ -4,6 +4,9 @@
#******************************************************************************#
include Makefile.vars Makefile.msg
# Check if we're a git repository
ISGIT := $(shell test -e .git && echo y)
#******************************************************************************#
# General targets #
#******************************************************************************#
@ -22,6 +25,7 @@ clean: clean-lib clean-doc
mrproper: clean
$(call rmsg,Removing configuration.)
$(call qcmd,$(RM) Makefile.cfg)
$(call qcmd,$(RM) -r lib$(NAME)-*)
# Remake everything. (clean and build)
re: clean all
@ -37,7 +41,7 @@ uninstall: uninstall-lib uninstall-doc uninstall-cfgtool
reinstall: uninstall install
# Make a distribution tarball
dist: mrproper
dist: mrproper $(if $(ISGIT),reinit-gitmodules)
$(call bcmd,mkdir,lib$(NAME)-$(VERSION),\
$(MD) .dist)
$(call bcmd,cp,* lib$(NAME)-$(VERSION),\
@ -52,14 +56,27 @@ dist: mrproper
.PHONY: all mostlyclean mclean clean fclean mrproper re
.PHONY: dist install uninstall reinstall
#******************************************************************************#
# Configuration (version) checking dependencies #
# Git submodules management #
#******************************************************************************#
# Main rule.
reinit-gitmodules:
$(call bcmd,Deinitializing git submodules.)
$(call qcmd,git submodule deinit -f --quiet -- \
$(shell grep path .gitmodules | sed 's/.*= //'))
$(call bcmd,Reinitializing git submodules.)
$(call qcmd,git submodule update --init --recursive --quiet)
.PHONY: reinit-gitmodules
#******************************************************************************#
# Checking dependencies #
#******************************************************************************#
# Define the dependencies.
CHECKCFG := $(if $(shell test -f Makefile.cfg || echo y),check-config, \
$(if $(shell [ "$(VERSION)" = "$(CONFIG_VERSION)" ] || echo y), \
check-config-version))
CHECKFC := $(if $(ISGIT),check-gitmodules)
# Define the rules.
# Configuration checking.
check-config:
@echo -e "\033[1;31mNo configuration file found!"
@echo -e "You should configure before re-running this target.\033[0m"
@ -69,7 +86,12 @@ dist: mrproper
@echo -e "You should re-configure before re-running this target.\033[0m"
@false
.PHONY: check-config check-config-version
# Git submodules checking.
check-gitmodules:
$(call bcmd,Checking git modules.)
$(call qcmd,git submodule update --init --recursive)
.PHONY: check-config check-config-version check-gitmodules
#******************************************************************************#
# Information getting from the Makefile variables #
#******************************************************************************#

View File

@ -87,6 +87,10 @@
# Directory maker
MD := mkdir -p
# Copier
CP := cp
# Mover
MV := mv
# Symbolic link maker
LN := ln -sf
# File remover

View File

@ -22,6 +22,7 @@ I took these as a reference because these are the ones I work with.
| [binutils](https://www.gnu.org/software/binutils/) | >= 2.25 |
| [asciidoc](http://asciidoc.org/) | >= 8.6.9 |
| [gzip](https://www.gnu.org/software/gzip/) | >= 1.6 |
| [python3](https://www.python.org/) | >= 3.5 |
### Runtime dependencies
| Name | Version |

19
configure vendored
View File

@ -10,9 +10,6 @@ version="$(make -s getversion)"
# Maintainer
maintainer="$(make -s getmaintainer)"
# Target
target=""
# Platform
platform="$(command -v gcc 1>/dev/null && gcc --print-multiarch)"
platform="$([ "$platform" ] && echo "/$platform")"
@ -21,7 +18,9 @@ platform="$([ "$platform" ] && echo "/$platform")"
make_full_log=
# Build options
target=
loglevel=none # none, info, warn, error, fatal
fcset=$(tools/list-sets --default)
# Installation directories
root=''
@ -53,6 +52,7 @@ General options:
--make-full-log display full commands while making
Build options:
--set=SET the FONTCHARACTER set (if none, default one)
--target=TARGET the target (if none, native)
--loglevel=LOGLEVEL library log level [$loglevel]
@ -71,6 +71,11 @@ Fine tuning of the installation directories:
--includedir=DIR include files for the compiler [$includedir]
--mandir=DIR man root [$mandir]
Available FONTCHARACTER sets are:
EOF
./tools/list-sets --long
cat <<EOF
Report bugs to ${maintainer}.
EOF
exit 0
@ -122,6 +127,13 @@ got '$level'"
fi
# then set
loglevel=$level ;;
--set=*)
s="${arg#*=}"
# check if in array
if tools/check-set $s
then fcset="$s"
else echo "$0: --set: not a valid set (see the help page)" >&2
fi ;;
--noinstall-manpages) install_manpages= ;;
--noinstall-devel) install_devel= ;;
--root=*) root="${arg#*=}" ;;
@ -163,6 +175,7 @@ cat <<EOF
# Build options
TARGET = $target
LOG_LEVEL = $loglevel
SET := $fcset
# Installation directories
IBINDIR = $bindir

49
include/libg1m/basic.h Normal file
View File

@ -0,0 +1,49 @@
/* ************************************************************************** */
/* _____ _ */
/* libg1m/basic.h |_ _|__ _ _| |__ ___ _ _ */
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
/* | | (_) | |_| | | | | __/ |_| | */
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
/* Last updated: 2017/01/07 17:00:25 |___/ */
/* */
/* ************************************************************************** */
#ifndef LIBG1M_BASIC_H
# define LIBG1M_BASIC_H
# define CBASIC_MAX_ARGUMENTS 3
/* libg1m has utilities for interacting with Basic programs!
* Everything is basically a statement, but when it's just a
* value/variable/..., it's instruction 0x00 with one argument.
*
* Here are the types an argument can take: */
enum g1m_argument_type {
g1m_argtype_value,
g1m_argtype_variable,
g1m_argtype_string,
g1m_argtype_list,
g1m_argtype_mat,
};
/* And here's the structure of a statement: */
typedef struct g1m_basic_statement_s {
FONTCHARACTER opcode;
int argtype, id;
/* BCD values */
struct bcd real;
struct bcd imgn;
/* arguments */
int nargs;
struct g1m_basic_statement_s *args;
} g1m_bst_t;
/* And here is the function to fetch an instruction from a program content
* buffer: */
int g1m_fetch_instruction(const FONTCHARACTER *buf, size_t size,
size_t *isize, g1m_bst_t *statement);
#endif /* LIBG1M_BASIC_H */

View File

@ -0,0 +1,232 @@
/* ************************************************************************** */
/* _____ _ */
/* basic/instruction.c |_ _|__ _ _| |__ ___ _ _ */
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
/* | | (_) | |_| | | | | __/ |_| | */
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
/* Last updated: 2017/01/07 14:55:53 |___/ */
/* */
/* ************************************************************************** */
#include <libg1m/internals.h>
#define go_forward(N) *buf += (N); *size -= (N)
/* ************************************************************************** */
/* Utilities */
/* ************************************************************************** */
/**
* parse_bcd:
* Parse a BCD.
*
* @arg buf the FONTCHARACTER buffer.
* @arg size the buffer size.
* @arg real the real part.
* @arg imgn the imaginary part.
* @return the error.
*/
static int fetch_bcd(const FONTCHARACTER **buf, size_t *size,
struct bcd *real, struct bcd *imgn)
{
/* TODO */
return (g1m_error_eof);
}
/**
* fetch_int:
* Decode an integer.
*
* @arg buf the FONTCHARACTER buffer.
* @arg size the buffer size.
* @arg num the integer to parse.
*/
static int fetch_int(const FONTCHARACTER **buf, size_t *size, int *id)
{
/* check the ans */
if (**buf == 0xC0) { *id = g1m_ans; (*buf)++; (*size)--; return (0); }
/* peek and get the size of the number */
int i; for (i = 0; i < *size && (*buf)[i] >= '0' && (*buf)[i] <= '9'; i++);
/* get the number */
int numsize = i;
*id = 0; while (i-- >= 0) *id = *id * 10 + (*buf)[i] - '0';
/* go forward and ok */
go_forward(numsize);
return (0);
}
/**
* fetch_argument:
* Decode an argument.
*
* @arg buf the FONTCHARACTER buffer.
* @arg size the buffer size.
* @arg arg the argument structure.
* @return if there was an error
*/
#define VAR(ID) (struct argument){.type = g1m_argtype_var, .id = (ID)}
static int fetch_argument(const FONTCHARACTER **buf, size_t *size,
struct argument *arg)
{
/* check if we have at least one character */
if (!*size) return (g1m_error_eof);
/* check if is something special */
FONTCHARACTER op = **buf;
if (opcode == 0xF93F) { arg->type = g1m_argtype_string; goto parse_id; }
if (opcode == 0x7F40) { arg->type = g1m_argtype_mat; goto parse_let; }
if (opcode == 0x7F51) { arg->type = g1m_argtype_list; goto parse_id; }
/* check if it's a var */
if (op == 0xC0) *arg = VAR(g1m_ans);
else if (op == 0xCE) *arg = VAR(g1m_theta);
else if (op == 0xCD) *arg = VAR(g1m_r);
else if (op >= 'A' && op <= 'Z') *arg = VAR(op - 'A');
else {
int err = fetch_bcd(buf, size, &arg->real, &arg->imgn);
if (err) return (fetch_statement(buf, size, arg->statement));
return (err);
}
/* was a var */
go_forward(1);
return (0);
/* it's something with an ID! */
parse_id:
go_forward(1);
return (fetch_int(buf, size, &arg->id));
/* it's something with a letter ID! */
parse_let:
go_forward(1);
return (fetch_let(buf, size, &arg->id));
}
/* ************************************************************************** */
/* Statements */
/* ************************************************************************** */
/* Statements */
struct statement {
/* the start opcode */
FONTCHARACTER opcode;
/* number of arguments */
int nargs;
/* finishes with a parenthesis */
int par;
};
/* Known statements */
static const struct statement statements[] = {
/* Locate x,x,x */
{0xF710, 3, 0},
/* Send(A) */
{0xF711, 1, 1},
/* Receive(A) */
{0xF712, 1, 1},
{0, 0}
};
/* Infix statements */
static const struct statement infix_statements[] = {
/* x! */
{0xEA, 1, 0},
/* a = b */
{0x3D, 2, 0},
{0, 0}
};
/**
* fetch_raw_statement:
* Fetch a statement.
*
* @arg buf the FONTCHARACTER buffer pointer.
* @arg size the FONTCHARACTER buffer size pointer.
* @arg st the statement pointer.
* @arg fst the first argument
* @arg infix is infix (boolean!)
* @return the error.
*/
static int fetch_raw_statement(const FONTCHARACTER **buf, size_t *size,
struct statement *st, struct argument *fst, int infix)
{
/* check if there is at least space for one opcode */
if (!*size) return (1);
/* get the statements tab */
const struct *sts =
(const *struct statement[]){statements, infix_statements}[infix];
/* check which opcode it is */
FONTCHARACTER op = **buf;
const struct *st;
for (st = sts; st->opcode && st->opcode != op; st++);
if (!st) return (1);
/* prepare the arguments */
int nargs = st->nargs;
struct argument *args = malloc(nargs * sizeof(struct argument));
if (!args) return (1);
if (nargs) memcpy(&args[0], fst, sizeof(struct argument));
/* iterate */
int last = infix - 1;
for (int i = infix; i < nargs; i++) {
/* parse the arg */
if (fetch_argument(buf, size, &args[i]))
return (1);
/* check the comma */
if (i < last && (!*size || **buf != ','))
return (1);
go_forward(1);
}
/* check right parenthesis */
if (st->par && *size && **buf != ')')
return (1);
if (*size) { go_forward(1); }
/* no error */
return (0);
}
/**
* fetch_statement:
* Fetch a statement.
*/
/* ************************************************************************** */
/* Main function */
/* ************************************************************************** */
/**
* g1m_fetch_instruction:
* Fetch the instruction.
*
* @arg buf the FONTCHARACTER buffer.
* @arg size the FONTCHARACTER buffer size.
* @arg statement the statement.
* @return if negative: the negative libg1m error code.
* otherwise: the size of the instruction.
*/
int g1m_fetch_instruction(const FONTCHARACTER *buf, size_t size,
g1m_bst_t *statement)
{
size_t sav = size;
/* start by free-ing statement content? */
/* TODO */
/* check it it's a statement */
int err = fetch_statement(&buf, &size, &statement, 0);
return (err ? -err : (int)(sav - size));
}

11
tools/check-set Executable file
View File

@ -0,0 +1,11 @@
#!/usr/bin/env python3
# Dependencies
import os, sys
from fontcharacter import Reference
# Open the reference
refpath = os.path.join(os.path.dirname(__file__), 'fontcharacter_reference')
ref = Reference(refpath, sets_only=True)
# Exit with the correct code
exit(not sys.argv[1] in ref.sets.keys())

1
tools/fontcharacter Submodule

@ -0,0 +1 @@
Subproject commit 72a14ac14d774416efc9c72bd3dd6646ee6138ea

@ -0,0 +1 @@
Subproject commit 1f382d0797f7534df408e858a9182bd11c9dddea

23
tools/list-sets Executable file
View File

@ -0,0 +1,23 @@
#!/usr/bin/env python3
# Dependencies
import os, sys
from fontcharacter import Reference
# Open the reference
refpath = os.path.join(os.path.dirname(__file__), 'fontcharacter_reference')
ref = Reference(refpath, sets_only=True)
# Put the default
if "--default" in sys.argv:
print(ref.default_set)
exit(0)
# List them
lg = "--long" in sys.argv
k = sorted(ref.sets.keys())
for name, s in zip(k, map(ref.sets.__getitem__, k)):
if lg:
print('* %s: %s%s'%(name, s['description'], \
' (default)' if name == ref.default_set else ''))
else:
print(name)

View File

@ -45,12 +45,7 @@ exit 0
# Version message #
#******************************************************************************#
version() {
cat <<EOF
${name} configuration tool v${version}
Written by Thomas "Cakeisalie5" Touhey.
This configuration tool is public domain.
EOF
echo ${version}
exit 0
}