mirror of
https://github.com/vonhyou/lisp-interpreter.git
synced 2025-06-08 02:02:01 +00:00
fix env and write a module for futuer update
This commit is contained in:
parent
1ea52e195f
commit
d0863d1636
1 changed files with 94 additions and 97 deletions
75
prol.rb
75
prol.rb
|
@ -9,29 +9,26 @@
|
||||||
# :atom
|
# :atom
|
||||||
#####
|
#####
|
||||||
|
|
||||||
def parse(program)
|
module Lisp
|
||||||
|
|
||||||
|
def self.parse(program)
|
||||||
read_tokens(tokenize(program))
|
read_tokens(tokenize(program))
|
||||||
end
|
end
|
||||||
|
|
||||||
def tokenize(program)
|
def self.tokenize(program)
|
||||||
# Convert scripts to token lists
|
# Convert scripts to token lists
|
||||||
program.gsub('(', ' ( ').gsub(')', ' ) ').split
|
program.gsub('(', ' ( ').gsub(')', ' ) ').split
|
||||||
end
|
end
|
||||||
|
|
||||||
def make_list(tokens)
|
def self.read_tokens(tokens, lst = [])
|
||||||
lst = []
|
|
||||||
lst << read_tokens(tokens) while tokens[0] != ')'
|
|
||||||
tokens.shift
|
|
||||||
lst
|
|
||||||
end
|
|
||||||
|
|
||||||
def read_tokens(tokens)
|
|
||||||
# read expressions from token
|
# read expressions from token
|
||||||
raise SyntaxError, 'Unexpected EOF' if tokens.empty?
|
raise SyntaxError, 'Unexpected EOF' if tokens.empty?
|
||||||
|
|
||||||
case token = tokens.shift
|
case token = tokens.shift
|
||||||
when '('
|
when '('
|
||||||
make_list tokens
|
lst << read_tokens(tokens) while tokens[0] != ')'
|
||||||
|
tokens.shift
|
||||||
|
lst
|
||||||
when ')'
|
when ')'
|
||||||
raise SyntaxError, "Unexpected ')'"
|
raise SyntaxError, "Unexpected ')'"
|
||||||
else
|
else
|
||||||
|
@ -39,7 +36,7 @@ def read_tokens(tokens)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def atom(token)
|
def self.atom(token)
|
||||||
# Analyse numbers and symbols
|
# Analyse numbers and symbols
|
||||||
case token
|
case token
|
||||||
when /\d/
|
when /\d/
|
||||||
|
@ -51,28 +48,27 @@ end
|
||||||
|
|
||||||
##### Environments
|
##### Environments
|
||||||
|
|
||||||
$global_env = {
|
def self.make_global
|
||||||
'+': ->(args) { args.sum }, # args.inject(0, :+)
|
@global_env ||= begin
|
||||||
'-': ->(*args) { eval args.join('-') },
|
ops = %i[== != < <= > >= + - * /]
|
||||||
'*': ->(*args) { eval args.join('*') },
|
ops.inject({}) do |scope, op|
|
||||||
'/': ->(*args) { eval args.join('/') },
|
scope.merge op => ->(*args) { args.inject(&op) }
|
||||||
'>': ->(args) { args[0] > args[1] },
|
end
|
||||||
'<': ->(args) { args[0] < args[1] },
|
end
|
||||||
'=': ->(args) { args[0] == args[1] },
|
# @global_env.merge {
|
||||||
'>=': ->(args) { args[0] >= args[1] },
|
# 'min' : ->(*args) { args.min },
|
||||||
'<=': ->(args) { args[0] <= args[1] },
|
# 'max' : ->(*args) { args.max },
|
||||||
'min': ->(*args) { args.min },
|
# 'car' : ->(arr) { arr[0] },
|
||||||
'max': ->(*args) { args.max },
|
# 'cdr' : ->(arr) { arr[1..-1] },
|
||||||
'car': ->(arr) { arr[0] },
|
# 'cons' : ->(arr) { arr },
|
||||||
'cdr': ->(arr) { arr[1..-1] },
|
# 'quote' : ->(arr) { arr },
|
||||||
'cons': ->(arr) { arr },
|
# 'print' : ->(arg) { p arg },
|
||||||
'quote': ->(arr) { arr },
|
# 'begin' : ->(*_args) { true }
|
||||||
'print': ->(arg) { p arg },
|
# }
|
||||||
'begin': ->(*_args) { true }
|
end
|
||||||
}
|
|
||||||
|
|
||||||
##### Lisp Eval
|
##### Lisp Eval
|
||||||
def lisp_eval(elem, env = $global_env)
|
def self.lisp_eval(elem, env = make_global)
|
||||||
if elem.instance_of? Symbol
|
if elem.instance_of? Symbol
|
||||||
env[elem]
|
env[elem]
|
||||||
elsif elem.instance_of?(Integer) || elem.instance_of?(Float)
|
elsif elem.instance_of?(Integer) || elem.instance_of?(Float)
|
||||||
|
@ -94,20 +90,20 @@ def lisp_eval(elem, env = $global_env)
|
||||||
elsif elem[0] == :not
|
elsif elem[0] == :not
|
||||||
!lisp_eval(elem[1], env)
|
!lisp_eval(elem[1], env)
|
||||||
else
|
else
|
||||||
args = []
|
func, *args = elem.map { |e| lisp_eval e, env }
|
||||||
elem[1..-1].each { |arg| args << lisp_eval(arg, env) }
|
func.call *args
|
||||||
p lisp_eval(elem[0], env)
|
|
||||||
lisp_eval(elem[0], env).call args
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# (def fib (lambda (n) (if (<= n 2) 1 (+ (fib (- n 1)) (fib (- n 2))))))
|
||||||
|
|
||||||
$copyleft = "Copyleft (Ↄ) 2021 vonhyou@lenva.tech
|
$copyleft = "Copyleft (Ↄ) 2021 vonhyou@lenva.tech
|
||||||
(PRO)cessor of (L)ist for Mathematical Calculation
|
(PRO)cessor of (L)ist for Mathematical Calculation
|
||||||
This is an open source software, you can view its source code on github:
|
This is an open source software, you can view its source code on github:
|
||||||
https://github.com/vonhyou/lisp-interpreter\n\n"
|
https://github.com/vonhyou/lisp-interpreter\n\n"
|
||||||
|
|
||||||
##### REPL
|
##### REPL
|
||||||
def repl(prompt = 'prol ƛ>> ')
|
def self.repl(prompt = 'prol ƛ>> ')
|
||||||
puts $copyleft
|
puts $copyleft
|
||||||
loop do
|
loop do
|
||||||
print prompt
|
print prompt
|
||||||
|
@ -117,8 +113,9 @@ def repl(prompt = 'prol ƛ>> ')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def print_value(value)
|
def self.print_value(value)
|
||||||
puts ";Value: #{value}"
|
puts ";Value: #{value}"
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
repl
|
Lisp.repl
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue