From aee665f2bc7d66d5e6ecb1e31f9e2ccf614c7fa2 Mon Sep 17 00:00:00 2001
From: Aleksey Veresov <aleksey@veresov.pro>
Date: Mon, 10 Aug 2020 10:59:49 +0300
Subject: Initial commit.

---
 LICENSE         |   9 +++++
 Makefile        | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 README          |  19 ++++++++++
 examples/math.c |  70 ++++++++++++++++++++++++++++++++++++
 4 files changed, 205 insertions(+)
 create mode 100644 LICENSE
 create mode 100644 Makefile
 create mode 100644 README
 create mode 100644 examples/math.c

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;
+}
-- 
cgit v1.2.3