Files
el/lang/tools/new-project.sh
T
2026-05-05 01:38:51 -05:00

165 lines
3.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# new-project.sh — scaffold a new El project.
#
# Usage:
# ./tools/new-project.sh <project-name>
#
# Creates:
# <project-name>/
# src/main.el — hello world entry point
# build.sh — build script using elc + el_runtime.c
# README.md — minimal project docs
set -euo pipefail
if [[ $# -lt 1 ]]; then
echo "Usage: $0 <project-name>" >&2
exit 1
fi
NAME="$1"
if [[ -e "${NAME}" ]]; then
echo "Error: '${NAME}' already exists." >&2
exit 1
fi
# Discover elc — prefer PATH, fall back to the local foundation/el tree
ELC="elc"
if ! command -v elc >/dev/null 2>&1; then
# Try a sibling or parent path convention
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOCAL_ELC="${SCRIPT_DIR}/../dist/platform/elc"
if [[ -x "${LOCAL_ELC}" ]]; then
ELC="$(cd "$(dirname "${LOCAL_ELC}")" && pwd)/$(basename "${LOCAL_ELC}")"
else
echo "Warning: elc not found in PATH or at ${LOCAL_ELC}" >&2
echo " The generated build.sh may need manual adjustment." >&2
ELC="elc"
fi
fi
# Discover el_runtime.c
EL_RUNTIME=""
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOCAL_RUNTIME="${SCRIPT_DIR}/../el-compiler/runtime/el_runtime.c"
if [[ -f "${LOCAL_RUNTIME}" ]]; then
EL_RUNTIME="$(cd "$(dirname "${LOCAL_RUNTIME}")" && pwd)/$(basename "${LOCAL_RUNTIME}")"
EL_INCLUDE="$(dirname "${EL_RUNTIME}")"
else
# Check installed location
if [[ -f "/usr/local/el/lib/libel.a" ]]; then
EL_RUNTIME_LINK="-L/usr/local/el/lib -lel"
EL_INCLUDE="/usr/local/el/include"
fi
EL_RUNTIME="${EL_RUNTIME_LINK:-}"
fi
echo "==> Scaffolding El project: ${NAME}"
mkdir -p "${NAME}/src" "${NAME}/dist"
# src/main.el
cat > "${NAME}/src/main.el" <<'ELEOF'
// main.el — entry point for this El program.
fn run() -> String {
println("hello from El!")
return ""
}
run()
ELEOF
# build.sh — adapts to whether we found elc/runtime locally or installed
if [[ -n "${EL_RUNTIME}" && -f "${EL_RUNTIME}" ]]; then
# Local source tree runtime
EL_INCLUDE_DIR="$(dirname "${EL_RUNTIME}")"
cat > "${NAME}/build.sh" <<BUILDEOF
#!/usr/bin/env bash
# build.sh — build ${NAME}
set -euo pipefail
ELC="${ELC}"
EL_RUNTIME="${EL_RUNTIME}"
EL_INCLUDE="${EL_INCLUDE_DIR}"
mkdir -p dist
echo "==> Compiling El -> C"
"\${ELC}" src/main.el > dist/main.c
echo "==> Compiling C -> binary"
cc -std=c11 -O2 -I"\${EL_INCLUDE}" -o dist/${NAME} dist/main.c "\${EL_RUNTIME}" -lcurl -lpthread
echo "==> Built: dist/${NAME}"
BUILDEOF
else
# Installed framework
cat > "${NAME}/build.sh" <<BUILDEOF
#!/usr/bin/env bash
# build.sh — build ${NAME}
# Requires El installed via tools/install.sh (elc in PATH, /usr/local/el/lib/libel.a)
set -euo pipefail
ELC="\${ELC:-elc}"
EL_PREFIX="\${EL_HOME:-/usr/local/el}"
mkdir -p dist
echo "==> Compiling El -> C"
"\${ELC}" src/main.el > dist/main.c
echo "==> Compiling C -> binary"
cc -std=c11 -O2 -I"\${EL_PREFIX}/include" -o dist/${NAME} dist/main.c -L"\${EL_PREFIX}/lib" -lel -lcurl -lpthread
echo "==> Built: dist/${NAME}"
BUILDEOF
fi
chmod +x "${NAME}/build.sh"
# README.md
cat > "${NAME}/README.md" <<READMEEOF
# ${NAME}
An El language project.
## Build
\`\`\`bash
./build.sh
\`\`\`
## Run
\`\`\`bash
./dist/${NAME}
\`\`\`
## Structure
\`\`\`
src/main.el — entry point
build.sh — build script
dist/ — compiled output (gitignored)
\`\`\`
READMEEOF
# .gitignore
cat > "${NAME}/.gitignore" <<'IGNEOF'
dist/
*.c
IGNEOF
echo
echo "==> Created ${NAME}/"
echo " src/main.el"
echo " build.sh"
echo " README.md"
echo " .gitignore"
echo
echo "To build:"
echo " cd ${NAME} && ./build.sh"
echo