Skip to content

Commit

Permalink
removing yaml require from py2cr, scaffolding for num.cr
Browse files Browse the repository at this point in the history
  • Loading branch information
nanobowers committed Nov 3, 2021
1 parent 9a7d37c commit 114c817
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 72 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
77 changes: 41 additions & 36 deletions py2cr/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,16 @@
from collections import OrderedDict
from pprint import pprint

import yaml

# local code
from . import formatter
from . import types

# translators
# function/attribute "translators"
from .translator import *
from . import pymain
from . import pyos
from . import pysys
from . import pysix
from . import numpy

registry = TranslatorRegistry()
Expand Down Expand Up @@ -90,15 +89,6 @@ def wrap_class_method(self, cls, method):

class RB(object):

module_map = {} # : Dict[str,str] = registry.module_to_require_map()


yaml_files = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'modules/*.yaml')
for filename in glob.glob(yaml_files):
with open(filename, 'r', encoding="utf-8") as f:
module_map.update(yaml.safe_load(f))


# python 3
name_constant_map = {
True : 'true',
Expand All @@ -112,7 +102,6 @@ class RB(object):
'open' : 'File.open',
}
name_map = {
#'self' : 'this',
'True' : 'true', # python 2.x
'False' : 'false', # python 2.x
'None' : 'nil', # python 2.x
Expand Down Expand Up @@ -182,8 +171,10 @@ class RB(object):
'hasattr' : 'instance_variable_defined?',
'getattr': 'py_getattr',
}

# np.array([x1, x2]) => Numo::NArray[x1, x2]
order_methods_with_bracket : Dict[str, str] = {}

methods_map : Dict[str, str] = {}
ignore : Dict[str, str] = {}
mod_class_name : Dict[str, str] = {}
Expand Down Expand Up @@ -296,10 +287,9 @@ def vprint(self, message : str) -> None:

def maybewarn(self, message : str) -> None:
if self._mode == OperationMode.WARNING:
self.set_result(1)
self.set_result(ResultStatus.INCLUDE_WARNING)
sys.stderr.write("Warning : " + message + "\n")


