Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion src/LispSyntax.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module LispSyntax

include("parser.jl")
export sx, desx, codegen, @lisp_str, assign_reader_dispatch
export sx, desx, codegen, @lisp_str, assign_reader_dispatch, include_lisp

# Internal types
mutable struct s_expr
Expand Down Expand Up @@ -158,4 +158,27 @@ macro lisp_str(str)
return esc(lisp_eval_helper(str))
end


"""
include_lisp(mod, source)

Parse expressions from `source` (which may be an `IO` or file name) and
evaluate them sequentially as top level code in module `mod`.
"""
function include_lisp(mod::Module, filename::AbstractString)
open(filename) do io
include_lisp(mod, io)
end
end

function include_lisp(mod::Module, io::IO)
content = Base.read(io, String)
res = nothing
for sxpr in parse_one(content, top_level)
ex = codegen(desx(sxpr))
res = Base.eval(mod, ex)
end
res
end

end # module
2 changes: 2 additions & 0 deletions src/parser.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ expr.matcher = doubley | floaty | inty | uchary | achary | chary | stringy | boo
macrosymy | dispatchy | sexpr | hashy | curly | bracket |
quot | quasi | tildeseq | tilde

top_level = Repeat(~opt_ws + expr) + ~opt_ws + Eos()

function read(str)
x = parse_one(str, expr)
x[1]
Expand Down
9 changes: 9 additions & 0 deletions test/lisp.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
; File containing top level Clojure-syntax code

(defn func_in_clj_file [x y] (string "x = " x "; y = " y))

(def some_global 1.23f)

; Following should be the return value of include_lisp
(let [not_a_global 10]
(* not_a_global not_a_global))
41 changes: 25 additions & 16 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -252,23 +252,32 @@ end

#-------------------------------------------------------------------------------
lisp"(import ParserCombinator)"
@testset "Import" begin
@test lisp"(@E_str \"S\")" == E"S"
end
@test lisp"(@E_str \"S\")" == E"S"

#-------------------------------------------------------------------------------
@testset "Bug reports" begin
@test lisp"""(def game_map (Dict
(=> 'living_room
'((you are in the living room
of a wizards house - there is a wizard
snoring loudly on the couch -)
(west door garden)
(upstairs stairway attic)))))""" ==
Dict(:living_room =>
Any[ Any[ :you, :are, :in, :the, :living, :room, :of, :a, :wizards, :house, :-,
:there, :is, :a, :wizard, :snoring, :loudly, :on, :the, :couch, :- ],
Any[ :west, :door, :garden ],
Any[ :upstairs, :stairway, :attic ] ])
@testset "Include from file" begin
# Return value is value of last expression
@test include_lisp(@__MODULE__, "lisp.clj") == 100
# Test objects defined in lisp.clj
@test func_in_clj_file(1, 2) == "x = 1; y = 2"
@test func_in_clj_file(10, 20) == "x = 10; y = 20"
@test some_global === 1.23f0
@test !isdefined(@__MODULE__, :not_a_global)
end

# ----------------------------------------------------------------------------------------------------------------------
# Bug reports
# ----------------------------------------------------------------------------------------------------------------------
@test lisp"""(def game_map (Dict
(=> 'living_room
'((you are in the living room
of a wizards house - there is a wizard
snoring loudly on the couch -)
(west door garden)
(upstairs stairway attic)))))""" == Dict(:living_room =>
Any[ Any[ :you, :are, :in, :the, :living, :room, :of, :a, :wizards, :house, :-,
:there, :is, :a, :wizard, :snoring, :loudly, :on, :the, :couch, :- ],
Any[ :west, :door, :garden ],
Any[ :upstairs, :stairway, :attic ] ])