From ccfa109b06e3fe358de0baddd25a7f43f0c08872 Mon Sep 17 00:00:00 2001 From: Christian Barthel Date: Sun, 4 Aug 2019 09:26:13 +0200 Subject: [PATCH] literature, attchment material, general comments i've added some literature that seems to be interesting. furthermore, i've updated the comments about what's actually working. --- attachment/awk_lisp.tgz | Bin 0 -> 24265 bytes attachment/faq-doc-6.txt | 77 ++++++++++ attachment/lis.py | 145 ++++++++++++++++++ attachment/lispy.py | 318 +++++++++++++++++++++++++++++++++++++++ llm.l | 29 +++- 5 files changed, 566 insertions(+), 3 deletions(-) create mode 100644 attachment/awk_lisp.tgz create mode 100644 attachment/faq-doc-6.txt create mode 100644 attachment/lis.py create mode 100644 attachment/lispy.py diff --git a/attachment/awk_lisp.tgz b/attachment/awk_lisp.tgz new file mode 100644 index 0000000000000000000000000000000000000000..e3804d299d795b3a515f8d35f42b836dbab1271e GIT binary patch literal 24265 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 literal 0 HcmV?d00001 diff --git a/attachment/faq-doc-6.txt b/attachment/faq-doc-6.txt new file mode 100644 index 0000000..daa55c9 --- /dev/null +++ b/attachment/faq-doc-6.txt @@ -0,0 +1,77 @@ +Quelle: http://www.cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/part1/faq-doc-6.html +Abruf: 04.08.2019 +----------------------------------------------------------------------------- +[1-5] What is the "minimal" set of primitives needed for a Lisp interpreter? + +Many Lisp functions can be defined in terms of other Lisp functions. +For example, CAAR can be defined in terms of CAR as + (defun caar (list) (car (car list))) +It is then natural to ask whether there is a "minimal" or smallest set +of primitives necessary to implement the language. + +There is no single "best" minimal set of primitives; it all depends on +the implementation. For example, even something as basic as numbers +need not be primitive, and can be represented as lists. One possible +set of primitives might include CAR, CDR, and CONS for manipulation of +S-expressions, READ and PRINT for the input/output of S-expressions +and APPLY and EVAL for the guts of an interpreter. But then you might +want to add LAMBDA for functions, EQ for equality, COND for +conditionals, SET for assignment, and DEFUN for definitions. QUOTE +might come in handy as well. If you add more specialized datatypes, +such as integers, floats, arrays, characters, and structures, you'll +need to add primitives to construct and access each. + +AWKLisp is a Lisp interpreter written in awk, available by anonymous +ftp from ftp.cs.cmu.edu:/user/ai/lang/lisp/impl/awk/. It has thirteen +built-in functions: CAR, CDR, CONS, EQ, ATOM, SET, EVAL, ERROR, QUOTE, +COND, AND, OR, LIST. + +A more practical notion of a "minimal" set of primitives might be to +look at the implementation of Scheme. While many Scheme functions can +be derived from others, the language is much smaller than Common Lisp. +See Dybvig's PhD thesis, + R. Kent Dybvig, "Three Implementation Models for Scheme", Department + of Computer Science Technical Report #87-011, University of North + Carolina at Chapel Hill, Chapel Hill, North Carolina, April 1987. +for a justification of a particularly practical minimal set of +primitives for Scheme. + +In a language like Common Lisp, however, there are a lot of low-level +primitive functions that cannot be written in terms of the others, +such as GET-UNIVERSAL-TIME, READ-CHAR, WRITE-CHAR, OPEN, and CLOSE, +for starters. Moreover, real Common Lisp implementations are often +built upon primitives that aren't part of the language, per se, and +certainly not intended to be user-accessible, such as SYS:%POINTER-REF. + +Beside the references listed in [1-4], some other relevant references +include: + + McCarthy, John, "Recursive Functions of Symbolic Expressions and + their Computation by Machine, Part I", CACM 3(4):185-195, April 1960. + [Defines five elementary functions on s-expressions.] + + McCarthy, John, "A Micro-Manual for Lisp -- not the whole Truth", + ACM SIGPLAN Notices, 13(8):215-216, August 1978. + [Defines the Lisp programming language in 10 rules and gives + a small interpreter (eval) written in this Lisp.] + + McCarthy, John, et al., "LISP 1.5 Programmer's Manual", 2nd edition, + MIT Press, 1965, ISBN 0-262-13011-4 (paperback). + [Gives five basic functions, CAR, CDR, CONS, EQ, and ATOM. + Using composition, conditional expressions (COND), and + recursion, LAMBDA, and QUOTE, these basic functions may be used + to construct the entire class of computable functions of + S-expressions. Gives the functions EVAL and APPLY in + M-expression syntax.] + + Abelson and Sussman's SICP, especially chapters 4 and 5 on the + implementation of meta-circular and explicit-control evaluators. + + Steele and Gabriel's "The Evolution of LISP". + +Go Back Up + +Go To Previous + +Go To Next + diff --git a/attachment/lis.py b/attachment/lis.py new file mode 100644 index 0000000..2d031ad --- /dev/null +++ b/attachment/lis.py @@ -0,0 +1,145 @@ +################ Lispy: Scheme Interpreter in Python + +## (c) Peter Norvig, 2010-16; See http://norvig.com/lispy.html + +from __future__ import division +import math +import operator as op + +################ Types + +Symbol = str # A Lisp Symbol is implemented as a Python str +List = list # A Lisp List is implemented as a Python list +Number = (int, float) # A Lisp Number is implemented as a Python int or float + +################ Parsing: parse, tokenize, and read_from_tokens + +def parse(program): + "Read a Scheme expression from a string." + return read_from_tokens(tokenize(program)) + +def tokenize(s): + "Convert a string into a list of tokens." + return s.replace('(',' ( ').replace(')',' ) ').split() + +def read_from_tokens(tokens): + "Read an expression from a sequence of tokens." + if len(tokens) == 0: + raise SyntaxError('unexpected EOF while reading') + token = tokens.pop(0) + if '(' == token: + L = [] + while tokens[0] != ')': + L.append(read_from_tokens(tokens)) + tokens.pop(0) # pop off ')' + return L + elif ')' == token: + raise SyntaxError('unexpected )') + else: + return atom(token) + +def atom(token): + "Numbers become numbers; every other token is a symbol." + try: return int(token) + except ValueError: + try: return float(token) + except ValueError: + return Symbol(token) + +################ Environments + +def standard_env(): + "An environment with some Scheme standard procedures." + env = Env() + env.update(vars(math)) # sin, cos, sqrt, pi, ... + env.update({ + '+':op.add, '-':op.sub, '*':op.mul, '/':op.truediv, + '>':op.gt, '<':op.lt, '>=':op.ge, '<=':op.le, '=':op.eq, + 'abs': abs, + 'append': op.add, + 'apply': apply, + 'begin': lambda *x: x[-1], + 'car': lambda x: x[0], + 'cdr': lambda x: x[1:], + 'cons': lambda x,y: [x] + y, + 'eq?': op.is_, + 'equal?': op.eq, + 'length': len, + 'list': lambda *x: list(x), + 'list?': lambda x: isinstance(x,list), + 'map': map, + 'max': max, + 'min': min, + 'not': op.not_, + 'null?': lambda x: x == [], + 'number?': lambda x: isinstance(x, Number), + 'procedure?': callable, + 'round': round, + 'symbol?': lambda x: isinstance(x, Symbol), + }) + return env + +class Env(dict): + "An environment: a dict of {'var':val} pairs, with an outer Env." + def __init__(self, parms=(), args=(), outer=None): + self.update(zip(parms, args)) + self.outer = outer + def find(self, var): + "Find the innermost Env where var appears." + return self if (var in self) else self.outer.find(var) + +global_env = standard_env() + +################ Interaction: A REPL + +def repl(prompt='lis.py> '): + "A prompt-read-eval-print loop." + while True: + val = eval(parse(raw_input(prompt))) + if val is not None: + print(lispstr(val)) + +def lispstr(exp): + "Convert a Python object back into a Lisp-readable string." + if isinstance(exp, List): + return '(' + ' '.join(map(lispstr, exp)) + ')' + else: + return str(exp) + +################ Procedures + +class Procedure(object): + "A user-defined Scheme procedure." + def __init__(self, parms, body, env): + self.parms, self.body, self.env = parms, body, env + def __call__(self, *args): + return eval(self.body, Env(self.parms, args, self.env)) + +################ eval + +def eval(x, env=global_env): + "Evaluate an expression in an environment." + if isinstance(x, Symbol): # variable reference + return env.find(x)[x] + elif not isinstance(x, List): # constant literal + return x + elif x[0] == 'quote': # (quote exp) + (_, exp) = x + return exp + elif x[0] == 'if': # (if test conseq alt) + (_, test, conseq, alt) = x + exp = (conseq if eval(test, env) else alt) + return eval(exp, env) + elif x[0] == 'define': # (define var exp) + (_, var, exp) = x + env[var] = eval(exp, env) + elif x[0] == 'set!': # (set! var exp) + (_, var, exp) = x + env.find(var)[var] = eval(exp, env) + elif x[0] == 'lambda': # (lambda (var...) body) + (_, parms, body) = x + return Procedure(parms, body, env) + else: # (proc arg...) + proc = eval(x[0], env) + args = [eval(exp, env) for exp in x[1:]] + return proc(*args) \ No newline at end of file diff --git a/attachment/lispy.py b/attachment/lispy.py new file mode 100644 index 0000000..08923c1 --- /dev/null +++ b/attachment/lispy.py @@ -0,0 +1,318 @@ +################ Scheme Interpreter in Python + +## (c) Peter Norvig, 2010; See http://norvig.com/lispy2.html + +################ Symbol, Procedure, classes + +from __future__ import division +import re, sys, StringIO + +class Symbol(str): pass + +def Sym(s, symbol_table={}): + "Find or create unique Symbol entry for str s in symbol table." + if s not in symbol_table: symbol_table[s] = Symbol(s) + return symbol_table[s] + +_quote, _if, _set, _define, _lambda, _begin, _definemacro, = map(Sym, +"quote if set! define lambda begin define-macro".split()) + +_quasiquote, _unquote, _unquotesplicing = map(Sym, +"quasiquote unquote unquote-splicing".split()) + +class Procedure(object): + "A user-defined Scheme procedure." + def __init__(self, parms, exp, env): + self.parms, self.exp, self.env = parms, exp, env + def __call__(self, *args): + return eval(self.exp, Env(self.parms, args, self.env)) + +################ parse, read, and user interaction + +def parse(inport): + "Parse a program: read and expand/error-check it." + # Backwards compatibility: given a str, convert it to an InPort + if isinstance(inport, str): inport = InPort(StringIO.StringIO(inport)) + return expand(read(inport), toplevel=True) + +eof_object = Symbol('#') # Note: uninterned; can't be read + +class InPort(object): + "An input port. Retains a line of chars." + tokenizer = r"""\s*(,@|[('`,)]|"(?:[\\].|[^\\"])*"|;.*|[^\s('"`,;)]*)(.*)""" + def __init__(self, file): + self.file = file; self.line = '' + def next_token(self): + "Return the next token, reading new text into line buffer if needed." + while True: + if self.line == '': self.line = self.file.readline() + if self.line == '': return eof_object + token, self.line = re.match(InPort.tokenizer, self.line).groups() + if token != '' and not token.startswith(';'): + return token + +def readchar(inport): + "Read the next character from an input port." + if inport.line != '': + ch, inport.line = inport.line[0], inport.line[1:] + return ch + else: + return inport.file.read(1) or eof_object + +def read(inport): + "Read a Scheme expression from an input port." + def read_ahead(token): + if '(' == token: + L = [] + while True: + token = inport.next_token() + if token == ')': return L + else: L.append(read_ahead(token)) + elif ')' == token: raise SyntaxError('unexpected )') + elif token in quotes: return [quotes[token], read(inport)] + elif token is eof_object: raise SyntaxError('unexpected EOF in list') + else: return atom(token) + # body of read: + token1 = inport.next_token() + return eof_object if token1 is eof_object else read_ahead(token1) + +quotes = {"'":_quote, "`":_quasiquote, ",":_unquote, ",@":_unquotesplicing} + +def atom(token): + 'Numbers become numbers; #t and #f are booleans; "..." string; otherwise Symbol.' + if token == '#t': return True + elif token == '#f': return False + elif token[0] == '"': return token[1:-1].decode('string_escape') + try: return int(token) + except ValueError: + try: return float(token) + except ValueError: + try: return complex(token.replace('i', 'j', 1)) + except ValueError: + return Sym(token) + +def to_string(x): + "Convert a Python object back into a Lisp-readable string." + if x is True: return "#t" + elif x is False: return "#f" + elif isa(x, Symbol): return x + elif isa(x, str): return '"%s"' % x.encode('string_escape').replace('"',r'\"') + elif isa(x, list): return '('+' '.join(map(to_string, x))+')' + elif isa(x, complex): return str(x).replace('j', 'i') + else: return str(x) + +def load(filename): + "Eval every expression from a file." + repl(None, InPort(open(filename)), None) + +def repl(prompt='lispy> ', inport=InPort(sys.stdin), out=sys.stdout): + "A prompt-read-eval-print loop." + sys.stderr.write("Lispy version 2.0\n") + while True: + try: + if prompt: sys.stderr.write(prompt) + x = parse(inport) + if x is eof_object: return + val = eval(x) + if val is not None and out: print >> out, to_string(val) + except Exception as e: + print '%s: %s' % (type(e).__name__, e) + +################ Environment class + +class Env(dict): + "An environment: a dict of {'var':val} pairs, with an outer Env." + def __init__(self, parms=(), args=(), outer=None): + # Bind parm list to corresponding args, or single parm to list of args + self.outer = outer + if isa(parms, Symbol): + self.update({parms:list(args)}) + else: + if len(args) != len(parms): + raise TypeError('expected %s, given %s, ' + % (to_string(parms), to_string(args))) + self.update(zip(parms,args)) + def find(self, var): + "Find the innermost Env where var appears." + if var in self: return self + elif self.outer is None: raise LookupError(var) + else: return self.outer.find(var) + +def is_pair(x): return x != [] and isa(x, list) +def cons(x, y): return [x]+y + +def callcc(proc): + "Call proc with current continuation; escape only" + ball = RuntimeWarning("Sorry, can't continue this continuation any longer.") + def throw(retval): ball.retval = retval; raise ball + try: + return proc(throw) + except RuntimeWarning as w: + if w is ball: return ball.retval + else: raise w + +def add_globals(self): + "Add some Scheme standard procedures." + import math, cmath, operator as op + self.update(vars(math)) + self.update(vars(cmath)) + self.update({ + '+':op.add, '-':op.sub, '*':op.mul, '/':op.div, 'not':op.not_, + '>':op.gt, '<':op.lt, '>=':op.ge, '<=':op.le, '=':op.eq, + 'equal?':op.eq, 'eq?':op.is_, 'length':len, 'cons':cons, + 'car':lambda x:x[0], 'cdr':lambda x:x[1:], 'append':op.add, + 'list':lambda *x:list(x), 'list?': lambda x:isa(x,list), + 'null?':lambda x:x==[], 'symbol?':lambda x: isa(x, Symbol), + 'boolean?':lambda x: isa(x, bool), 'pair?':is_pair, + 'port?': lambda x:isa(x,file), 'apply':lambda proc,l: proc(*l), + 'eval':lambda x: eval(expand(x)), 'load':lambda fn: load(fn), 'call/cc':callcc, + 'open-input-file':open,'close-input-port':lambda p: p.file.close(), + 'open-output-file':lambda f:open(f,'w'), 'close-output-port':lambda p: p.close(), + 'eof-object?':lambda x:x is eof_object, 'read-char':readchar, + 'read':read, 'write':lambda x,port=sys.stdout:port.write(to_string(x)), + 'display':lambda x,port=sys.stdout:port.write(x if isa(x,str) else to_string(x))}) + return self + +isa = isinstance + +global_env = add_globals(Env()) + +################ eval (tail recursive) + +def eval(x, env=global_env): + "Evaluate an expression in an environment." + while True: + if isa(x, Symbol): # variable reference + return env.find(x)[x] + elif not isa(x, list): # constant literal + return x + elif x[0] is _quote: # (quote exp) + (_, exp) = x + return exp + elif x[0] is _if: # (if test conseq alt) + (_, test, conseq, alt) = x + x = (conseq if eval(test, env) else alt) + elif x[0] is _set: # (set! var exp) + (_, var, exp) = x + env.find(var)[var] = eval(exp, env) + return None + elif x[0] is _define: # (define var exp) + (_, var, exp) = x + env[var] = eval(exp, env) + return None + elif x[0] is _lambda: # (lambda (var*) exp) + (_, vars, exp) = x + return Procedure(vars, exp, env) + elif x[0] is _begin: # (begin exp+) + for exp in x[1:-1]: + eval(exp, env) + x = x[-1] + else: # (proc exp*) + exps = [eval(exp, env) for exp in x] + proc = exps.pop(0) + if isa(proc, Procedure): + x = proc.exp + env = Env(proc.parms, exps, proc.env) + else: + return proc(*exps) + +################ expand + +def expand(x, toplevel=False): + "Walk tree of x, making optimizations/fixes, and signaling SyntaxError." + require(x, x!=[]) # () => Error + if not isa(x, list): # constant => unchanged + return x + elif x[0] is _quote: # (quote exp) + require(x, len(x)==2) + return x + elif x[0] is _if: + if len(x)==3: x = x + [None] # (if t c) => (if t c None) + require(x, len(x)==4) + return map(expand, x) + elif x[0] is _set: + require(x, len(x)==3); + var = x[1] # (set! non-var exp) => Error + require(x, isa(var, Symbol), "can set! only a symbol") + return [_set, var, expand(x[2])] + elif x[0] is _define or x[0] is _definemacro: + require(x, len(x)>=3) + _def, v, body = x[0], x[1], x[2:] + if isa(v, list) and v: # (define (f args) body) + f, args = v[0], v[1:] # => (define f (lambda (args) body)) + return expand([_def, f, [_lambda, args]+body]) + else: + require(x, len(x)==3) # (define non-var/list exp) => Error + require(x, isa(v, Symbol), "can define only a symbol") + exp = expand(x[2]) + if _def is _definemacro: + require(x, toplevel, "define-macro only allowed at top level") + proc = eval(exp) + require(x, callable(proc), "macro must be a procedure") + macro_table[v] = proc # (define-macro v proc) + return None # => None; add v:proc to macro_table + return [_define, v, exp] + elif x[0] is _begin: + if len(x)==1: return None # (begin) => None + else: return [expand(xi, toplevel) for xi in x] + elif x[0] is _lambda: # (lambda (x) e1 e2) + require(x, len(x)>=3) # => (lambda (x) (begin e1 e2)) + vars, body = x[1], x[2:] + require(x, (isa(vars, list) and all(isa(v, Symbol) for v in vars)) + or isa(vars, Symbol), "illegal lambda argument list") + exp = body[0] if len(body) == 1 else [_begin] + body + return [_lambda, vars, expand(exp)] + elif x[0] is _quasiquote: # `x => expand_quasiquote(x) + require(x, len(x)==2) + return expand_quasiquote(x[1]) + elif isa(x[0], Symbol) and x[0] in macro_table: + return expand(macro_table[x[0]](*x[1:]), toplevel) # (m arg...) + else: # => macroexpand if m isa macro + return map(expand, x) # (f arg...) => expand each + +def require(x, predicate, msg="wrong length"): + "Signal a syntax error if predicate is false." + if not predicate: raise SyntaxError(to_string(x)+': '+msg) + +_append, _cons, _let = map(Sym, "append cons let".split()) + +def expand_quasiquote(x): + """Expand `x => 'x; `,x => x; `(,@x y) => (append x y) """ + if not is_pair(x): + return [_quote, x] + require(x, x[0] is not _unquotesplicing, "can't splice here") + if x[0] is _unquote: + require(x, len(x)==2) + return x[1] + elif is_pair(x[0]) and x[0][0] is _unquotesplicing: + require(x[0], len(x[0])==2) + return [_append, x[0][1], expand_quasiquote(x[1:])] + else: + return [_cons, expand_quasiquote(x[0]), expand_quasiquote(x[1:])] + +def let(*args): + args = list(args) + x = cons(_let, args) + require(x, len(args)>1) + bindings, body = args[0], args[1:] + require(x, all(isa(b, list) and len(b)==2 and isa(b[0], Symbol) + for b in bindings), "illegal binding list") + vars, vals = zip(*bindings) + return [[_lambda, list(vars)]+map(expand, body)] + map(expand, vals) + +macro_table = {_let:let} ## More macros can go here + +eval(parse("""(begin + +(define-macro and (lambda args + (if (null? args) #t + (if (= (length args) 1) (car args) + `(if ,(car args) (and ,@(cdr args)) #f))))) + +;; More macros can also go here + +)""")) + +if __name__ == '__main__': + repl() + diff --git a/llm.l b/llm.l index a625482..9167a89 100644 --- a/llm.l +++ b/llm.l @@ -35,8 +35,8 @@ * Data types: * #fn Functions * t,nil boolean (nand ) -> boolean - * "str" Strings (streq ) -> boolean - * abc Symboles (symeq ) -> boolean + * "str" Strings + * abc Symboles * 1234 Number/Integer (inv ) -> -num * (add ) -> num * (lt ) -> boolean @@ -48,7 +48,7 @@ * (lm () ()) * create function with one or more PARAMs and * BODY. - * (if ) + * (if ) * Evaluate BOOL and execute CASETRUE if true, * otherwise evaulate CASEFALSE * (quote a) @@ -60,6 +60,29 @@ * systems) * BUGS: * no freeing of memory (yet) + * + * Literature: + * [1] https://news.ycombinator.com/item?id=8714988 + * Discussion about "minimal" set of primitives + * for a LISP interpreter. + * [2] https://stackoverflow.com/questions/3482389/ + * How many primitives does it take to build a + * LISP machine? Ten, seven or five? + * [3] http://www.cs.cmu.edu/Groups/AI/html/faqs/lang/ \ + * lisp/part1/faq-doc-6.html + * Discussion about the minimal set of primitives + * (see attachment) + * [4] https://www.cs.cmu.edu/afs/cs/project/ai-repository \ + * /ai/lang/lisp/impl/awk/0.html + * LISP Interpreter in AWK. (see attachments) + * [5] http://norvig.com/lispy.html + * Similar project, with Python instead of C + * [6] http://norvig.com/lispy2.html + * Improved version of [5] in Python. (attachment) + * [7] Structure and Interpretation of Computer Programs, + * by Abelson, Sussman, and Sussman + * [8] FernUniversität Hagen: Logisches und funktionales + * Programmieren, by Prof.Dr.Beierle. */ %{ #define _POSIX_C_SOURCE 200809L