1
1
mirror of https://github.com/kanaka/mal.git synced 2024-09-20 01:57:09 +03:00

RPython: add keywords. Use unicode internally.

This commit is contained in:
Joel Martin 2015-06-03 22:22:48 -05:00
parent 80320efc47
commit f0cd131844
3 changed files with 42 additions and 33 deletions

View File

@ -58,7 +58,7 @@ import sys, copy, types as pytypes
## return copy.copy(obj)
def _replace(match, sub, old_str):
new_str = ""
new_str = u""
idx = 0
while idx < len(old_str):
midx = old_str.find(match, idx)
@ -108,7 +108,7 @@ def _int_Q(exp):
# String
class MalStr(MalType):
def __init__(self, value):
assert isinstance(value, str)
assert isinstance(value, unicode)
self.value = value
def __len__(self):
return len(self.value)
@ -119,20 +119,29 @@ def _string_Q(exp):
# Symbols
class MalSym(MalType):
def __init__(self, value):
assert isinstance(value, str)
assert isinstance(value, unicode)
self.value = value
def _symbol_Q(exp):
assert isinstance(exp, MalType)
return exp.__class__ is MalSym
### Keywords
### A specially prefixed string
##def _keyword(str):
## if str[0] == u("\u029e"): return str
## else: return u("\u029e") + str
##def _keyword_Q(exp):
## return _string_Q(exp) and exp[0] == u("\u029e")
##
# Keywords
# A specially prefixed string
def _keyword(mstr):
assert isinstance(mstr, MalType)
if isinstance(mstr, MalStr):
val = mstr.value
if val[0] == u"\u029e": return mstr
else: return MalStr(u"\u029e" + val)
else:
raise Exception("_keyword called on non-string")
# Create keyword from unicode string
def _keywordu(strn):
assert isinstance(strn, unicode)
return MalStr(u"\u029e" + strn)
def _keyword_Q(exp):
return _string_Q(exp) and exp.value[0] == u"\u029e"
### Functions
##def _function(Eval, Env, ast, env, params):
## def fn(*args):

View File

@ -17,7 +17,7 @@ def _pr_str(obj, print_readably=True):
res = []
for e in obj.values:
res.append(_pr_str(e,_r))
return "(" + " ".join(res) + ")"
return u"(" + u" ".join(res) + u")"
## elif types._vector_Q(obj):
## return "[" + " ".join(map(lambda e: _pr_str(e,_r), obj)) + "]"
## elif types._hash_map_Q(obj):
@ -28,20 +28,20 @@ def _pr_str(obj, print_readably=True):
elif types._string_Q(obj):
assert isinstance(obj, MalStr)
val = obj.value
if len(val) > 0 and val[0] == '\u029e':
return ':' + val[1:]
if len(val) > 0 and val[0] == u'\u029e':
return u':' + val[1:]
elif print_readably:
return '"' + types._replace('\\n', '\\n',
types._replace('\"', '\\"',
types._replace('\\\\', '\\\\', val))) + '"'
return u'"' + types._replace(u'\\n', u'\\n',
types._replace(u'\"', u'\\"',
types._replace(u'\\\\', u'\\\\', val))) + u'"'
else:
return val
elif types._nil_Q(obj):
return "nil"
return u"nil"
elif types._true_Q(obj):
return "true"
return u"true"
elif types._false_Q(obj):
return "false"
return u"false"
## elif types._atom_Q(obj):
## return "(atom " + _pr_str(obj.val,_r) + ")"
elif types._symbol_Q(obj):
@ -49,7 +49,7 @@ def _pr_str(obj, print_readably=True):
return obj.value
elif types._int_Q(obj):
assert isinstance(obj, MalInt)
return str(obj.value)
return unicode(str(obj.value))
else:
return "unknown"
return u"unknown"

View File

@ -7,7 +7,7 @@ else:
import re
import mal_types as types
from mal_types import (MalSym, MalInt, MalStr, _list)
from mal_types import (MalSym, MalInt, MalStr, _keywordu, _list)
class Blank(Exception): pass
@ -47,14 +47,14 @@ def read_atom(reader):
elif token[0] == '"':
end = len(token)-1
if end < 2:
return MalStr("")
return MalStr(u"")
else:
return MalStr(types._replace('\\"', '"', token[1:end]))
## elif token[0] == ':': return _keyword(token[1:])
return MalStr(types._replace(u'\\"', u'"', unicode(token[1:end])))
elif token[0] == ':': return _keywordu(unicode(token[1:]))
elif token == "nil": return types.nil
elif token == "true": return types.true
elif token == "false": return types.false
else: return MalSym(token)
else: return MalSym(unicode(token))
def read_sequence(reader, typ, start='(', end=')'):
ast = typ()
@ -87,23 +87,23 @@ def read_form(reader):
return None
elif token == '\'':
reader.next()
return _list(MalSym('quote'), read_form(reader))
return _list(MalSym(u'quote'), read_form(reader))
elif token == '`':
reader.next()
return _list(MalSym('quasiquote'), read_form(reader))
return _list(MalSym(u'quasiquote'), read_form(reader))
elif token == '~':
reader.next()
return _list(MalSym('unquote'), read_form(reader))
return _list(MalSym(u'unquote'), read_form(reader))
elif token == '~@':
reader.next()
return _list(MalSym('splice-unquote'), read_form(reader))
return _list(MalSym(u'splice-unquote'), read_form(reader))
elif token == '^':
reader.next()
meta = read_form(reader)
return _list(MalSym('with-meta'), read_form(reader), meta)
return _list(MalSym(u'with-meta'), read_form(reader), meta)
elif token == '@':
reader.next()
return _list(MalSym('deref'), read_form(reader))
return _list(MalSym(u'deref'), read_form(reader))
# list
elif token == ')': raise Exception("unexpected ')'")