code: def typeCompileAst(ast):
      
      children = list(ast.children)
      if ast.astType == 'op':
          retsig = ast.typecode()
          basesig = ''.join(x.typecode() for x in list(ast.children))
          # Find some operation that will work on an acceptable casting of args.
          for sig in sigPerms(basesig):
              value = (ast.value + '_' + retsig + sig).encode('ascii')
              if value in interpreter.opcodes:
                  break
          else:
              for sig in sigPerms(basesig):
                  funcname = (ast.value + '_' + retsig + sig).encode('ascii')
                  if funcname in interpreter.funccodes:
                      value = ('func_%sn' % (retsig + sig)).encode('ascii')
                      children += [ASTNode('raw', 'none',
                                           interpreter.funccodes[funcname])]
                      break
              else:
                  raise NotImplementedError(
                      "couldn't find matching opcode for '%s'"
                      % (ast.value + '_' + retsig + basesig))
          # First just cast constants, then cast variables if necessary:
          for i, (have, want) in enumerate(zip(basesig, sig)):
              if have != want:
                  kind = typecode_to_kind[want]
                  if children[i].astType == 'constant':
                      children[i] = ASTNode('constant', kind, children[i].value)
                  else:
                      opname = "cast"
                      children[i] = ASTNode('op', kind, opname, [children[i]])
      else:
          value = ast.value
          children = ast.children
      return ASTNode(ast.astType, ast.astKind, value,
                     [typeCompileAst(c) for c in children])
docs: Assign appropiate types to each node in the AST.
  
      Will convert opcodes and functions to appropiate upcast version,
      and add "cast" ops if needed.