# Error Stop Mode
def mode(self, mode):
self._mode = mode
Expand Down Expand Up @@ -358,8 +348,10 @@ def __init__(self, path='', dir_path='', base_path_count=0, mod_paths = None, ve
self._dict_format = False # True : Symbol ":", False : String "=>"

self._is_string_symbol = False # True : ':foo' , False : '"foo"'

# This lists all variables in the local scope:
self._scope = []

#All calls to names within _class_names will be preceded by 'new'
# Python original class name
self._class_names = set()
Expand Down Expand Up @@ -401,6 +393,9 @@ def __init__(self, path='', dir_path='', base_path_count=0, mod_paths = None, ve
# This lists all lambda functions:
self._lambda_functions = []

# This is a mapping of module-name when "import foo as bar" is used.
self._module_aliases : Dict[str,str] = {}

self._import_files = []
self._imports = []
self._call = False
Expand Down Expand Up @@ -437,7 +432,7 @@ def visit(self, node, scope=None, crytype=None):
visitor = getattr(self, 'visit_' + self.name(node))
except AttributeError:
if self._mode == OperationMode.STOP:
self.set_result(2)
self.set_result(ResultStatus.INCLUDE_ERROR)
raise CrystalError("Syntax not supported (%s line:%d col:%d)" % (node, node.lineno, node.col_offset))
else:
self.maybewarn("Syntax not supported (%s line:%d col:%d)" % (node, node.lineno, node.col_offset))
Expand Down Expand Up @@ -1036,7 +1031,7 @@ def visit_For(self, node):
For(expr target, expr iter, stmt* body, stmt* orelse)
"""
if not isinstance(node.target, (ast.Name,ast.Tuple, ast.List)):
self.set_result(2)
self.set_result(ResultStatus.INCLUDE_ERROR)
raise CrystalError("Argument decomposition in 'for' loop is not supported")
#if isinstance(node.target, ast.Tuple):

Expand Down Expand Up @@ -1283,17 +1278,20 @@ def visit_Import(self, node):
mb = Foo::Moduleb_class.new()
"""
mod_name = node.names[0].name
self.vprint(f"%%%MODULE_MAP_KEYS: {self.module_map.keys()}")
self.vprint(f"Import mod_name: {mod_name} mod_paths : {self.mod_paths}")
#if mod_name not in self.module_map:



if registry.require_lookup_or_none(mod_name):

self.vprint(f"Import mod_name={mod_name} mod_paths={self.mod_paths} **found-in-registry**")

mod_name = node.names[0].name.replace('.', '/')
for path, rel_path in self.mod_paths.items():
self.vprint("Import mod_name : %s rel_path : %s" % (mod_name, rel_path))
self.vprint("Import mod_name=%s rel_path=%s" % (mod_name, rel_path))
if (rel_path.startswith(mod_name + '/') or mod_name.endswith(rel_path)) and os.path.exists(path):
self._import_files.append(os.path.join(self._dir_path, rel_path).replace('/', '.'))
self.vprint("Import self._import_files: %s" % self._import_files)
self.write("require \"./%s\"" % rel_path)
self.write(f'require "./{rel_path}"')

if node.names[0].asname != None:
if node.names[0].name in self._import_files:
Expand All @@ -1307,13 +1305,17 @@ def visit_Import(self, node):
# self._classes_self_functions_args[node.names[0].asname] = self._classes_self_functions_args[node.names[0].name]
#else:
# self.write("alias %s %s" % (node.names[0].asname, node.names[0].name))
return

mod_as_name = node.names[0].asname or mod_name
self.vprint(f"Aliasing {mod_as_name} to {mod_name}")
self._module_aliases[mod_as_name] = mod_name

#return

#>> module foo as otherfoo
mod_as_name = node.names[0].asname or mod_name

#>> get module's crystal name alias
#_mod_name = self.module_map[mod_name].get('mod_name', '')

require_name = registry.require_lookup(mod_name)


Expand Down Expand Up @@ -1440,7 +1442,7 @@ class spam:
class Spam
"""
self.vprint(f"mod_paths : {self.mod_paths}")
#if node.module != None and node.module not in self.module_map:

if node.module is not None and not registry.require_lookup_or_none(node.module):

require_name = registry.require_lookup(node.module)
Expand Down Expand Up @@ -1496,11 +1498,7 @@ class Spam
func= Name(id='array', ctx= Load()),
args=[ List(elts=[ Num(n=1), Num(n=1)], ctx= Load())], keywords=[]))
"""
# Not Use?
#if node.module == None:
# mod_name = node.names[0].name
#else:
# mod_name = self.module_map[node.module]


require_name = registry.require_lookup(node.module)

Expand Down Expand Up @@ -2084,7 +2082,7 @@ def get_methods_map(self, method_map, rb_args=False, ins=False):
elif self._verbose:
print("get_methods_map key : %s not match method_map['val'][key] %s" % (key, method_map['val'][key]))
if len(args_hash) == 0:
self.set_result(2)
self.set_result(ResultStatus.INCLUDE_ERROR)
raise CrystalError("methods_map default argument Error : not found args")

if 'main_data_key' in method_map:
Expand Down Expand Up @@ -2112,7 +2110,7 @@ def get_methods_map(self, method_map, rb_args=False, ins=False):
main_func = method_map['main_func_hash_nm']
main_func = method_map['val'][func_key] % {'mod': mod, 'data': main_data, 'main_func': main_func}
if main_func == '':
self.set_result(2)
self.set_result(ResultStatus.INCLUDE_ERROR)
raise CrystalError("methods_map main function Error : not found args")

if rtn:
Expand Down Expand Up @@ -2308,8 +2306,15 @@ def visit_Call(self, node, crytype = None):
if isinstance(node.func, ast.Call):
return f"{func}.py_call({cry_args_s})"

self.vprint(f"looking up: [{funcdb.func_module} {funcdb.func_name}]")
lkfunc = registry.func_lookup(funcdb.func_module, funcdb.func_name)

func_modulename = funcdb.func_module

# de-alias the modulename to look it up for translation
dealias_modulename = self._module_aliases.get(func_modulename, func_modulename)
self.vprint(f"looking up: module({func_modulename}=>{dealias_modulename}) func=({funcdb.func_name})")


lkfunc = registry.func_lookup(dealias_modulename, funcdb.func_name)
if lkfunc:
return lkfunc(funcdb)

Expand Down Expand Up @@ -2621,7 +2626,7 @@ def visit_Tuple(self, node) -> str:
elif self._tuple_type == '':
return "%s" % (", ".join(els))
else:
self.set_result(2)
self.set_result(ResultStatus.INCLUDE_ERROR)
raise CrystalError("tuples in argument list Error")

def visit_Dict(self, node, crytype = None) -> str:
Expand Down
88 changes: 58 additions & 30 deletions py2cr/numpy.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,68 @@
import ast
import re
from .translator import *

class Numcr:
typemap = {
"int8": "Int8",
"int16": "Int8",
"int32": "Int32",
"int64": "Int64",
"int": "Int64",
"uint8": "UInt8",
"uint16": "UInt8",
"uint32": "UInt32",
"uint64": "UInt64",
"uint": "UInt64",
"float32": "Float32",
"float64": "Float64",
}

@staticmethod
def parse_args(funcdb):
templatetype = "Int32" # default value
otherargs = []
for arg in funcdb.node.args:
otherargs.append(funcdb.crystal_visitor.visit(arg))

for kw in funcdb.node.keywords:
if kw.arg == "dtype":
dtype_value = funcdb.crystal_visitor.visit(kw.value)
# remove preceding np./numpy. to get dtype for lookup
dtype_value_hack = re.sub(r".*\.", '', dtype_value)
templatetype = Numcr.typemap[dtype_value_hack]
else:
otherargs.append(funcdb.crystal_visitor.visit(kw))

return (templatetype, otherargs)

@staticmethod
def _tensor(function, funcdb):
templatetype, otherargs = Numcr.parse_args(funcdb)

arglist = ", ".join(otherargs)
return f"Tensor({templatetype}).{function}({arglist})"

class Numpy(CrystalTranslator):
def __init__(self):
self.python_module_name = "numpy"
self.crystal_require = "num"

def arange(self):
return "ARANGE"

def arange(funcdb):
return Numcr._tensor("range", funcdb)

def ones(funcdb):
return Numcr._tensor("ones", funcdb)

def zeros(funcdb):
return Numcr._tensor("zeros", funcdb)

def ones_like(funcdb):
return Numcr._tensor("ones_like", funcdb)

def zeros_like(funcdb):
return Numcr._tensor("zeros_like", funcdb)


class Collections(CrystalTranslator):
def __init__(self):
Expand All @@ -17,30 +72,3 @@ def __init__(self):
def OrderedDict(funcdb):
# replace with first arg (a dict)
return funcdb.crystal_args[0]

class SixMoves(CrystalTranslator):
def __init__(self):
self.python_module_name = "six.moves"
self.crystal_require = None

def range(funcdb):
# six.moves.range() => range()
return "PyRange.range(%s)" % ", ".join(funcdb.crystal_args)

class Six(CrystalTranslator):
attribute_map = {
"PY2": "false",
"PY3": "true",
"integer_types": "[Int32]"
}
def __init__(self):
self.python_module_name = "six"
self.crystal_require = None

def itervalues(funcdb):
receiver = funcdb.crystal_args[0]
return f"{receiver}.values"

def iteritems(funcdb):
receiver = funcdb.crystal_args[0]
return f"{receiver}.to_a"
29 changes: 29 additions & 0 deletions py2cr/pysix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import ast
from .translator import *

class SixMoves(CrystalTranslator):
def __init__(self):
self.python_module_name = "six.moves"
self.crystal_require = None

def range(funcdb):
# six.moves.range() => range()
return "PyRange.range(%s)" % ", ".join(funcdb.crystal_args)

class Six(CrystalTranslator):
attribute_map = {
"PY2": "false",
"PY3": "true",
"integer_types": "[Int32]"
}
def __init__(self):
self.python_module_name = "six"
self.crystal_require = None

def itervalues(funcdb):
receiver = funcdb.crystal_args[0]
return f"{receiver}.values"

def iteritems(funcdb):
receiver = funcdb.crystal_args[0]
return f"{receiver}.to_a"
15 changes: 9 additions & 6 deletions tests/numpy/not_like.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@ def print_array(data):
datas.append(float("%.3f" % i))
print(datas)

x = np.ones(5)
print_array(x)
x1 = np.ones(5, dtype=np.int8)
print_array(x1)

x = np.zeros(5)
print_array(x)
x2 = np.ones(5)
print_array(x2)

x = np.full((2, 2), 1)
print_matrix(x)
x3 = np.zeros(5)
print_array(x3)

x4 = np.full((2, 2), 1)
print_matrix(x4)

#x = np.empty([2, 2])
#print(list(x.shape))
Expand Down

0 comments on commit 114c817

Please sign in to comment.