From aee665f2bc7d66d5e6ecb1e31f9e2ccf614c7fa2 Mon Sep 17 00:00:00 2001 From: Aleksey Veresov 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 + + +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