aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Veresov <aleksey@veresov.pro>2020-08-10 10:59:49 +0300
committerAleksey Veresov <aleksey@veresov.pro>2020-08-10 10:59:49 +0300
commitaee665f2bc7d66d5e6ecb1e31f9e2ccf614c7fa2 (patch)
tree57310c4f259f5d7c9388ede6327307dcae895286
downloadcsx-aee665f2bc7d66d5e6ecb1e31f9e2ccf614c7fa2.tar
csx-aee665f2bc7d66d5e6ecb1e31f9e2ccf614c7fa2.tar.xz
csx-aee665f2bc7d66d5e6ecb1e31f9e2ccf614c7fa2.zip
Initial commit.
-rw-r--r--LICENSE9
-rw-r--r--Makefile107
-rw-r--r--README19
-rw-r--r--examples/math.c70
4 files changed, 205 insertions, 0 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..4921ae2
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,9 @@
+Copyright 2020 Aleksey Veresov
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from
+the use of this software.
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..05c8746
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,107 @@
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+# Compilation Options
+# Debug mode [yes/no] (allowing to debug the library via gdb):
+DEBUG ?= no
+# Specify your favourite C compiler here:
+COMPILE ?= gcc
+# Specify your include directory (headers location):
+INCDIR ?= /usr/include
+# Specify your libraries directory:
+LIBDIR ?= /usr/lib
+# Specify location of man pages on your machine:
+MANDIR ?= /usr/share/man
+
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+# Preparations
+# Compile as ANSI C code:
+CFLAGS = -xc -ansi -Wall
+# Specify linker to use the library:
+LFLAGS = -L$(BUILD) -lcsx
+# Debug and optimisation (as well as -static for valgrind) are not compatible:
+ifeq '$(DEBUG)' 'yes'
+CFLAGS += -g -O0
+else
+CFLAGS += -O3
+LFLAGS += -static
+endif
+
+# Directories definitions:
+INCLUDE = include
+BUILD = build
+SRCDIR = src
+EXADIR = examples
+MAN = man
+# Library itself:
+LIB = libcsx.a
+# Modules:
+EXTERNAL = $(foreach x,$(notdir $(wildcard $(INCLUDE)/csx/*.h)),$(x:.h=))
+INTERNAL = $(foreach x,$(notdir $(wildcard $(SRCDIR)/*.h)),$(x:.h=))
+
+# Default target is library:
+TARGET = $(BUILD)/$(LIB)
+# Determing needed object files:
+EXTER_H = $(foreach x,$(EXTERNAL:=.h),$(INCLUDE)/csx/$(x))
+EXTER_C = $(foreach x,$(EXTERNAL:=.c),$(SRCDIR)/$(x))
+INTER_H = $(foreach i,$(INTERNAL:=.h),$(SRCDIR)/$(i))
+INTER_C = $(INTER_H:.h=.c)
+SRC = $(INTER_C) $(EXTER_C)
+OBJ = $(foreach o,$(SRC:.c=.o),$(BUILD)/$(o))
+# Example executables:
+XSRC = $(wildcard $(EXADIR)/*.c)
+EXAMPLES = $(foreach x,$(XSRC:.c=),$(BUILD)/$(x))
+# Dependency file:
+DEPS = deps.mk
+
+SRCINC = -I$(INCLUDE)/csx
+XINC = -I$(INCLUDE)
+SRCBUILD = $(BUILD)/$(SRCDIR)
+XBLD = $(BUILD)/$(EXADIR)
+
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+# Targets
+.PHONY: all examples clean install uninstall
+
+all: $(SRCBUILD) $(TARGET)
+
+examples: all $(XBLD) $(EXAMPLES)
+
+clean:
+ rm -f $(TARGET) $(OBJ) $(EXAMPLES) $(DEPS)
+
+install: all
+ cp -r $(INCLUDE)/* $(INCDIR)
+ cp $(TARGET) $(LIBDIR)
+ cp $(MAN)/* $(MANDIR)/man3
+
+uninstall:
+ rm -r $(INCDIR)/csx.h $(INCDIR)/csx
+ rm $(LIBDIR)/$(LIB)
+ rm $(MANDIR)/man3/csx.3 $(MANDIR)/man3/libcsx.3
+
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+# Compilation
+-include $(DEPS)
+
+# Packing object files into library:
+$(TARGET): $(OBJ)
+ ar -rcs $@ $^
+
+# Compile object files from corresponding source:
+$(BUILD)/%.o: %.c
+ $(COMPILE) $(CFLAGS) $(SRCINC) -c $< -o $@
+
+# Compile executables from corresponding sources and library:
+$(BUILD)/%: %.c $(TARGET)
+ $(COMPILE) $(CFLAGS) $(XINC) $< $(LFLAGS) -o $@
+
+# Create build directories, if no such:
+$(SRCBUILD) $(XBLD):
+ mkdir -p $@
+
+# Generate dependency file, adding corresponding build prefixes:
+$(DEPS): $(SRC) $(EXASRC) $(EXTER_H) $(INTER_H) $(INCLUDE)/csx.h
+ $(COMPILE) $(SRCINC) $(SRC) -MM | sed '/^ /!s#^#$(SRCBUILD)/#' >$@
+ $(COMPILE) $(XINC) $(XSRC) -MM | sed '/^ /!s#^#$(XBLD)/#;s/\.o//' >>$@
diff --git a/README b/README
new file mode 100644
index 0000000..bac93d8
--- /dev/null
+++ b/README
@@ -0,0 +1,19 @@
+ Description
+CSX Library (libcsx) extends C with S-Expressions.
+
+ Overview
+CSX is free and open-source software: legal info is in the 'LICENSE' file.
+For detailed documentation look into 'man' directory.
+
+ Compiling
+...
+
+ Examples
+Running 'make examples' produces executable for each example in 'examples'.
+Descriptions and details are in corresponding source files.
+
+ Usage
+...
+
+ Motivation
+You can do such things in C, this fact should be more known.
diff --git a/examples/math.c b/examples/math.c
new file mode 100644
index 0000000..df0aabc
--- /dev/null
+++ b/examples/math.c
@@ -0,0 +1,70 @@
+#include <csx.h>
+
+
+v def_rat_sum(v construct, v numer, v denom)
+{
+ v a = atom("a");
+ v b = atom("b");
+ return el(define, l(atom("rat_sum"), a, b),
+ l(construct, l(sum, l(mul, l(numer, a), l(denom, b)),
+ l(mul, l(numer, b), l(denom, a))),
+ l(mul, l(denom, a), l(denom, b)))
+ );
+}
+
+v def_rat_sum(v construct, v numer, v denom)
+{
+ v a = atom("a");
+ v b = atom("b");
+ return el(define, l(atom("rat_sub"), a, b),
+ l(construct, l(sub, l(mul, l(numer, a), l(denom, b)),
+ l(mul, l(numer, b), l(denom, a))),
+ l(mul, l(denom, a), l(denom, b)))
+ );
+}
+
+v def_rat_equ(v construct, v numer, v denom)
+{
+ v a = atom("a");
+ v b = atom("b");
+ return el(define, l(atom("rat_equ"), a, b),
+ l(equ, l(mul, l(numer, a), l(denom, b)),
+ l(mul, l(numer, b), l(denom, a)))
+ );
+}
+
+void printres(v a, v b, v absum, v absub, int *are_equ, v numer, v denom)
+{
+ int an = *(int *)el(numer, a);
+ int ad = *(int *)el(denom, a);
+ int bn = *(int *)el(numer, b);
+ int bd = *(int *)el(denom, b);
+ int sumn = *(int *)el(numer, absum);
+ int sumd = *(int *)el(denom, absum);
+ int subn = *(int *)el(numer, absub);
+ int subd = *(int *)el(denom, absub);
+ printf("%d/%d + %d/%d = %d/%d\n", an, ad, bn, bd, sumn, sumd);
+ printf("%d/%d - %d/%d = %d/%d\n", an, ad, bn, bd, subn, subd);
+ if (*are_equ) {
+ puts("And they are equal.\n");
+ } else {
+ puts("And they are not equal.\n");
+ }
+}
+
+int main()
+{
+ v rat = l(define, atom("rat"), cons);
+ v rat_numer = l(define, atom("rat_numer"), car);
+ v rat_denom = l(define, atom("rat_denom"), cdr);
+ v rat_sum = def_rat_sum(rat, rat_numer, rat_denom);
+ v rat_sub = def_rat_sub(rat, rat_numer, rat_denom);
+ v rat_equ = def_rat_equ(rat, rat_numer, rat_denom);
+ v number_a = el(rat, n(19), n(99));
+ v number_b = el(rat, n(7), n(3));
+ v absum = el(rat_sum, number_a, number_b);
+ v absub = el(rat_sub, number_a, number_b);
+ v are_equ = el(rat_equ, number_a, number_b);
+ printres(number_a, number_b, sum, sub, are_equ, numer, denom);
+ return 0;
+}