Port to Chicken 6
This commit is contained in:
commit
7cb9a1c8bb
14 changed files with 747 additions and 0 deletions
2
.envrc
Normal file
2
.envrc
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export NIXPKGS_ALLOW_BROKEN=1
|
||||||
|
use nix
|
4
README.org
Normal file
4
README.org
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
* symbol-utils Egg for Chicken 6
|
||||||
|
|
||||||
|
This is a port of =symbol-utils= to Chicken 6. It implements minimal changes to make the egg work.
|
||||||
|
|
126
nix/chicken.nix
Normal file
126
nix/chicken.nix
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
stdenv,
|
||||||
|
fetchgit,
|
||||||
|
fetchurl,
|
||||||
|
makeWrapper,
|
||||||
|
darwin,
|
||||||
|
tcc-mob,
|
||||||
|
version ? "git",
|
||||||
|
testers
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
platform = with stdenv;
|
||||||
|
if isDarwin then "macosx"
|
||||||
|
else if isCygwin then "cygwin"
|
||||||
|
else if (isFreeBSD || isOpenBSD) then "bsd"
|
||||||
|
else if isSunOS then "solaris"
|
||||||
|
else "linux"; # Should be a sane default
|
||||||
|
in
|
||||||
|
stdenv.mkDerivation (finalAttrs: {
|
||||||
|
pname = "chicken";
|
||||||
|
inherit version;
|
||||||
|
|
||||||
|
binaryVersion = 12;
|
||||||
|
|
||||||
|
srcs = [
|
||||||
|
(fetchgit {
|
||||||
|
url = "git://code.call-cc.org/chicken-core";
|
||||||
|
rev = "dbffda19e57c3be092e5a9174f1829632f5fa5a7";
|
||||||
|
sha256 = "sha256-zWjf9JS4H1buBlkmUhIv+odCQzXaOPtI7VfIaQUhe6Q=";
|
||||||
|
})
|
||||||
|
(fetchurl {
|
||||||
|
url = "https://code.call-cc.org/dev-snapshots/2024/07/01/chicken-6.0.0-bootstrap.tar.gz";
|
||||||
|
sha256 = "sha256-qkcyWzsaN9+HbMBolmv7zeaPrtbaCTGa9HoF2g/3//o=";
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
unpackPhase = ''
|
||||||
|
cp -r `echo $srcs | awk '{print $1}'`/* .
|
||||||
|
cp -r `echo $srcs | awk '{print $1}'`/.* .
|
||||||
|
chmod -R 777 .
|
||||||
|
mkdir -p boot/snapshot
|
||||||
|
cd boot
|
||||||
|
tar xzf `echo $srcs | awk '{print $2}'`
|
||||||
|
cd ..
|
||||||
|
echo ${version} > buildid
|
||||||
|
|
||||||
|
cd boot/chicken-6.0.0
|
||||||
|
case "${platform}" in
|
||||||
|
bsd)
|
||||||
|
mkcmd=gmake;;
|
||||||
|
*)
|
||||||
|
mkcmd=make;;
|
||||||
|
esac
|
||||||
|
export CC="${tcc-mob}/bin/tcc"
|
||||||
|
$mkcmd C_COMPILER=$CC PREFIX="$(pwd)"/../snapshot
|
||||||
|
$mkcmd C_COMPILER=$CC PREFIX="$(pwd)"/../snapshot install
|
||||||
|
cd ../..
|
||||||
|
./configure --chicken "$(pwd)"/boot/snapshot/bin/chicken --c-compiler "${tcc-mob}/bin/tcc"
|
||||||
|
$mkcmd boot-chicken
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Disable two broken tests: "static link" and "linking tests"
|
||||||
|
postPatch = ''
|
||||||
|
sed -i tests/runtests.sh -e "/static link/,+4 { s/^/# / }"
|
||||||
|
sed -i tests/runtests.sh -e "/linking tests/,+11 { s/^/# / }"
|
||||||
|
'';
|
||||||
|
|
||||||
|
# -fno-strict-overflow is not a supported argument in clang
|
||||||
|
hardeningDisable = lib.optionals stdenv.cc.isClang [ "strictoverflow" ];
|
||||||
|
|
||||||
|
makeFlags = [
|
||||||
|
"PLATFORM=${platform}"
|
||||||
|
"PREFIX=$(out)"
|
||||||
|
"C_COMPILER=${tcc-mob}/bin/tcc"
|
||||||
|
"CXX_COMPILER=$(CXX)"
|
||||||
|
] ++ (lib.optionals stdenv.isDarwin [
|
||||||
|
"XCODE_TOOL_PATH=${darwin.binutils.bintools}/bin"
|
||||||
|
"LINKER_OPTIONS=-headerpad_max_install_names"
|
||||||
|
"POSTINSTALL_PROGRAM=install_name_tool"
|
||||||
|
]) ++ (lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
|
||||||
|
"HOSTSYSTEM=${stdenv.hostPlatform.config}"
|
||||||
|
"TARGET_C_COMPILER=${tcc-mob}/bin/${stdenv.cc.targetPrefix}tcc"
|
||||||
|
"TARGET_CXX_COMPILER=${stdenv.cc}/bin/${stdenv.cc.targetPrefix}c++"
|
||||||
|
]);
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
makeWrapper
|
||||||
|
pkgs.hostname
|
||||||
|
tcc-mob
|
||||||
|
] ++ lib.optionals (stdenv.isDarwin && stdenv.isAarch64) [
|
||||||
|
darwin.autoSignDarwinBinariesHook
|
||||||
|
];
|
||||||
|
|
||||||
|
configurePhase = ''
|
||||||
|
./configure --chicken ./chicken-boot --prefix $PREFIX --platform=$PLATFORM --c-compiler "${tcc-mob}/bin/tcc"
|
||||||
|
'';
|
||||||
|
|
||||||
|
doCheck = !stdenv.isDarwin;
|
||||||
|
postCheck = ''
|
||||||
|
./csi -R chicken.pathname -R chicken.platform \
|
||||||
|
-p "(assert (equal? \"${toString finalAttrs.binaryVersion}\" (pathname-file (car (repository-path)))))"
|
||||||
|
'';
|
||||||
|
|
||||||
|
passthru.tests.version = testers.testVersion {
|
||||||
|
package = finalAttrs.finalPackage;
|
||||||
|
command = "csi -version";
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
homepage = "https://call-cc.org/";
|
||||||
|
license = lib.licenses.bsd3;
|
||||||
|
maintainers = with lib.maintainers; [ corngood nagy konst-aa ];
|
||||||
|
platforms = lib.platforms.unix;
|
||||||
|
description = "Portable compiler for the Scheme programming language";
|
||||||
|
longDescription = ''
|
||||||
|
CHICKEN is a compiler for the Scheme programming language.
|
||||||
|
CHICKEN produces portable and efficient C, supports almost all
|
||||||
|
of the R5RS Scheme language standard, and includes many
|
||||||
|
enhancements and extensions. CHICKEN runs on Linux, macOS,
|
||||||
|
Windows, and many Unix flavours.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
})
|
129
nix/tinycc.nix
Normal file
129
nix/tinycc.nix
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
{ lib
|
||||||
|
, copyPkgconfigItems
|
||||||
|
, fetchFromRepoOrCz
|
||||||
|
, makePkgconfigItem
|
||||||
|
, perl
|
||||||
|
, stdenv
|
||||||
|
, texinfo
|
||||||
|
, which
|
||||||
|
}:
|
||||||
|
|
||||||
|
stdenv.mkDerivation (finalAttrs: {
|
||||||
|
pname = "tcc-mob";
|
||||||
|
version = "0.9.29-unstable-2024-09-16";
|
||||||
|
|
||||||
|
src = fetchFromRepoOrCz {
|
||||||
|
repo = "tinycc";
|
||||||
|
rev = "b8b6a5fd7b4e8cab8e5a5d01064cf5bf2b5eed95";
|
||||||
|
hash = "sha256-jY0P2GErmo//YBaz6u4/jj/voOE3C2JaIDRmo0orXN8=";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = [ "out" "info" "man" ];
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
copyPkgconfigItems
|
||||||
|
perl
|
||||||
|
texinfo
|
||||||
|
which
|
||||||
|
];
|
||||||
|
|
||||||
|
strictDeps = true;
|
||||||
|
|
||||||
|
pkgconfigItems = let
|
||||||
|
libtcc-pcitem = {
|
||||||
|
name = "libtcc";
|
||||||
|
inherit (finalAttrs) version;
|
||||||
|
cflags = [ "-I${libtcc-pcitem.variables.includedir}" ];
|
||||||
|
libs = [
|
||||||
|
"-L${libtcc-pcitem.variables.libdir}"
|
||||||
|
"-Wl,--rpath ${libtcc-pcitem.variables.libdir}"
|
||||||
|
"-ltcc"
|
||||||
|
];
|
||||||
|
variables = {
|
||||||
|
prefix = "${placeholder "out"}";
|
||||||
|
includedir = "${placeholder "dev"}/include";
|
||||||
|
libdir = "${placeholder "lib"}/lib";
|
||||||
|
};
|
||||||
|
description = "Tiny C compiler backend";
|
||||||
|
};
|
||||||
|
in [
|
||||||
|
(makePkgconfigItem libtcc-pcitem)
|
||||||
|
];
|
||||||
|
|
||||||
|
postPatch = ''
|
||||||
|
patchShebangs texi2pod.pl
|
||||||
|
'';
|
||||||
|
|
||||||
|
configureFlags = [
|
||||||
|
"--cc=$CC"
|
||||||
|
"--ar=$AR"
|
||||||
|
"--crtprefix=${lib.getLib stdenv.cc.libc}/lib"
|
||||||
|
"--sysincludepaths=${lib.getDev stdenv.cc.libc}/include:{B}/include"
|
||||||
|
"--libpaths=${lib.getLib stdenv.cc.libc}/lib"
|
||||||
|
# build cross compilers
|
||||||
|
"--enable-cross"
|
||||||
|
] ++ lib.optionals stdenv.hostPlatform.isMusl [
|
||||||
|
"--config-musl"
|
||||||
|
];
|
||||||
|
|
||||||
|
preConfigure = let
|
||||||
|
# To avoid "malformed 32-bit x.y.z" error on mac when using clang
|
||||||
|
versionIsClean = version:
|
||||||
|
builtins.match "^[0-9]\\.+[0-9]+\\.[0-9]+" version != null;
|
||||||
|
in ''
|
||||||
|
${
|
||||||
|
if stdenv.isDarwin && ! versionIsClean finalAttrs.version
|
||||||
|
then "echo 'not overwriting VERSION since it would upset ld'"
|
||||||
|
else "echo ${finalAttrs.version} > VERSION"
|
||||||
|
}
|
||||||
|
configureFlagsArray+=("--elfinterp=$(< $NIX_CC/nix-support/dynamic-linker)")
|
||||||
|
'';
|
||||||
|
|
||||||
|
env.NIX_CFLAGS_COMPILE = toString (lib.optionals stdenv.cc.isClang [
|
||||||
|
"-Wno-error=implicit-int"
|
||||||
|
"-Wno-error=int-conversion"
|
||||||
|
]);
|
||||||
|
|
||||||
|
# Test segfault for static build
|
||||||
|
doCheck = !stdenv.hostPlatform.isStatic;
|
||||||
|
|
||||||
|
checkTarget = "test";
|
||||||
|
# https://www.mail-archive.com/tinycc-devel@nongnu.org/msg10142.html
|
||||||
|
preCheck = lib.optionalString (stdenv.isDarwin && stdenv.isx86_64) ''
|
||||||
|
rm tests/tests2/{108,114}*
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
homepage = "https://repo.or.cz/tinycc.git";
|
||||||
|
description = "Small, fast, and embeddable C compiler and interpreter";
|
||||||
|
longDescription = ''
|
||||||
|
TinyCC (aka TCC) is a small but hyper fast C compiler. Unlike other C
|
||||||
|
compilers, it is meant to be self-sufficient: you do not need an external
|
||||||
|
assembler or linker because TCC does that for you.
|
||||||
|
|
||||||
|
TCC compiles so fast that even for big projects Makefiles may not be
|
||||||
|
necessary.
|
||||||
|
|
||||||
|
TCC not only supports ANSI C, but also most of the new ISO C99 standard
|
||||||
|
and many GNU C extensions.
|
||||||
|
|
||||||
|
TCC can also be used to make C scripts, i.e. pieces of C source that you
|
||||||
|
run as a Perl or Python script. Compilation is so fast that your script
|
||||||
|
will be as fast as if it was an executable.
|
||||||
|
|
||||||
|
TCC can also automatically generate memory and bound checks while allowing
|
||||||
|
all C pointers operations. TCC can do these checks even if non patched
|
||||||
|
libraries are used.
|
||||||
|
|
||||||
|
With libtcc, you can use TCC as a backend for dynamic code generation.
|
||||||
|
'';
|
||||||
|
license = with lib.licenses; [ lgpl21Only ];
|
||||||
|
mainProgram = "tcc";
|
||||||
|
maintainers = with lib.maintainers; [ joachifm AndersonTorres ];
|
||||||
|
platforms = lib.platforms.unix;
|
||||||
|
# https://www.mail-archive.com/tinycc-devel@nongnu.org/msg10199.html
|
||||||
|
broken = stdenv.isDarwin && stdenv.isAarch64;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
# TODO: more multiple outputs
|
||||||
|
# TODO: self-compilation
|
32
shell.nix
Normal file
32
shell.nix
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
with import <nixpkgs> {
|
||||||
|
overlays = [
|
||||||
|
(final: prev: {
|
||||||
|
tcc-mob = final.callPackage ./nix/tinycc.nix { stdenv = final.gcc13Stdenv; };
|
||||||
|
chicken = final.callPackage ./nix/chicken.nix { stdenv = final.gcc13Stdenv; };
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
mkShell {
|
||||||
|
packages = with pkgs; [
|
||||||
|
tcc-mob
|
||||||
|
chicken
|
||||||
|
rlwrap
|
||||||
|
]
|
||||||
|
# ++ (with pkgs.chickenPackages_5.chickenEggs; [
|
||||||
|
# apropos
|
||||||
|
# chicken-doc
|
||||||
|
# srfi-1
|
||||||
|
# srfi-18
|
||||||
|
# lsp-server
|
||||||
|
# srfi-152
|
||||||
|
# ])
|
||||||
|
;
|
||||||
|
shellHook = ''
|
||||||
|
export CC="${pkgs.tcc-mob}/bin/tcc"
|
||||||
|
export CHICKEN_PREFIX="$HOME/.chicken"
|
||||||
|
export CHICKEN_INSTALL_REPOSITORY="$HOME/.chicken/eggs"
|
||||||
|
export CHICKEN_REPOSITORY_PATH="${pkgs.chicken}/lib/chicken/12:$HOME/.chicken/eggs"
|
||||||
|
export PATH="$PATH:$CHICKEN_PREFIX"
|
||||||
|
export CHICKEN_PREFIX="${pkgs.chicken}"
|
||||||
|
'';
|
||||||
|
}
|
23
symbol-lolevel-utils.scm
Normal file
23
symbol-lolevel-utils.scm
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
;;;; symbol-lolevel-utils.scm -*- Scheme -*-
|
||||||
|
;;;; Kon Lovett, Mar '20
|
||||||
|
;;;; Kon Lovett, Jul '18
|
||||||
|
|
||||||
|
(declare
|
||||||
|
(bound-to-procedure ##sys#intern-symbol ##sys#check-symbol))
|
||||||
|
|
||||||
|
(module symbol-lolevel-utils
|
||||||
|
|
||||||
|
(;export
|
||||||
|
interned-symbol?)
|
||||||
|
|
||||||
|
(import scheme)
|
||||||
|
(import (chicken type))
|
||||||
|
|
||||||
|
(: interned-symbol? (symbol --> boolean))
|
||||||
|
|
||||||
|
(define (check-symbol loc obj) (##sys#check-symbol obj loc) obj)
|
||||||
|
|
||||||
|
(define (interned-symbol? sym)
|
||||||
|
(##sys#interned-symbol? (check-symbol 'interned-symbol? sym)) )
|
||||||
|
|
||||||
|
) ;module symbol-lolevel-utils
|
198
symbol-name-utils.scm
Normal file
198
symbol-name-utils.scm
Normal file
|
@ -0,0 +1,198 @@
|
||||||
|
;;;; symbol-name-utils.scm -*- Scheme -*-
|
||||||
|
;;;; Kon Lovett, Mar '20
|
||||||
|
;;;; Kon Lovett, Jul '18
|
||||||
|
|
||||||
|
(declare
|
||||||
|
(bound-to-procedure ##sys#check-symbol ##sys#check-keyword ##sys#check-list))
|
||||||
|
|
||||||
|
(module symbol-name-utils
|
||||||
|
|
||||||
|
(;export
|
||||||
|
;
|
||||||
|
->symbol
|
||||||
|
->uninterned-symbol
|
||||||
|
keyword->symbol
|
||||||
|
keyword->uninterned-symbol
|
||||||
|
symbol->keyword
|
||||||
|
;
|
||||||
|
symbol-printname-details
|
||||||
|
symbol-printname=? symbol-printname<?
|
||||||
|
symbol-printname-ci=? symbol-printname-ci<?
|
||||||
|
symbol-printname-length
|
||||||
|
max-symbol-printname-length
|
||||||
|
;
|
||||||
|
module-printname module-printnames)
|
||||||
|
|
||||||
|
(import scheme)
|
||||||
|
(import (chicken base))
|
||||||
|
(import (chicken type))
|
||||||
|
(import (chicken keyword))
|
||||||
|
(import (chicken fixnum))
|
||||||
|
(import (chicken string))
|
||||||
|
(import (srfi 13))
|
||||||
|
|
||||||
|
(cond-expand
|
||||||
|
(chicken-5.0
|
||||||
|
(define-type keyword symbol))
|
||||||
|
(chicken-6.0
|
||||||
|
(define-type keyword symbol))
|
||||||
|
(else))
|
||||||
|
|
||||||
|
(: exploded-qualified-symbol=? (string string string string #!optional boolean --> boolean))
|
||||||
|
(: exploded-qualified-symbol<? (string string string string #!optional boolean --> boolean))
|
||||||
|
|
||||||
|
(: *symbol-printname-details (symbol (or keyword symbol) --> string string))
|
||||||
|
(
|
||||||
|
: ->symbol (* --> symbol))
|
||||||
|
(: ->uninterned-symbol (* -> symbol))
|
||||||
|
|
||||||
|
(: keyword->symbol (keyword --> symbol))
|
||||||
|
(: keyword->uninterned-symbol (keyword -> symbol))
|
||||||
|
(: symbol->keyword ((or keyword symbol) --> keyword))
|
||||||
|
|
||||||
|
(: symbol-printname-details ((or keyword symbol) --> string string))
|
||||||
|
|
||||||
|
(: symbol-printname=? ((or keyword symbol) (or keyword symbol) --> boolean))
|
||||||
|
(: symbol-printname<? ((or keyword symbol) (or keyword symbol) --> boolean))
|
||||||
|
(: symbol-printname-ci=? ((or keyword symbol) (or keyword symbol) --> boolean))
|
||||||
|
(: symbol-printname-ci<? ((or keyword symbol) (or keyword symbol) --> boolean))
|
||||||
|
|
||||||
|
(: symbol-printname-length ((or keyword symbol) #!optional boolean --> fixnum))
|
||||||
|
(: max-symbol-printname-length ((list-of (or keyword symbol)) #!optional boolean --> fixnum))
|
||||||
|
|
||||||
|
(: module-printname (* -> (or false string)))
|
||||||
|
(: module-printnames (* -> (or false (list-of string))))
|
||||||
|
|
||||||
|
;;
|
||||||
|
|
||||||
|
(define (check-keyword loc obj) (##sys#check-keyword obj loc) obj)
|
||||||
|
(define (check-symbol loc obj) (##sys#check-symbol obj loc) obj)
|
||||||
|
(define (check-list loc obj) (##sys#check-list obj loc) obj)
|
||||||
|
|
||||||
|
;;
|
||||||
|
|
||||||
|
(define (exploded-qualified-symbol=? px sx py sy #!optional ci)
|
||||||
|
(if ci
|
||||||
|
(and (string-ci= px py) (string-ci= sx sy))
|
||||||
|
(and (string=? px py) (string=? sx sy)) ) )
|
||||||
|
|
||||||
|
(define (exploded-qualified-symbol<? px sx py sy #!optional ci)
|
||||||
|
(if ci
|
||||||
|
(or (and (string-ci= px py) (string-ci< sx sy))
|
||||||
|
(string-ci< px py))
|
||||||
|
(or (and (string=? px py) (string<? sx sy))
|
||||||
|
(string<? px py)) ) )
|
||||||
|
|
||||||
|
;;
|
||||||
|
|
||||||
|
(define (*symbol-printname-details loc sym)
|
||||||
|
(cond ((keyword? sym) (values (keyword->string sym) ":"))
|
||||||
|
(else (values (symbol->string (check-symbol loc sym)) ""))) )
|
||||||
|
|
||||||
|
;;;
|
||||||
|
|
||||||
|
;;
|
||||||
|
|
||||||
|
(define (->symbol obj)
|
||||||
|
(cond ((symbol? obj) obj )
|
||||||
|
((string? obj) (string->symbol obj) )
|
||||||
|
(else (string->symbol (->string obj)) ) ) )
|
||||||
|
|
||||||
|
(define (->uninterned-symbol obj)
|
||||||
|
(string->uninterned-symbol (cond ((symbol? obj) (symbol->string obj))
|
||||||
|
((string? obj) obj)
|
||||||
|
(else (->string obj)))) )
|
||||||
|
|
||||||
|
;;
|
||||||
|
|
||||||
|
(define (keyword->symbol kwd)
|
||||||
|
(string->symbol (keyword->string (check-keyword 'keyword->symbol kwd))) )
|
||||||
|
|
||||||
|
(define (keyword->uninterned-symbol kwd)
|
||||||
|
(string->uninterned-symbol (keyword->string (check-keyword 'keyword->uninterned-symbol kwd))) )
|
||||||
|
|
||||||
|
;;
|
||||||
|
|
||||||
|
;symbol->string drops namespace qualification!
|
||||||
|
;which means a keyword and a symbol of the same name have the same printname.
|
||||||
|
|
||||||
|
(define (symbol->keyword sym)
|
||||||
|
(cond ((keyword? sym) (the keyword sym))
|
||||||
|
(else (string->keyword (symbol->string sym)) ) ) )
|
||||||
|
|
||||||
|
(define (symbol-printname-details sym)
|
||||||
|
(receive (s p) (*symbol-printname-details 'symbol-printname-details sym)
|
||||||
|
;do not expose the symbol's "raw" printname
|
||||||
|
(values (string-copy s) (string-copy p)) ) )
|
||||||
|
|
||||||
|
;FIXME (forall (a ...) (a a --> boolean))
|
||||||
|
|
||||||
|
(define (symbol-printname=? x y)
|
||||||
|
(let-values (((sx px) (*symbol-printname-details 'symbol-printname=? x))
|
||||||
|
((sy py) (*symbol-printname-details 'symbol-printname=? y)) )
|
||||||
|
(exploded-qualified-symbol=? px sx py sy) ) )
|
||||||
|
|
||||||
|
(define (symbol-printname<? x y)
|
||||||
|
(let-values (((sx px) (*symbol-printname-details 'symbol-printname<? x))
|
||||||
|
((sy py) (*symbol-printname-details 'symbol-printname<? y)) )
|
||||||
|
(exploded-qualified-symbol<? px sx py sy) ) )
|
||||||
|
|
||||||
|
(define (symbol-printname-ci=? x y)
|
||||||
|
(let-values (((sx px) (*symbol-printname-details 'symbol-printname=? x))
|
||||||
|
((sy py) (*symbol-printname-details 'symbol-printname=? y)) )
|
||||||
|
(exploded-qualified-symbol=? px sx py sy #t) ) )
|
||||||
|
|
||||||
|
(define (symbol-printname-ci<? x y)
|
||||||
|
(let-values (((sx px) (*symbol-printname-details 'symbol-printname<? x))
|
||||||
|
((sy py) (*symbol-printname-details 'symbol-printname<? y)) )
|
||||||
|
(exploded-qualified-symbol<? px sx py sy #t) ) )
|
||||||
|
|
||||||
|
;;
|
||||||
|
|
||||||
|
(define (symbol-printname-length sym #!optional (sexp? #f))
|
||||||
|
(cond ((keyword? sym)
|
||||||
|
(let ((l (string-length (keyword->string sym))))
|
||||||
|
(fx+ l (if sexp? 2 1)) ) )
|
||||||
|
(else
|
||||||
|
(string-length (symbol->string (check-symbol 'symbol-printname-length sym))) ) ) )
|
||||||
|
|
||||||
|
(define (max-symbol-printname-length syms #!optional (sexp? #f))
|
||||||
|
(foldl (lambda (mx sm) (fxmax mx (symbol-printname-length sm sexp?))) 0 (check-list 'max-symbol-printname-length syms)) )
|
||||||
|
|
||||||
|
;;
|
||||||
|
|
||||||
|
(define (module-printname obj)
|
||||||
|
;
|
||||||
|
(define (norm-module-printname)
|
||||||
|
(cond ((string? obj) obj)
|
||||||
|
((symbol? obj) (symbol->string obj))
|
||||||
|
((list? obj)
|
||||||
|
(and-let* ((l (foldl
|
||||||
|
(lambda (l s)
|
||||||
|
(and (list? l) (symbol? s) (cons (symbol->string s) l)))
|
||||||
|
'()
|
||||||
|
obj))
|
||||||
|
(l (reverse l)) )
|
||||||
|
(string-concatenate (intersperse l ".")) ) )
|
||||||
|
(else #f)) )
|
||||||
|
;
|
||||||
|
(define (srfi-module-printname)
|
||||||
|
(and (list? obj) (= 2 (length obj))
|
||||||
|
(eq? 'srfi (car obj))
|
||||||
|
(and-let* ((n (cadr obj))
|
||||||
|
((and (integer? n) (not (negative? n)))) )
|
||||||
|
(string-append "srfi-" (number->string n)) ) ) )
|
||||||
|
;
|
||||||
|
(or (srfi-module-printname) (norm-module-printname)) )
|
||||||
|
|
||||||
|
(define (module-printnames obj)
|
||||||
|
(and (list? obj)
|
||||||
|
(and-let* ((l (foldl
|
||||||
|
(lambda (l s)
|
||||||
|
(and (list? l)
|
||||||
|
(and-let* ((m (module-printname s))) (cons m l))) )
|
||||||
|
'()
|
||||||
|
obj)) )
|
||||||
|
(reverse l) ) ) )
|
||||||
|
|
||||||
|
) ;module symbol-name-utils
|
29
symbol-utils.egg
Normal file
29
symbol-utils.egg
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
;;;; symbol-utils.meta -*- Scheme -*-
|
||||||
|
;;;; Kon Lovett, Mar '20
|
||||||
|
;;;; Kon Lovett, Jul '18
|
||||||
|
|
||||||
|
((synopsis "Symbol Utilities")
|
||||||
|
(version "2.6.1")
|
||||||
|
(category data)
|
||||||
|
(author "Kon Lovett")
|
||||||
|
(license "BSD")
|
||||||
|
(dependencies srfi-13)
|
||||||
|
(test-dependencies test test-utils)
|
||||||
|
(components
|
||||||
|
(extension symbol-utils.gen
|
||||||
|
(types-file)
|
||||||
|
(csc-options "-O3" "-d1" "-strict-types" "-no-procedure-checks" "-no-bound-checks") )
|
||||||
|
(extension symbol-lolevel-utils
|
||||||
|
(types-file)
|
||||||
|
(csc-options "-O3" "-d1" "-strict-types" "-no-procedure-checks" "-no-bound-checks") )
|
||||||
|
(extension symbol-name-utils
|
||||||
|
(types-file)
|
||||||
|
;; FIXME: "-strict-types" here breaks *symbol-printname-details.
|
||||||
|
(csc-options "-O2" "-d1" "-no-procedure-checks" "-no-bound-checks") )
|
||||||
|
(extension symbol-value-utils
|
||||||
|
(types-file)
|
||||||
|
(csc-options "-O3" "-d1" "-strict-types" "-no-procedure-checks" "-no-bound-checks") )
|
||||||
|
(extension symbol-utils
|
||||||
|
(types-file)
|
||||||
|
(component-dependencies symbol-utils.gen symbol-lolevel-utils symbol-name-utils symbol-value-utils)
|
||||||
|
(csc-options "-O3" "-d1" "-strict-types" "-no-procedure-checks" "-no-bound-checks") ) ) )
|
30
symbol-utils.gen.scm
Normal file
30
symbol-utils.gen.scm
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
;;;; symbol-utils.gen.scm -*- Scheme -*-
|
||||||
|
;;;; Kon Lovett, Oct '22
|
||||||
|
|
||||||
|
;"atomic"
|
||||||
|
(declare (disable-interrupts))
|
||||||
|
|
||||||
|
(module (symbol-utils gen)
|
||||||
|
|
||||||
|
(;export
|
||||||
|
make-gensym)
|
||||||
|
|
||||||
|
(import scheme (chicken base) (chicken type))
|
||||||
|
|
||||||
|
(: make-gensym ((or symbol string) -> (#!optional (or symbol string) -> symbol)))
|
||||||
|
|
||||||
|
(define (str-or-sym loc tag)
|
||||||
|
(cond ((not tag) "")
|
||||||
|
((symbol? tag) (symbol->string tag))
|
||||||
|
((string? tag) tag)
|
||||||
|
(else (error loc "bad argument - not a string or symbol" tag))) )
|
||||||
|
|
||||||
|
(define (make-gensym bas)
|
||||||
|
(letrec ((+bas+ (str-or-sym 'make-gensym bas))
|
||||||
|
(+cnt+ 0)
|
||||||
|
(cnt++ (lambda () (let ((cnt +cnt+)) (set! +cnt+ (+ +cnt+ 1)) cnt))) )
|
||||||
|
(lambda (#!optional tag)
|
||||||
|
(string->uninterned-symbol
|
||||||
|
(string-append +bas+ (str-or-sym 'make-gensym tag) (number->string (cnt++)))) ) ) )
|
||||||
|
|
||||||
|
) ;module (symbol-utils gen)
|
4
symbol-utils.release-info
Normal file
4
symbol-utils.release-info
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
;; -*- Scheme -*-
|
||||||
|
(repo git "https://gitea.lyrion.ch/Chicken/symbol-utils")
|
||||||
|
(uri targz "https://gitea.lyrion.ch/Chicken/symbol-utils/archive/{egg-release}.tar.gz")
|
||||||
|
(release "2.6.1") ;; Port to Chicken 6
|
15
symbol-utils.scm
Normal file
15
symbol-utils.scm
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
;;;; symbol-utils.scm -*- Scheme -*-
|
||||||
|
;;;; Kon Lovett, Mar '20
|
||||||
|
;;;; Kon Lovett, Jul '18
|
||||||
|
;;;; Kon Lovett, Aug '17
|
||||||
|
;;;; Kon Lovett, Aug '10
|
||||||
|
|
||||||
|
(module symbol-utils ()
|
||||||
|
|
||||||
|
(import scheme)
|
||||||
|
(import (chicken module))
|
||||||
|
(import (symbol-utils gen) symbol-name-utils symbol-value-utils symbol-lolevel-utils)
|
||||||
|
|
||||||
|
(reexport (symbol-utils gen) symbol-name-utils symbol-value-utils symbol-lolevel-utils)
|
||||||
|
|
||||||
|
) ;module symbol-utils
|
59
symbol-value-utils.scm
Normal file
59
symbol-value-utils.scm
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
;;;; symbol-value-utils.scm -*- Scheme -*-
|
||||||
|
;;;; Kon Lovett, Mar '20
|
||||||
|
;;;; Kon Lovett, Jul '18
|
||||||
|
|
||||||
|
(declare
|
||||||
|
(bound-to-procedure ##sys#slot))
|
||||||
|
|
||||||
|
(module symbol-value-utils
|
||||||
|
|
||||||
|
(;export
|
||||||
|
;Compiled Use Only
|
||||||
|
unbound-value? unbound?
|
||||||
|
symbol-value
|
||||||
|
;
|
||||||
|
unspecified-value ;FIXME suspicious much?
|
||||||
|
unspecified-value? unspecified?)
|
||||||
|
|
||||||
|
(import scheme)
|
||||||
|
(import (chicken base))
|
||||||
|
(import (chicken syntax))
|
||||||
|
(import (chicken foreign))
|
||||||
|
|
||||||
|
;; Unbound
|
||||||
|
|
||||||
|
(define-syntax unbound-value?
|
||||||
|
(syntax-rules ()
|
||||||
|
((unbound-value? ?val)
|
||||||
|
(##core#inline "C_unboundvaluep" ?val) ) ) )
|
||||||
|
|
||||||
|
(define-syntax unbound?
|
||||||
|
(syntax-rules ()
|
||||||
|
((unbound? ?sym)
|
||||||
|
(unbound-value? (##sys#slot ?sym 0)) ) ) )
|
||||||
|
|
||||||
|
(define-syntax symbol-value
|
||||||
|
(syntax-rules ()
|
||||||
|
;
|
||||||
|
((symbol-value ?sym ?def)
|
||||||
|
(let ((val (##sys#slot ?sym 0)))
|
||||||
|
(if (unbound-value? val) ?def val) ) )
|
||||||
|
;
|
||||||
|
((symbol-value ?sym)
|
||||||
|
(symbol-value ?sym #f) ) ) )
|
||||||
|
|
||||||
|
;; Undefined
|
||||||
|
|
||||||
|
(define unspecified-value void)
|
||||||
|
|
||||||
|
(define-syntax unspecified-value?
|
||||||
|
(syntax-rules ()
|
||||||
|
((unspecified-value? ?val)
|
||||||
|
(eq? (unspecified-value) ?val) ) ) )
|
||||||
|
|
||||||
|
(define-syntax unspecified?
|
||||||
|
(syntax-rules ()
|
||||||
|
((unspecified? ?obj)
|
||||||
|
(unspecified-value? ?obj) ) ) )
|
||||||
|
|
||||||
|
) ;module symbol-value-utils
|
4
tests/run.scm
Normal file
4
tests/run.scm
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
;;;; run.scm -*- Scheme -*-
|
||||||
|
|
||||||
|
(import (test-utils run))
|
||||||
|
(run-tests-for "symbol-utils")
|
92
tests/symbol-utils-test.scm
Normal file
92
tests/symbol-utils-test.scm
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
;;;; symbol-utils-test.scm -*- Scheme -*-
|
||||||
|
;;;; Kon Lovett, Jul '18
|
||||||
|
|
||||||
|
(import test)
|
||||||
|
|
||||||
|
(test-begin "Symbol Utils")
|
||||||
|
|
||||||
|
;;;
|
||||||
|
|
||||||
|
(import symbol-utils)
|
||||||
|
|
||||||
|
(test-group "value"
|
||||||
|
(cond-expand
|
||||||
|
(compiling
|
||||||
|
(test-assert (symbol-value symbol->keyword)) )
|
||||||
|
(else) )
|
||||||
|
(test-assert (unspecified? (unspecified-value)))
|
||||||
|
)
|
||||||
|
|
||||||
|
(test-group "keyword"
|
||||||
|
(test 'foo (keyword->symbol #:foo))
|
||||||
|
(test "foo" (symbol->string (keyword->uninterned-symbol #:foo)))
|
||||||
|
(test #:foo (symbol->keyword 'foo))
|
||||||
|
)
|
||||||
|
|
||||||
|
(test-group "printname"
|
||||||
|
(test-assert (symbol-printname=? 'foo 'foo))
|
||||||
|
(test-assert (not (symbol-printname=? 'foo 'bar)))
|
||||||
|
(test-assert (symbol-printname=? '##sys#list->string '##sys#list->string))
|
||||||
|
(test-assert (not (symbol-printname=? '##sys#list->string 'list->string)))
|
||||||
|
|
||||||
|
(test-assert (not (symbol-printname<? 'foo 'foo)))
|
||||||
|
(test-assert (symbol-printname<? 'bar 'foo))
|
||||||
|
(test-assert (not (symbol-printname<? '##sys#list->string '##sys#list->string)))
|
||||||
|
#;(test-assert (symbol-printname<? 'list->string '##sys#list->string))
|
||||||
|
|
||||||
|
(test-assert (symbol-printname-ci=? 'foo 'FOO))
|
||||||
|
(test-assert (not (symbol-printname-ci=? 'foo 'BAR)))
|
||||||
|
(test-assert (symbol-printname-ci=? '##sys#list->string '##sys#list->STRING))
|
||||||
|
(test-assert (not (symbol-printname-ci=? '##sys#list->string 'list->STRING)))
|
||||||
|
|
||||||
|
(test-assert (not (symbol-printname-ci<? 'foo 'FOO)))
|
||||||
|
(test-assert (symbol-printname-ci<? 'bar 'FOO))
|
||||||
|
(test-assert (not (symbol-printname-ci<? '##sys#list->string '##sys#list->STRING)))
|
||||||
|
#;(test-assert (symbol-printname-ci<? 'list->string '##sys#list->STRING))
|
||||||
|
|
||||||
|
(test 3 (symbol-printname-length 'foo))
|
||||||
|
(test 4 (symbol-printname-length #:foo))
|
||||||
|
(test 5 (symbol-printname-length #:foo #t))
|
||||||
|
|
||||||
|
(test 0 (max-symbol-printname-length '()))
|
||||||
|
(test 3 (max-symbol-printname-length '(a abc ab)))
|
||||||
|
(test 5 (max-symbol-printname-length '(a abc ab #:foo) #t))
|
||||||
|
)
|
||||||
|
|
||||||
|
(test-group "module printname"
|
||||||
|
(test-assert "must be list" (not (module-printnames "abc")))
|
||||||
|
(test-assert "not a #" (not (module-printnames '(a 23 "c"))))
|
||||||
|
(test-assert "xplody must be symbol" (not (module-printnames '(a (b "c") "d"))))
|
||||||
|
(test-assert "no negatives" (not (module-printnames '(a (srfi -8) "d"))))
|
||||||
|
(let ((mns (module-printnames '((foo bar baz) foo (srfi 0)))))
|
||||||
|
(test "xplody" "foo.bar.baz" (car mns))
|
||||||
|
(test "just a'" "foo" (cadr mns))
|
||||||
|
(test "special" "srfi-0" (caddr mns)) )
|
||||||
|
)
|
||||||
|
|
||||||
|
#;
|
||||||
|
(test-group "qualified"
|
||||||
|
(test '##foo#bar (make-qualified-symbol "foo" 'bar))
|
||||||
|
(test-assert (qualified-symbol? '##sys#list->string))
|
||||||
|
(test-assert (not (qualified-symbol? 'sym)))
|
||||||
|
(test "##sys#list->string" (symbol->qualified-string '##sys#list->string))
|
||||||
|
(test "list->string" (symbol->qualified-string 'list->string))
|
||||||
|
(test-assert (not (interned-symbol? (make-qualified-uninterned-symbol "bar" 'foo))))
|
||||||
|
)
|
||||||
|
|
||||||
|
(test-group "interned"
|
||||||
|
(test-assert (interned-symbol? 'foo))
|
||||||
|
(test-assert (not (interned-symbol? (gensym))))
|
||||||
|
)
|
||||||
|
|
||||||
|
(test-group "gensym"
|
||||||
|
(let ((gen (make-gensym 'test)))
|
||||||
|
(test "gen 0" "test0" (symbol->string (gen)))
|
||||||
|
(test "gen 1" "testfoo1" (symbol->string (gen 'foo))) )
|
||||||
|
)
|
||||||
|
|
||||||
|
;;;
|
||||||
|
|
||||||
|
(test-end "Symbol Utils")
|
||||||
|
|
||||||
|
(test-exit)
|
Loading…
Reference in a new issue