1 #!/usr/bin/env python 2 3 """ 4 Encoder functions, producing representations of program objects. 5 6 Copyright (C) 2016 Paul Boddie <paul@boddie.org.uk> 7 8 This program is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free Software 10 Foundation; either version 3 of the License, or (at your option) any later 11 version. 12 13 This program is distributed in the hope that it will be useful, but WITHOUT 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 details. 17 18 You should have received a copy of the GNU General Public License along with 19 this program. If not, see <http://www.gnu.org/licenses/>. 20 """ 21 22 from common import first 23 24 # Output encoding and decoding for the summary files. 25 26 def encode_attrnames(attrnames): 27 28 "Encode the 'attrnames' representing usage." 29 30 return ", ".join(attrnames) or "{}" 31 32 def encode_constrained(constrained): 33 34 "Encode the 'constrained' status for program summaries." 35 36 return constrained and "constrained" or "deduced" 37 38 def encode_usage(usage): 39 40 "Encode attribute details from 'usage'." 41 42 all_attrnames = [] 43 for t in usage: 44 all_attrnames.append(t) 45 return ", ".join(all_attrnames) or "{}" 46 47 def encode_access_location(t): 48 49 "Encode the access location 't'." 50 51 path, name, attrname, version = t 52 return "%s %s %s:%d" % (path, name or "{}", attrname, version) 53 54 def encode_location(t): 55 56 "Encode the general location 't' in a concise form." 57 58 path, name, attrname, version = t 59 if name is not None and version is not None: 60 return "%s %s:%d" % (path, name, version) 61 elif name is not None: 62 return "%s %s" % (path, name) 63 else: 64 return "%s :%s" % (path, attrname) 65 66 def encode_modifiers(modifiers): 67 68 "Encode assignment details from 'modifiers'." 69 70 all_modifiers = [] 71 for t in modifiers: 72 all_modifiers.append(encode_modifier_term(t)) 73 return "".join(all_modifiers) 74 75 def encode_modifier_term(t): 76 77 "Encode modifier 't' representing assignment status." 78 79 assignment = t 80 return assignment and "A" or "_" 81 82 def decode_modifier_term(s): 83 84 "Decode modifier term 's' representing assignment status." 85 86 return s == "A" 87 88 89 90 # Test generation functions. 91 92 def get_kinds(all_types): 93 94 """ 95 Return object kind details for 'all_types', being a collection of 96 references for program types. 97 """ 98 99 return map(lambda ref: ref.get_kind(), all_types) 100 101 def test_for_kind(prefix, kind): 102 103 "Return a test condition identifier featuring 'prefix' and 'kind'." 104 105 return "%s-%s" % (prefix, kind == "<instance>" and "instance" or "type") 106 107 def test_for_kinds(prefix, all_kinds): 108 109 """ 110 Return an identifier describing test conditions incorporating the given 111 'prefix' and involving 'all_kinds', being a collection of object kinds. 112 """ 113 114 return test_for_kind(prefix, first(all_kinds)) 115 116 def test_for_type(prefix, ref): 117 118 """ 119 Return an identifier describing a test condition incorporating the given 120 'prefix' and involving 'ref', being a program type reference. The kind of 121 the reference is employed in the identifier. 122 """ 123 124 return test_for_kind(prefix, ref.get_kind()) 125 126 127 128 # Output program encoding. 129 130 def encode_function_pointer(path): 131 132 "Encode 'path' as a reference to an output program function." 133 134 return "__fn_%s" % encode_path(path) 135 136 def encode_instantiator_pointer(path): 137 138 "Encode 'path' as a reference to an output program instantiator." 139 140 return "__new_%s" % encode_path(path) 141 142 def encode_path(path): 143 144 "Encode 'path' as an output program object, translating special symbols." 145 146 if path in reserved_words: 147 return "__%s" % path 148 else: 149 return path.replace("#", "__").replace("$", "__").replace(".", "_") 150 151 def encode_symbol(symbol_type, path=None): 152 153 "Encode a symbol with the given 'symbol_type' and optional 'path'." 154 155 return "__%s%s" % (symbol_type, path and "_%s" % encode_path(path) or "") 156 157 158 159 # Output language reserved words. 160 161 reserved_words = [ 162 "break", "char", "const", "continue", 163 "default", "double", "else", 164 "float", "for", 165 "if", "int", "long", 166 "NULL", 167 "return", "struct", 168 "typedef", 169 "void", "while", 170 ] 171 172 # vim: tabstop=4 expandtab shiftwidth=4