def type_to_tree(tree, t): """ Converts a type to its respective AST Tree representation. """ if isinstance(t, ListType): inner = SymbolExpressionVisitor.type_to_tree(tree, t.inner) return Tree('list_type', [Tree('types', [inner])]) if isinstance(t, MapType): key = SymbolExpressionVisitor.type_to_tree(tree, t.key) value = SymbolExpressionVisitor.type_to_tree(tree, t.value) return Tree('map_type', [ key, Tree('types', [value]), ]) if t == BooleanType.instance(): base_type = tree.create_token('BOOLEAN_TYPE', 'boolean') elif t == IntType.instance(): base_type = tree.create_token('INTEGER_TYPE', 'int') elif t == FloatType.instance(): base_type = tree.create_token('FLOAT_TYPE', 'float') elif t == StringType.instance(): base_type = tree.create_token('STRING_TYPE', 'string') elif t == TimeType.instance(): base_type = tree.create_token('TIME_TYPE', 'time') elif t == RegExpType.instance(): base_type = tree.create_token('REGEXP_TYPE', 'regex') else: assert t == AnyType.instance() base_type = tree.create_token('ANY_TYPE', 'any') return Tree('base_type', [base_type])
def test_none_op(): none = NoneType.instance() assert none.binary_op(none, Token('MINUS', '-')) is None assert none.binary_op(IntType.instance(), Token('MINUS', '-')) is None assert none.binary_op(IntType.instance(), Token('PLUS', '+')) is None assert none.binary_op(StringType.instance(), Token('PLUS', '+')) is None assert none.binary_op(AnyType.instance(), None) is None
def test_mutation_pretty_b(): args = { "a": Symbol("a", IntType.instance()), "b": Symbol("b", StringType.instance()), } fn = MutationFunction("foo", args, AnyType.instance(), desc="") assert fn.pretty() == "foo(a:`int` b:`string`)"
def test_none_op(): none = NoneType.instance() assert none.binary_op(none, Token("MINUS", "-")) is None assert none.binary_op(IntType.instance(), Token("MINUS", "-")) is None assert none.binary_op(IntType.instance(), Token("PLUS", "+")) is None assert none.binary_op(StringType.instance(), Token("PLUS", "+")) is None assert none.binary_op(AnyType.instance(), None) is None
def base_type(self, tree): """ Resolves a base type expression to a type """ assert tree.data == 'base_type' tok = tree.first_child() if tok.type == 'BOOLEAN_TYPE': return base_symbol(BooleanType.instance()) elif tok.type == 'INT_TYPE': return base_symbol(IntType.instance()) elif tok.type == 'FLOAT_TYPE': return base_symbol(FloatType.instance()) elif tok.type == 'STRING_TYPE': return base_symbol(StringType.instance()) elif tok.type == 'ANY_TYPE': return base_symbol(AnyType.instance()) elif tok.type == 'OBJECT_TYPE': return base_symbol(ObjectType.instance()) elif tok.type == 'FUNCTION_TYPE': return base_symbol(AnyType.instance()) elif tok.type == 'TIME_TYPE': return base_symbol(TimeType.instance()) else: assert tok.type == 'REGEXP_TYPE' return base_symbol(RegExpType.instance())
def test_symbols_pretty(): int_sym = Symbol('foo', IntType.instance()) string_sym = Symbol('bar', StringType.instance()) symbols = Symbols() symbols.insert(int_sym) symbols.insert(string_sym) assert symbols.pretty() == 'foo: int\nbar: string\n' assert symbols.pretty(indent=' ') == ' foo: int\n bar: string\n'
def test_symbols_pretty(): int_sym = Symbol("foo", IntType.instance()) string_sym = Symbol("bar", StringType.instance()) symbols = Symbols() symbols.insert(int_sym) symbols.insert(string_sym) assert symbols.pretty() == "foo: int\nbar: string\n" assert symbols.pretty(indent=" ") == " foo: int\n bar: string\n"
def get_type_instance(cls, ty): """ Maps a type class from the hub SDK to its corresponding TypeClass in the compiler. """ assert isinstance(ty, OutputBase), ty if isinstance(ty, OutputBoolean): return BooleanType.instance() if isinstance(ty, OutputInt): return IntType.instance() if isinstance(ty, OutputFloat): return FloatType.instance() if isinstance(ty, OutputString): return StringType.instance() if isinstance(ty, OutputAny): return AnyType.instance() if isinstance(ty, OutputObject): return ObjectType( { k: Symbol( k, cls.get_type_instance(v), storage_class=StorageClass.read(), desc=v.help(), ) for k, v in ty.properties().items() } ) if isinstance(ty, OutputList): return ListType(cls.get_type_instance(ty.elements()),) if isinstance(ty, OutputNone): return NoneType.instance() if isinstance(ty, OutputRegex): return RegExpType.instance() if isinstance(ty, OutputEnum): return StringType.instance() assert isinstance(ty, OutputMap), f"Unknown Hub Type: {ty!r}" return MapType( cls.get_type_instance(ty.keys()), cls.get_type_instance(ty.values()), )
def names(self, tree): """ Extracts names from a path tree """ assert tree.data == "path" main_name = tree.child(0).value names = [NamedPath(main_name, main_name, IndexKind.FIRST)] for fragment in tree.children[1:]: child = fragment.child(0) kind = IndexKind.INDEX if isinstance(child, Tree): child.expect(child.data != "null", "path_index_no_null") if child.data == "string": type_ = StringType.instance() value = child.child(0).value elif child.data == "boolean": type_ = BooleanType.instance() value = child.child(0).value elif child.data == "range": self.module.storycontext.deprecate(child, "no_range") type_ = RangeType.instance() value = "range" elif child.data == "number": type_ = self.number(child) value = child.child(0).value else: assert child.data == "path" type_ = self.path(child) value = child.child(0).value else: assert child.type == "NAME" kind = IndexKind.DOT value = child.value type_ = StringType.instance() names.append(NamedPath(value, type_, kind)) return names
def parse_type(type_): """ Parses a type string and returns its parsed type which can be a: - BaseType (e.g. `IntType`) - TypeSymbol (e.g. `TypeSymbol(A)`) - GenericType (e.g. `ListGenericType(TypeSymbol(A))`) """ assert len(type_) > 0 type_ = type_.strip() if type_ == "boolean": return BooleanType.instance() if type_ == "int": return IntType.instance() if type_ == "float": return FloatType.instance() if type_ == "string": return StringType.instance() if type_ == "time": return TimeType.instance() if type_ == "none": return NoneType.instance() if type_ == "regexp": return RegExpType.instance() if type_ == "any": return AnyType.instance() if "[" in type_: types = [] for t in parse_type_inner(type_).split(","): t2 = parse_type(t) types.append(t2) if type_.startswith("List["): return ListGenericType(types) else: assert type_.startswith("Map[") return MapGenericType(types) assert "]" not in type_ return TypeSymbol(type_)
def test_symbol_desc_string(): sym = Symbol("foo", StringType.instance(), desc=".desc.") assert sym.desc() == ".desc."
def test_symbol_str_string(): sym = Symbol("foo", StringType.instance()) assert str(sym) == "Symbol('foo', string, wa)"
def test_symbol_pretty_string(): sym = Symbol("foo", StringType.instance()) assert sym.pretty() == "string"
def test_symbol_pretty_string(): sym = Symbol('foo', StringType.instance()) assert sym.pretty() == 'string'
def test_symbol_str_ro_string(): sym = Symbol("foo", StringType.instance(), storage_class=StorageClass.read()) assert str(sym) == "Symbol('foo', string, r-)"
assert single_fn() == 1 assert c == 1 @mark.parametrize( "type_,expected", [ (BooleanType.instance(), "boolean"), (IntType.instance(), "int"), (FloatType.instance(), "float"), (NoneType.instance(), "none"), (AnyType.instance(), "any"), (RegExpType.instance(), "regexp"), (ListType(AnyType.instance()), "List[any]"), ( MapType(IntType.instance(), StringType.instance()), "Map[int,string]", ), (NullType.instance(), "null"), ], ) def test_boolean_str(type_, expected): assert str(type_) == expected def test_none_eq(): assert NoneType.instance() == NoneType.instance() assert NoneType.instance() != IntType.instance() assert NoneType.instance() != AnyType.instance()
# -*- coding: utf-8 -*- from storyscript.compiler.semantics.types.Types import ( MapType, ObjectType, StringType, ) from .Symbols import StorageClass, Symbol, Symbols app_props = { "secrets": Symbol( name="secrets", type_=ObjectType( obj=MapType(StringType.instance(), StringType.instance())), storage_class=StorageClass.read(), desc="Secret variables of this application", ), "hostname": Symbol( name="hostname", type_=StringType.instance(), storage_class=StorageClass.read(), desc="Server hostname of this application", ), "version": Symbol( name="version", type_=StringType.instance(), storage_class=StorageClass.read(),
def throw_statement(self, tree, scope): tree.expect(tree.entity is not None, 'throw_only_string') sym = self.resolver.entity(tree.entity) tree.entity.expect(sym.type() == StringType.instance(), 'throw_only_string')
('foo[a, b] arg:list[int] a2:bar', ['foo[a, b]', 'arg:list[int]', 'a2:bar']), ('foo[a, b] arg:foo[bar]', ['foo[a, b]', 'arg:foo[bar]']), ('foo[bar[abc]] arg:foo[bar]', ['foo[bar[abc]]', 'arg:foo[bar]']), ]) def test_split_args(text, expected): assert [*split_type_arguments(text)] == expected @mark.parametrize('text,expected', [ ('any', AnyType.instance()), ('boolean', BooleanType.instance()), ('float', FloatType.instance()), ('int', IntType.instance()), ('none', NoneType.instance()), ('string', StringType.instance()), ('time', TimeType.instance()), ('A', TypeSymbol('A')), ]) def test_parse_type_base(text, expected): t = parse_type(text) assert str(t) == str(expected) @mark.parametrize('text,expected_type,expected_symbols', [ ('List[int]', ListGenericType, [IntType.instance()]), ('List[float]', ListGenericType, [FloatType.instance()]), ('Map[int,string]', MapGenericType, [IntType.instance(), StringType.instance()]), ('List[A]', ListGenericType, [TypeSymbol('A')]), ('Map[A,B]', MapGenericType, [TypeSymbol('A'),
RegExpType, StringType, ) from storyscript.hub.TypeMappings import TypeMappings @mark.parametrize( "expected,hub", [ (BooleanType.instance(), OutputBoolean(data={})), (IntType.instance(), OutputInt(data={})), (FloatType.instance(), OutputFloat(data={})), (NoneType.instance(), OutputNone(data={})), (AnyType.instance(), OutputAny(data={})), (RegExpType.instance(), OutputRegex(data={})), (StringType.instance(), OutputEnum(data={})), ( ListType(AnyType.instance()), OutputList(OutputAny.create(), data={}), ), ( ListType(IntType.instance()), OutputList(OutputInt(data={}), data={}), ), ( MapType(IntType.instance(), StringType.instance()), OutputMap(OutputInt(data={}), OutputString(data={}), data={}), ), ( ObjectType({ "i": IntType.instance(),
single_fn = singleton(test_fn) assert single_fn() == 1 assert single_fn() == 1 assert c == 1 @mark.parametrize('type_,expected', [ (BooleanType.instance(), 'boolean'), (IntType.instance(), 'int'), (FloatType.instance(), 'float'), (NoneType.instance(), 'none'), (AnyType.instance(), 'any'), (RegExpType.instance(), 'regexp'), (ListType(AnyType.instance()), 'List[any]'), (MapType(IntType.instance(), StringType.instance()), 'Map[int,string]'), ]) def test_boolean_str(type_, expected): assert str(type_) == expected def test_none_eq(): assert NoneType.instance() == NoneType.instance() assert NoneType.instance() != IntType.instance() assert NoneType.instance() != AnyType.instance() def test_none_assign(): assert not NoneType.instance().can_be_assigned(IntType.instance()) assert not NoneType.instance().can_be_assigned(AnyType.instance())
# -*- coding: utf-8 -*- from storyscript.compiler.semantics.types.Types import MapType, ObjectType, \ StringType from .Symbols import StorageClass, Symbol, Symbols app_props = { 'secrets': Symbol(name='secrets', type_=ObjectType(obj=MapType(StringType.instance(), StringType.instance())), storage_class=StorageClass.read()), 'hostname': Symbol(name='hostname', type_=StringType.instance(), storage_class=StorageClass.read()), 'version': Symbol(name='version', type_=StringType.instance(), storage_class=StorageClass.read()), } app_keyword = Symbol(name='app', type_=ObjectType(obj=app_props), storage_class=StorageClass.read()) class Scope: """ Manages an individual scope """ def __init__(self, parent=None): self._parent = parent self._symbols = Symbols()
def string(self, tree): """ Compiles a string tree. """ assert tree.data == 'string' return base_symbol(StringType.instance())
def test_parse_end_error(): with raises(AssertionError): parse_type_inner("foo[bar") @mark.parametrize( "text,expected", [ ("any", AnyType.instance()), ("boolean", BooleanType.instance()), ("float", FloatType.instance()), ("int", IntType.instance()), ("none", NoneType.instance()), ("string", StringType.instance()), ("time", TimeType.instance()), ("A", TypeSymbol("A")), ], ) def test_parse_type_base(text, expected): t = parse_type(text) assert str(t) == str(expected) @mark.parametrize( "text,expected_type,expected_symbols", [ ("List[int]", ListGenericType, [IntType.instance()]), ("List[float]", ListGenericType, [FloatType.instance()]), (