1
0
mirror of https://github.com/janet-lang/janet synced 2025-02-02 10:19:10 +00:00

Fix bug in compiler with if form under certain conditions.

Begin bundled 'cook' tool for managing janet projects.
This commit is contained in:
Calvin Rose 2018-12-25 15:32:42 -05:00
parent 2c94aa1a6a
commit 17283241ab
8 changed files with 136 additions and 72 deletions

View File

@ -1,44 +0,0 @@
# Copyright (c) 2018 Calvin Rose
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
CFLAGS:=-std=c99 -Wall -Wextra -O2 -shared -fpic
CFLAGS=-std=c99 -Wall -Wextra -I../../src/include -O2 -shared -fpic
OBJECTS:=json.o
TARGET:=json.so
# MacOS specifics
UNAME:=$(shell uname -s)
ifeq ($(UNAME), Darwin)
CFLAGS:=$(CFLAGS) -undefined dynamic_lookup
endif
all: $(TARGET)
%.o: %.c $(HEADERS)
$(CC) $(CFLAGS) -c $<
$(TARGET): $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $^
clean:
rm $(OBJECTS)
rm $(TARGET)
.PHONY: all clean

5
natives/json/build.janet Normal file
View File

@ -0,0 +1,5 @@
(import cook)
(cook/make-native
:name "json"
:source ["json.c"])

View File

@ -1,25 +0,0 @@
@rem Generated batch script, run in 'Visual Studio Developer Prompt'
@rem
@echo off
cl /nologo /I..\..\src\include /c /O2 /W3 json.c
@if errorlevel 1 goto :BUILDFAIL
link /nologo /dll ..\..\janet.lib /out:json.dll *.obj
if errorlevel 1 goto :BUILDFAIL
@echo .
@echo ======
@echo Build Succeeded.
@echo =====
exit /b 0
:BUILDFAIL
@echo .
@echo =====
@echo BUILD FAILED. See Output For Details.
@echo =====
@echo .
exit /b 1

View File

@ -196,7 +196,7 @@ static const char *decode_one(const char **p, Janet *out, int depth) {
if (cp[1] != 'u' || cp[2] != 'l' || cp[3] != 'l') if (cp[1] != 'u' || cp[2] != 'l' || cp[3] != 'l')
goto badident; goto badident;
*out = janet_wrap_nil(); *out = janet_csymbolv(":null");
*p = cp + 4; *p = cp + 4;
break; break;
} }

View File

@ -233,6 +233,22 @@
(array/concat accum body) (array/concat accum body)
(tuple/slice accum 0)) (tuple/slice accum 0))
(defmacro try
"Try something and catch errors. Body is any expression,
and catch should be a form with the first element a tuple. This tuple
should contain a binding for errors and an optional binding for
the fiber wrapping the body. Returns the result of body if no error,
or the result of catch if an error."
[body catch]
(let [[[err fib]] catch
f (gensym)
r (gensym)]
~(let [,f (,fiber/new (fn [] ,body) :e)
,r (resume ,f)]
(if (= (,fiber/status ,f) :error)
(do (def ,err ,r) ,(if fib ~(def ,fib ,f)) ,;(tuple/slice catch 1))
,r))))
(defmacro and (defmacro and
"Evaluates to the last argument if all preceding elements are true, otherwise "Evaluates to the last argument if all preceding elements are true, otherwise
evaluates to false." evaluates to false."

View File

@ -369,8 +369,9 @@ static JanetSlot janetc_if(JanetFopts opts, int32_t argn, const Janet *argv) {
falsebody = truebody; falsebody = truebody;
truebody = temp; truebody = temp;
} }
janetc_scope(&tempscope, c, 0, "if-body"); janetc_scope(&tempscope, c, 0, "if-true");
target = janetc_value(bodyopts, truebody); right = janetc_value(bodyopts, truebody);
if (!drop && !tail) janetc_copy(c, target, right);
janetc_popscope(c); janetc_popscope(c);
janetc_throwaway(bodyopts, falsebody); janetc_throwaway(bodyopts, falsebody);
janetc_popscope(c); janetc_popscope(c);

View File

@ -46,4 +46,11 @@
@[x y] (+ x y 10) @[x y] (+ x y 10)
0)) "match 3") 0)) "match 3")
# Edge case should cause old compilers to fail due to
# if statement optimization
(var var-a 1)
(var var-b (if false 2 (string "hello")))
(assert (= var-b "hello") "regression 1")
(end-suite) (end-suite)

104
tools/cook.janet Normal file
View File

@ -0,0 +1,104 @@
# Library to help build janet natives and other
# build artifacts.
# Windows is the OS outlier
(def- is-win (= (os/which) :windows))
(defn- shell
"Do a shell command"
[& args]
(print ;args)
(def res (os/shell (string ;args)))
(unless (zero? res)
(print "Error executing command: " ;args)
(os/exit res)))
(defn- mkdir
"Make a directory. Not safe for user code."
[path]
(if is-win
(shell "mkdir " path)
(shell "mkdir -p " path)))
(defn- rm
"Remove a directory. Not safe for user code."
[path]
(if is-win
(shell "rmdir " path " /s")
(shell "rm -rf " path)))
(defn- object-name
"Rename a source file so it can be built in a flat source tree."
[path]
(if is-win
(->> path
(string/replace-all "\\" "___")
(string/replace-all ".c" ".obj")
(string "build\\")))
(->> path
(string/replace-all "/" "___")
(string/replace-all ".c" ".o")
(string "build/")))
(defn- lib-name
"Generate name for dynamic library."
[name]
(if is-win
(string "build\\" name ".dll")
(string "build/" name ".so")))
# Defaults
(def OPTIMIZE 2)
(def CC (if is-win "cl" "cc"))
(def LD (if is-win "link" (string CC " -shared")))
(def CFLAGS (string (if is-win "/0" "-std=c99 -Wall -Wextra -fpic -O") OPTIMIZE))
(defn- compile-c
"Compile a C file into an object file."
[opts src dest]
(def cc (or opts:compiler CC))
(def cflags (or opts:cflags CFLAGS))
(if is-win
(shell cc " /nologo /c " cflags " /Fo" dest " " src)
(shell cc " " cflags " -o " dest " -c " src)))
(defn- link-c
"Link a number of object files together."
[opts target & objects]
(def ld (or opts:linker LD))
(def cflags (or opts:cflags CFLAGS))
(def olist (string/join objects " "))
(if is-win
(shell ld "/out:" target " " olist)
(shell ld " " cflags " -o " target " " olist)))
# Public
(defn make-native
"Build a native binary. This is a shared library that can be loaded
dynamically by a janet runtime."
[& opts]
(def opt-table (table ;opts))
(mkdir "build")
(loop [src :in opt-table:source]
(compile-c opt-table src (object-name src)))
(link-c opt-table (lib-name opt-table:name) ;(map object-name opt-table:source)))
(defn clean
"Remove all built artifacts."
[]
(rm "build"))
(defn make-archive
"Build a janet archive. This is a file that bundles together many janet
scripts into a janet form. This file can the be moved to any machine with
a janet vm and the required dependencies and run there."
[& opts]
(error "Not Yet Implemented."))
(defn make-binary
"Make a binary executable that can be run on the current platform. This function
generates a self contained binary that can be run of the same architecture as the
build machine, as the current janet vm will be packaged with the output binary."
[& opts]
(error "Not Yet Implemented."))