Skip to content

Commit 40d4ba3

Browse files
authored
Merge pull request #24 from swadey/cjf/include-from-file
Implement `include_lisp` to eval multiple top level exprs from file.
2 parents f22171a + 5b16aa4 commit 40d4ba3

File tree

4 files changed

+60
-17
lines changed

4 files changed

+60
-17
lines changed

src/LispSyntax.jl

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module LispSyntax
22

33
include("parser.jl")
4-
export sx, desx, codegen, @lisp_str, assign_reader_dispatch
4+
export sx, desx, codegen, @lisp_str, assign_reader_dispatch, include_lisp
55

66
# Internal types
77
mutable struct s_expr
@@ -158,4 +158,27 @@ macro lisp_str(str)
158158
return esc(lisp_eval_helper(str))
159159
end
160160

161+
162+
"""
163+
include_lisp(mod, source)
164+
165+
Parse expressions from `source` (which may be an `IO` or file name) and
166+
evaluate them sequentially as top level code in module `mod`.
167+
"""
168+
function include_lisp(mod::Module, filename::AbstractString)
169+
open(filename) do io
170+
include_lisp(mod, io)
171+
end
172+
end
173+
174+
function include_lisp(mod::Module, io::IO)
175+
content = Base.read(io, String)
176+
res = nothing
177+
for sxpr in parse_one(content, top_level)
178+
ex = codegen(desx(sxpr))
179+
res = Base.eval(mod, ex)
180+
end
181+
res
182+
end
183+
161184
end # module

src/parser.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ expr.matcher = doubley | floaty | inty | uchary | achary | chary | stringy | boo
3737
macrosymy | dispatchy | sexpr | hashy | curly | bracket |
3838
quot | quasi | tildeseq | tilde
3939

40+
top_level = Repeat(~opt_ws + expr) + ~opt_ws + Eos()
41+
4042
function read(str)
4143
x = parse_one(str, expr)
4244
x[1]

test/lisp.clj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
; File containing top level Clojure-syntax code
2+
3+
(defn func_in_clj_file [x y] (string "x = " x "; y = " y))
4+
5+
(def some_global 1.23f)
6+
7+
; Following should be the return value of include_lisp
8+
(let [not_a_global 10]
9+
(* not_a_global not_a_global))

test/runtests.jl

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -252,23 +252,32 @@ end
252252

253253
#-------------------------------------------------------------------------------
254254
lisp"(import ParserCombinator)"
255-
@testset "Import" begin
256-
@test lisp"(@E_str \"S\")" == E"S"
257-
end
255+
@test lisp"(@E_str \"S\")" == E"S"
258256

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

268+
# ----------------------------------------------------------------------------------------------------------------------
269+
# Bug reports
270+
# ----------------------------------------------------------------------------------------------------------------------
271+
@test lisp"""(def game_map (Dict
272+
(=> 'living_room
273+
'((you are in the living room
274+
of a wizards house - there is a wizard
275+
snoring loudly on the couch -)
276+
(west door garden)
277+
(upstairs stairway attic)))))""" == Dict(:living_room =>
278+
Any[ Any[ :you, :are, :in, :the, :living, :room, :of, :a, :wizards, :house, :-,
279+
:there, :is, :a, :wizard, :snoring, :loudly, :on, :the, :couch, :- ],
280+
Any[ :west, :door, :garden ],
281+
Any[ :upstairs, :stairway, :attic ] ])
282+
283+

0 commit comments

Comments
 (0)