예제 #1
0
파일: reader.py 프로젝트: llnek/kirby
def readBlock(tree, ends):
  ast,token= std.pair(), popToken(tree)
  cur,jso,expr,ok,start=None,None,None,True,token
  ###
  if ends[0]=="[": ast=std.vector()
  if ends[0]=="(": expr=True

  if token.value != ends[0]:
    throwE(token, "expected '", ends[0], "'")

  while True:
    cur = peekToken(tree)
    if not cur: throwE(start, "expected '", ends[1], "', got EOF")
    if ends[1] == cur.value: break
    addAst(ast, readAst(tree))
  ##get rid of the last token
  popToken(tree)
  if jso:
    ast.insert(0,std.symbol("object*"))
  elif expr:
    if ast and std.isSymbol(ast[0]):
      cmd=str(ast[0])
      if cmd== "hash-map": ast[0].value="hashmap*"
      elif cmd== "hash-set": ast[0].value="hashset*"
      elif cmd== "list": ast[0].value="list*"
      elif cmd== "vec" or cmd=="vector": ast[0].value="vector*"
      elif cmd=="js-obj" or cmd== "object": ast[0].value="object*"
  elif ends[0]=="#{":
    ast.insert(0,std.symbol("hashset*"))
  elif ends[0]=="{":
    ast.insert(0,std.symbol("hashmap*"))
  return copyTokenData(start, ast)
예제 #2
0
def backtick(ast):
    def lstQ(a):
        return std.isSequential(a) and std.notEmpty(a)

    if not lstQ(ast):
        rc = std.pair(std.symbol("quote"), ast)
    elif std.isSymbol(ast[0], "unquote"):
        rc = ast[1]
    elif lstQ(ast[0]) and std.isSymbol(ast[0][0], "splice-unquote"):
        rc = std.pair(std.symbol("concat*"), ast[0][1], backtick(ast.slice(1)))
    else:
        rc = std.pair(std.symbol("cons*"), backtick(ast[0]), backtick(ast[1:]))
    return rc
예제 #3
0
파일: reader.py 프로젝트: llnek/kirby
def readAtom(tree):
  token = popToken(tree)
  ret,tn = None,token.value
  ###
  if not tn:
    pass
    #//ret = undefined
  elif REGEX.float.search(tn):
    ret = float(tn)
  elif REGEX.hex.search(tn) or REGEX.int.search(tn):
    ret = int(tn)
  elif tn.startswith("\"") and tn.endswith("\""):
    ret = std.unquoteStr(tn)
  elif tn.startswith(":"):
    ret = std.keyword(tn)
  elif tn.startswith("%"):
    ret = LambdaArg(token)
  elif tn.startswith("#/") and (tn.endswith("/") or tn[0:-1].endswith("/")):
    ret = std.RegexObj(tn)
  elif tn == "nil" or tn == "null":
    ret = std.Null()
  elif tn == "#t" or tn == "true":
    ret = True
  elif tn == "#f" or tn == "false":
    ret = False
  else:
    ret = std.symbol(tn)
  return copyTokenData(token, ret)
예제 #4
0
def doMACRO(ast, env):
    name = cmd = str(ast[1])
    nsp = core.peekNS()
    nsp = nsp.id if nsp else KBSTDLIB
    #ast[2]===args, ast[3]===body
    mc = fnToNative(ast[2], ast[3], env)
    if "/" not in cmd:
        name = f"{nsp}/{cmd}"
        env.set(std.symbol(cmd), mc)
    setMacro(name, mc)
예제 #5
0
파일: reader.py 프로젝트: llnek/kirby
 def scan(ast):
   nonlocal z,c
   for i,a in enumerate(ast):
     if isinstance(a,list):
       scan(a)
     elif isinstance(a, LambdaArg):
       z=int(a.value[1:])
       if z>c: c=z
       #replace it with symbol
       ast[i]=std.symbol(f"{base}{z}")
예제 #6
0
파일: reader.py 프로젝트: llnek/kirby
def lspec(tree):
  z,c,base=0,0,std.gensym().value + "__"
  tree=readAst(tree)
  def scan(ast):
    nonlocal z,c
    for i,a in enumerate(ast):
      if isinstance(a,list):
        scan(a)
      elif isinstance(a, LambdaArg):
        z=int(a.value[1:])
        if z>c: c=z
        #replace it with symbol
        ast[i]=std.symbol(f"{base}{z}")
  ###
  if not std.isPair(tree):
    throwE(tree, "expected pair")
  scan(tree)
  args= std.vector()
  i=1
  while i<=c:
    args.append(std.symbol(f"{base}{i}"))
    i+=1
  return std.pair(std.symbol("lambda*"), args, tree)
예제 #7
0
def newEnv():
    ret = LEXEnv()
    for k, v in _intrinsics_.items():
        ret.set(std.symbol(k), v)
    return ret
예제 #8
0
파일: reader.py 프로젝트: llnek/kirby
def _rspec(s):
  return lambda a: std.pair(std.symbol(s), readAst(a))
예제 #9
0
파일: reader.py 프로젝트: llnek/kirby
def _metaFunc(a1):
  t= readAst(a1)
  return std.pair(std.symbol("with-meta"), readAst(a1), t)