Coverage for skema/gromet/primitive_map.py: 0%

709 statements  

« prev     ^ index     » next       coverage.py v7.5.0, created at 2024-04-30 17:15 +0000

1from typing import Iterator, Union, Tuple, Dict, List, Set, Any 

2from dataclasses import dataclass 

3import numpy 

4 

5import sys 

6import inspect 

7 

8 

9@dataclass(frozen=True) 

10class Field: 

11 name: str 

12 type: str 

13 variatic: bool = False 

14 

15 

16@dataclass 

17class RecordField: 

18 name: str 

19 value_type: type 

20 value: Any 

21 

22 

23@dataclass 

24class Record(object): 

25 name: str 

26 fields: "list[RecordField]" 

27 

28 

29class UAdd(object): 

30 source_language_name = {"Python": "UAdd", "CAST": "UAdd"} 

31 inputs = [Field("operand", "Number")] 

32 outputs = [Field("result", "Number")] 

33 shorthand = "u+" 

34 documentation = "" 

35 

36 def exec( 

37 operand: Union[int, float, complex] 

38 ) -> Union[int, float, complex]: 

39 return +operand 

40 

41 

42class USub(object): 

43 source_language_name = {"Python": "USub", "CAST": "USub"} 

44 inputs = [Field("operand", "Number")] 

45 outputs = [Field("result", "Number")] 

46 shorthand = "u-" 

47 documentation = "" 

48 

49 def exec( 

50 operand: Union[int, float, complex] 

51 ) -> Union[int, float, complex]: 

52 return -operand 

53 

54 

55class Not(object): 

56 source_language_name = {"Python": "Not", "CAST": "Not"} 

57 inputs = [Field("operand", "Boolean")] 

58 outputs = [Field("result", "Boolean")] 

59 shorthand = "not" 

60 documentation = "" 

61 

62 def exec(operand: bool) -> bool: 

63 return not operand 

64 

65 

66class Invert(object): 

67 source_language_name = {"Python": "Invert", "CAST": "Invert"} 

68 inputs = [Field("operand", "Number")] 

69 outputs = [Field("result", "Number")] 

70 shorthand = "~" 

71 documentation = "" 

72 

73 def exec( 

74 operand: Union[int, float, complex] 

75 ) -> Union[int, float, complex]: 

76 return ~operand 

77 

78 

79class Add(object): 

80 source_language_name = {"Python": "Add", "GCC": "plus_expr", "CAST": "Add"} 

81 inputs = [Field("augend", "Number"), Field("addend", "Number")] 

82 outputs = [Field("sum", "Number")] 

83 shorthand = "+" 

84 documentation = "Add is the numerical addition operator. For a general addition operation (For example, the case of concatanation with +) see GenAdd." 

85 

86 @staticmethod # TODO: Look into if this is required. Only need @staticmethod if you intend to call the method from an instance of class 

87 def exec( 

88 augend: Union[int, float, complex], addend: Union[int, float, complex] 

89 ) -> Union[int, float, complex]: 

90 return augend + addend 

91 

92 

93class GenAdd(object): 

94 source_language_name = {"Python": "Add"} 

95 inputs = [Field("operand1", "Any"), Field("operand2", "Any")] 

96 outputs = [Field("result", "Any")] 

97 shorthand = "g+" 

98 documentation = "" 

99 

100 def exec(operand1: Any, operand2: Any) -> Any: 

101 return operand1 + operand2 

102 

103 

104class Sub(object): 

105 source_language_name = { 

106 "Python": "Sub", 

107 "GCC": "minus_expr", 

108 "CAST": "Sub", 

109 } 

110 inputs = [Field("minuend", "Number"), Field("subtrahend", "Number")] 

111 outputs = [Field("difference", "Number")] 

112 shorthand = "-" 

113 documentation = "Sub is the numerical subtraction operator. For a general subtraction operation () see GenSub." 

114 

115 def exec( 

116 minuend: Union[int, float, complex], 

117 subtahend: Union[int, float, complex], 

118 ) -> Union[int, float, complex]: 

119 return minuend - subtahend 

120 

121 

122class GenSub(object): 

123 source_language_name = {"Python": "Sub"} 

124 inputs = [Field("operand1", "Any"), Field("operand2", "Any")] 

125 outputs = [Field("result", "Any")] 

126 shorthand = "g-" 

127 documentation = "" 

128 

129 def exec(operand1: Any, operand2: Any) -> Any: 

130 return operand1 - operand2 

131 

132 

133class Mult(object): 

134 source_language_name = { 

135 "Python": "Mult", 

136 "GCC": "mult_expr", 

137 "CAST": "Mult", 

138 } 

139 inputs = [Field("multiplier", "Number"), Field("multiplicand", "Number")] 

140 outputs = [Field("product", "Number")] 

141 shorthand = "*" 

142 documentation = "" 

143 

144 def exec( 

145 multiplier: Union[int, float, complex], 

146 multiplicand: Union[int, float, complex], 

147 ) -> Union[int, float, complex]: 

148 return multiplier * multiplicand 

149 

150 

151# TODO: Do we need a general operator for all overloadable operators in Python (https://www.programiz.com/python-programming/operator-overloading)? 

152 

153 

154class Div(object): 

155 source_language_name = {"Python": "Div", "GCC": "rdiv_expr", "CAST": "Div"} 

156 inputs = [Field("dividend", "Number"), Field("divisor", "Number")] 

157 outputs = [Field("quotient", "Number")] 

158 shorthand = "/" 

159 documentation = "" 

160 

161 def exec( 

162 dividend: Union[int, float, complex], 

163 divisor: Union[int, float, complex], 

164 ) -> Union[int, float, complex]: 

165 return dividend / divisor 

166 

167 

168class FloorDiv(object): 

169 source_language_name = {"Python": "FloorDiv", "CAST": "FloorDiv"} 

170 inputs = [Field("dividend", "Number"), Field("divisor", "Number")] 

171 outputs = [Field("quotient", "Number")] 

172 shorthand = "//" 

173 documentation = "" 

174 

175 def exec( 

176 dividend: Union[int, float, complex], 

177 divisor: Union[int, float, complex], 

178 ) -> Union[int, float, complex]: 

179 return dividend // divisor 

180 

181 

182class Mod(object): 

183 source_language_name = { 

184 "Python": "Mod", 

185 "GCC": "trunc_mod_expr", 

186 "CAST": "Mod", 

187 } 

188 inputs = [Field("dividend", "Number"), Field("divisor", "Number")] 

189 outputs = [Field("remainder", "Number")] 

190 shorthand = "%" 

191 documentation = "" 

192 

193 def exec( 

194 dividend: Union[int, float, complex], 

195 divisor: Union[int, float, complex], 

196 ) -> Union[int, float, complex]: 

197 return dividend % divisor 

198 

199 

200class Pow(object): 

201 source_language_name = {"Python": "Pow", "CAST": "Pow"} 

202 inputs = [Field("base", "Number"), Field("exponent", "Number")] 

203 outputs = [Field("power", "Number")] 

204 shorthand = "**" 

205 documentation = "" 

206 

207 def exec( 

208 base: Union[int, float, complex], power: Union[int, float, complex] 

209 ) -> Union[int, float, complex]: 

210 return base**power 

211 

212 

213class LShift(object): 

214 source_language_name = { 

215 "Python": "LShift", 

216 "GCC": "lshift_expr", 

217 "CAST": "LShift", 

218 } 

219 inputs = [Field("operand1", "Number"), Field("operand2", "Number")] 

220 outputs = [Field("result", "Number")] 

221 shorthand = "<<" 

222 documentation = "" 

223 

224 def exec( 

225 operand1: Union[int, float, complex], 

226 operand2: Union[int, float, complex], 

227 ) -> Union[int, float, complex]: 

228 return operand1 << operand2 

229 

230 

231class RShift(object): 

232 source_language_name = { 

233 "Python": "RShift", 

234 "GCC": "rshift_expr", 

235 "CAST": "RShift", 

236 } 

237 inputs = [Field("operand1", "Number"), Field("operand2", "Number")] 

238 outputs = [Field("result", "Number")] 

239 shorthand = ">>" 

240 documentation = "" 

241 

242 def exec( 

243 operand1: Union[int, float, complex], 

244 operand2: Union[int, float, complex], 

245 ) -> Union[int, float, complex]: 

246 return operand1 >> operand2 

247 

248 

249class BitOr(object): 

250 source_language_name = { 

251 "Python": "BitOr", 

252 "GCC": "bit_ior_expr", 

253 "CAST": "BitOr", 

254 } 

255 inputs = [Field("binary1", "Number"), Field("binary2", "Number")] 

256 outputs = [Field("result", "Number")] 

257 shorthand = "|" 

258 documentation = "" 

259 

260 def exec( 

261 binary1: Union[int, float, complex], 

262 binary2: Union[int, float, complex], 

263 ) -> Union[int, float, complex]: 

264 return binary1 | binary2 

265 

266 

267class BitXor(object): 

268 source_language_name = { 

269 "Python": "BitXor", 

270 "GCC": "bit_xor_expr", 

271 "CAST": "BitXor", 

272 } 

273 inputs = [Field("binary1", "Number"), Field("binary2", "Number")] 

274 outputs = [Field("result", "Number")] 

275 shorthand = "^" 

276 documentation = "" 

277 

278 def exec( 

279 binary1: Union[int, float, complex], 

280 binary2: Union[int, float, complex], 

281 ) -> Union[int, float, complex]: 

282 return binary1 ^ binary2 

283 

284 

285class BitAnd(object): 

286 source_language_name = { 

287 "Python": "BitAnd", 

288 "GCC": "bit_and_expr", 

289 "CAST": "BitAnd", 

290 } 

291 inputs = [Field("binary1", "Number"), Field("binary2", "Number")] 

292 outputs = [Field("result", "Number")] 

293 shorthand = "&" 

294 documentation = "" 

295 

296 def exec( 

297 binary1: Union[int, float, complex], 

298 binary2: Union[int, float, complex], 

299 ) -> Union[int, float, complex]: 

300 return binary1 & binary2 

301 

302 

303class And(object): 

304 source_language_name = { 

305 "Python": "And", 

306 "GCC": "logical_and", 

307 "CAST": "And", 

308 } 

309 inputs = [Field("logical1", "Boolean"), Field("logical2", "Boolean")] 

310 outputs = [Field("result", "Boolean")] 

311 shorthand = "and" 

312 documentation = "" 

313 

314 def exec(logical1: bool, logical2: bool) -> bool: 

315 return logical1 and logical2 

316 

317 

318class Or(object): 

319 source_language_name = {"Python": "Or", "GCC": "logical_or", "CAST": "Or"} 

320 inputs = [Field("logical1", "Boolean"), Field("logical2", "Boolean")] 

321 outputs = [Field("result", "Boolean")] 

322 shorthand = "or" 

323 documentation = "" 

324 

325 def exec(logical1: bool, logical2: bool) -> bool: 

326 return logical1 or logical2 

327 

328 

329class Eq(object): 

330 source_language_name = {"Python": "Eq", "GCC": "eq_expr", "CAST": "Eq"} 

331 inputs = [Field("operand1", "Any"), Field("operand2", "Any")] 

332 outputs = [Field("result", "Boolean")] 

333 shorthand = "==" 

334 documentation = "" 

335 

336 def exec(operand1: Any, operand2: Any) -> bool: 

337 return operand1 == operand2 

338 

339 

340class NotEq(object): 

341 source_language_name = { 

342 "Python": "NotEq", 

343 "GCC": "ne_expr", 

344 "CAST": "NotEq", 

345 } 

346 inputs = [Field("operand1", "Any"), Field("operand2", "Any")] 

347 outputs = [Field("result", "Boolean")] 

348 shorthand = "!=" 

349 documentation = "" 

350 

351 def exec(operand1: Any, operand2: Any) -> bool: 

352 return operand1 != operand2 

353 

354 

355class Lt(object): 

356 source_language_name = {"Python": "Lt", "GCC": "lt_expr", "CAST": "Lt"} 

357 inputs = [Field("number1", "Number"), Field("number2", "Number")] 

358 outputs = [Field("result", "Boolean")] 

359 shorthand = "<" 

360 documentation = "" 

361 

362 def exec( 

363 number1: Union[int, float, complex], 

364 number2: Union[int, float, complex], 

365 ) -> bool: 

366 return number1 < number2 

367 

368 

369class Lte(object): 

370 source_language_name = { 

371 "Python": "Lte", 

372 "GCC": "le_expr", 

373 "CAST": "Lte", 

374 } # TODO: Is it LtE or Lte for Python and CAST 

375 inputs = [Field("number1", "Number"), Field("number2", "Number")] 

376 outputs = [Field("result", "Boolean")] 

377 shorthand = "<=" 

378 documentation = "" 

379 

380 def exec( 

381 number1: Union[int, float, complex], 

382 number2: Union[int, float, complex], 

383 ) -> bool: 

384 return number1 <= number2 

385 

386 

387class Gt(object): 

388 source_language_name = {"Python": "Gt", "GCC": "gt_expr", "CAST": "Gt"} 

389 inputs = [Field("number1", "Number"), Field("number2", "Number")] 

390 outputs = [Field("result", "Boolean")] 

391 shorthand = ">" 

392 documentation = "" 

393 

394 def exec( 

395 number1: Union[int, float, complex], 

396 number2: Union[int, float, complex], 

397 ) -> bool: 

398 return number1 > number2 

399 

400 

401class Gte(object): 

402 source_language_name = {"Python": "GtE", "GCC": "ge_expr", "CAST": "Gte"} 

403 inputs = [Field("number1", "Number"), Field("number2", "Number")] 

404 outputs = [Field("result", "Boolean")] 

405 shorthand = ">=" 

406 documentation = "" 

407 

408 def exec( 

409 number1: Union[int, float, complex], 

410 number2: Union[int, float, complex], 

411 ) -> bool: 

412 return number1 >= number2 

413 

414 

415class In( 

416 object 

417): # TODO: How should In and NotIn work? What is the difference between in, member, List_in? 

418 source_language_name = {"Python": "In", "CAST": "In"} 

419 inputs = [Field("container_input", "Any"), Field("value", "Any")] 

420 outputs = [Field("result", "Boolean")] 

421 shorthand = "in" 

422 documentation = "" 

423 

424 def exec(container_input: Any, value: Any) -> bool: 

425 return value in container_input 

426 

427 

428class NotIn( 

429 object 

430): # TODO: How should In and NotIn work? What is the difference between in, member, List_in? 

431 source_language_name = {"Python": "NotIn", "CAST": "NotIn"} 

432 inputs = [Field("container_input", "Any"), Field("value", "Any")] 

433 outputs = [Field("result", "Boolean")] 

434 shorthand = "not in" 

435 documentation = "" 

436 

437 def exec(container_input: Any, value: Any) -> bool: 

438 return value not in container_input 

439 

440 

441class Set_new_Iterator(object): 

442 source_language_name = {"Python": "Set_new_Iterator"} 

443 inputs = [Field("set_input", "Set")] 

444 outputs = [Field("set_iterator", "IteratorSet")] 

445 shorthand = "Set_new_Iterator" 

446 documentation = "" 

447 

448 def exec(set_input: set) -> Iterator[set]: 

449 return iter(set_input) 

450 

451 

452class Set_in(object): 

453 source_language_name = {"Python": "Set_in"} 

454 inputs = [Field("set_input", "set"), Field("value", "Any")] 

455 outputs = [Field("result", "Boolean")] 

456 shorthand = "Set_in" 

457 documentation = "" 

458 

459 def exec(set_input: set, value: Any) -> bool: 

460 return value in set_input 

461 

462 

463class new_Set(object): 

464 source_language_name = {"Python": "new_set"} 

465 inputs = [Field("elements", "Any", True)] 

466 outputs = [Field("set_output", "Set")] 

467 shorthand = "new_Set" 

468 documentation = "" 

469 

470 def exec(*elements: Any) -> set: 

471 return set(elements) 

472 

473 

474class member(object): # TODO: Still unsure the difference between this and in 

475 source_language_name = {"Python": "member"} 

476 inputs = [Field("set_input", "Set", True), Field("value", "Any")] 

477 outputs = [Field("result", "Boolean")] 

478 shorthand = "member" 

479 documentation = "" 

480 

481 def exec(set_input: set, value: Any) -> set: 

482 return value in set_input 

483 

484 

485class add_elm(object): 

486 source_language_name = {"Python": "add_elm"} 

487 inputs = [Field("input_set", "Set"), Field("element", "Any")] 

488 outputs = [Field("set_output", "Set")] 

489 shorthand = "add_elm" 

490 documentation = "" 

491 

492 def exec(input_set: set, element: Any) -> set: 

493 return input_set.add(element) 

494 

495 

496class del_elm(object): 

497 source_language_name = {"Python": "del_elm"} 

498 inputs = [Field("input_set", "Set"), Field("element", "Any")] 

499 outputs = [Field("set_output", "Set")] 

500 shorthand = "del_elm" 

501 documentation = "" 

502 

503 def exec(input_set: set, element: Any) -> set: 

504 return input_set.remove( 

505 element 

506 ) # TODO: Do we need to check if this exists first? Will throw KeyError if it does not 

507 

508 

509class List_get(object): 

510 source_language_name = {"Python": "List_get"} # TODO: What should this be? 

511 inputs = [Field("list_input", "List"), Field("index", "Integer")] 

512 outputs = [Field("item", "Any")] 

513 shorthand = "List_get" 

514 documentation = "" 

515 

516 def exec(list_input: list, index: int) -> Any: 

517 return list_input[index] 

518 

519 

520class List_set(object): 

521 source_language_name = {"Python": "List_set"} 

522 inputs = [ 

523 Field("list_input", "List"), 

524 Field("index", "Integer"), 

525 Field("value", "Any"), 

526 ] 

527 outputs = [Field("list_output", "List")] 

528 shorthand = "List_set" 

529 documentation = "" 

530 

531 def exec(list_input: list, index: int, value: Any) -> list: 

532 list_input[index] = value 

533 return list_input 

534 

535 

536class List_in(object): 

537 source_language_name = {"Python": "List_in"} 

538 inputs = [Field("list_input", "List"), Field("value", "Any")] 

539 outputs = [Field("result", "Boolean")] 

540 shorthand = "List_in" 

541 documentation = "" 

542 

543 def exec(list_input: list, value: Any) -> bool: 

544 return value in list_input 

545 

546 

547class List_new_Iterator(object): 

548 source_language_name = {"Python": "List_new_Iterator"} 

549 inputs = [Field("list_input", "List")] 

550 outputs = [Field("list_iterator", "IteratorList")] 

551 shorthand = "List_new_Iterator" 

552 documentation = "" 

553 

554 def exec(list_input: list) -> Iterator[list]: 

555 return iter(list_input) 

556 

557 

558class new_List(object): 

559 source_language_name = {"Python": "new_List"} 

560 inputs = [Field("elements", "Any", True)] 

561 outputs = [Field("list_output", "List")] 

562 shorthand = "new_List" 

563 documentation = "" 

564 

565 def exec(*elements: Any) -> list: 

566 return list( 

567 elements 

568 ) # Interestingly when passing variable sized arguments, it is passeed as a tuple 

569 

570 

571class new_List_num(object): 

572 source_language_name = {"Python": "new_List_num"} 

573 inputs = [Field("element", "Any", True), Field("count", "Integer")] 

574 outputs = [Field("list_output", "List")] 

575 shorthand = "new_List_num" 

576 documentation = "" 

577 

578 def exec(element: Any, count: int) -> list: 

579 return [element] * count 

580 

581 

582class Array_get( 

583 object 

584): # TODO: Should this do type checking for each element? 

585 source_language_name = {"Python": "Array_get"} 

586 inputs = [Field("array_input", "Array"), Field("index", "Integer")] 

587 outputs = [Field("item", "Any")] 

588 shorthand = "Array_get" 

589 documentation = "" 

590 

591 def exec(array_input: numpy.ndarray, index: int) -> Any: 

592 return array_input[index] 

593 

594 

595class Array_set(object): 

596 source_language_name = {"Python": "Array_set"} 

597 inputs = [ 

598 Field("array_input", "Array"), 

599 Field("index", "Integer"), 

600 Field("value", "Any"), 

601 ] 

602 outputs = [Field("array_output", "Array")] 

603 shorthand = "Array_set" 

604 documentation = "" 

605 

606 def exec( 

607 array_input: numpy.ndarray, index: int, value: Any 

608 ) -> numpy.ndarray: 

609 array_input[index] = value 

610 return array_input 

611 

612 

613class Array_in(object): 

614 source_language_name = {"Python": "Array_in"} 

615 inputs = [Field("array_input", "Array"), Field("value", "Any")] 

616 outputs = [Field("result", "Boolean")] 

617 shorthand = "Array_in" 

618 documentation = "" 

619 

620 def exec(array_input: numpy.ndarray, value: Any) -> bool: 

621 return value in array_input 

622 

623 

624class Array_new_Iterator(object): 

625 source_language_name = {"Python": "Array_new_Iterator"} 

626 inputs = [Field("array_input", "Array")] 

627 outputs = [Field("array_iterator", "IteratorArray")] 

628 shorthand = "Array_new_Iterator" 

629 documentation = "" 

630 

631 def exec( 

632 array_input: numpy.ndarray, 

633 ) -> Iterator: # TODO: Numpy array is not built in type, can we still customize type hints 

634 return iter(array_input) 

635 

636 

637class new_Array(object): 

638 source_language_name = {"Python": "new_Array"} 

639 inputs = [Field("elements", "Any", True)] 

640 outputs = [Field("array_output", "Array")] 

641 shorthand = "new_Array" 

642 documentation = "" 

643 

644 def exec(*elements: Any) -> numpy.ndarray: 

645 return numpy.array(list(elements)) 

646 

647 

648class new_Array_num(object): 

649 source_language_name = {"Python": "new_Array_num"} 

650 inputs = [Field("element", "Any", True), Field("count", "Integer")] 

651 outputs = [Field("array_output", "Array")] 

652 shorthand = "new_Array_num" 

653 documentation = "" 

654 

655 def exec(element: Any, count: int) -> numpy.ndarray: 

656 return numpy.array([element] * count) 

657 

658 

659class Tuple_get(object): 

660 source_language_name = { 

661 "Python": "Tuple_get" 

662 } # TODO: What should this be? 

663 inputs = [Field("tuple_input", "Tuple"), Field("index", "Integer")] 

664 outputs = [Field("item", "Any")] 

665 shorthand = "Tuple_get" 

666 documentation = "" 

667 

668 def exec(tuple_input: tuple, index: int) -> Any: 

669 return tuple_input[index] 

670 

671 

672class Tuple_set(object): # TODO: Should this exist? 

673 source_language_name = {"Python": "Tuple_set"} 

674 inputs = [ 

675 Field("tuple_input", "Tuple"), 

676 Field("index", "Integer"), 

677 Field("value", "Any"), 

678 ] 

679 outputs = [Field("tuple_output", "Tuple")] 

680 shorthand = "Tuple_set" 

681 documentation = "" 

682 

683 def exec(tuple_input: tuple, index: int, value: Any) -> tuple: 

684 placeholder_list = list( 

685 tuple_input 

686 ) # tuples are immutable, so conversions must be made 

687 placeholder_list[index] = value 

688 return tuple(placeholder_list) # Convert back to tuple for output 

689 

690 

691class Tuple_in(object): 

692 source_language_name = {"Python": "Tuple_in"} 

693 inputs = [Field("tuple_input", "Tuple"), Field("value", "Any")] 

694 outputs = [Field("result", "Boolean")] 

695 shorthand = "Tuple_in" 

696 documentation = "" 

697 

698 def exec(tuple_input: list, value: Any) -> bool: 

699 return value in tuple_input 

700 

701 

702class Tuple_new_Iterator(object): 

703 source_language_name = {"Python": "Tuple_new_Iterator"} 

704 inputs = [Field("tuple_input", "Tuple")] 

705 outputs = [Field("tuple_iterator", "IteratorTuple")] 

706 shorthand = "Tuple_new_Iterator" 

707 documentation = "" 

708 

709 def exec(tuple_input: list) -> Iterator[tuple]: 

710 return iter(tuple_input) 

711 

712 

713class new_Tuple(object): 

714 source_language_name = {"Python": "new_Tuple"} 

715 inputs = [Field("elements", "Any", True)] 

716 outputs = [Field("tuple_output", "Tuple")] 

717 shorthand = "new_Tuple" 

718 documentation = "" 

719 

720 def exec(*elements: Any) -> tuple: 

721 return elements # Interestingly when passing variable sized arguments, it is passeed as a tuple 

722 

723 

724class new_Tuple_num(object): 

725 source_language_name = {"Python": "new_Tuple_num"} 

726 inputs = [Field("element", "Any", True), Field("count", "Integer")] 

727 outputs = [Field("tuple_output", "Tuple")] 

728 shorthand = "new_Tuple_num" 

729 documentation = "" 

730 

731 def exec(element: Any, count: int) -> tuple: 

732 return tuple([element] * count) 

733 

734 

735class Map_get(object): 

736 source_language_name = {"Python": "Map_get"} # TODO: What should this be? 

737 inputs = [Field("map_input", "Map"), Field("index", "Any")] 

738 outputs = [Field("item", "Any")] 

739 shorthand = "Map_get" 

740 documentation = "" 

741 

742 def exec( 

743 map_input: dict, index: Any 

744 ) -> Any: # TODO: Should index really be Any for dict? 

745 return map_input[index] 

746 

747 

748class Map_set(object): 

749 source_language_name = {"Python": "Map_set"} 

750 inputs = [ 

751 Field("map_input", "List"), 

752 Field("index", "Any"), 

753 Field("value", "Any"), 

754 ] 

755 outputs = [Field("map_output", "Map")] 

756 shorthand = "Map_set" 

757 documentation = "" 

758 

759 def exec(map_input: dict, index: Any, value: Any) -> dict: 

760 map_input[index] = value 

761 return map_input 

762 

763 

764class Map_in(object): 

765 source_language_name = {"Python": "Map_in"} 

766 inputs = [Field("map_input", "List"), Field("value", "Any")] 

767 outputs = [Field("result", "Boolean")] 

768 shorthand = "Map_in" 

769 documentation = "" 

770 

771 def exec(map_input: dict, value: Any) -> bool: 

772 return value in map_input 

773 

774 

775class Map_new_Iterator(object): 

776 source_language_name = {"Python": "Map_new_Iterator"} 

777 inputs = [Field("map_input", "Map")] 

778 outputs = [Field("map_iterator", "IteratorMap")] 

779 shorthand = "Map_new_Iterator" 

780 documentation = "" 

781 

782 def exec(map_input: dict) -> Iterator[dict]: 

783 return iter(map_input) 

784 

785 

786class new_Map(object): # TODO: Should we have inputs for this? 

787 source_language_name = {"Python": "new_Map"} 

788 inputs = [] 

789 outputs = [Field("map_output", "Map")] 

790 shorthand = "new_Map" 

791 documentation = "" 

792 

793 def exec() -> dict: 

794 return {} 

795 

796 

797class new_List_num(object): 

798 source_language_name = {"Python": "new_List_num"} 

799 inputs = [Field("element", "Any", True), Field("count", "Integer")] 

800 outputs = [Field("list_output", "List")] 

801 shorthand = "new_List_num" 

802 documentation = "" 

803 

804 def exec(element: Any, count: int) -> list: 

805 return [element] * count 

806 

807 

808class Record_get(object): 

809 source_language_name = {"Python": "Record_get"} 

810 inputs = [Field("record_input", "Record"), Field("field_name", "String")] 

811 outputs = [Field("field", "Field")] 

812 shorthand = "Record_get" 

813 documentation = "" 

814 

815 def exec(record_input: Record, field_name: str) -> RecordField: 

816 for field in record_input.fields: 

817 if field.name == field_name: 

818 return field 

819 return None 

820 

821 

822class Record_set(object): 

823 source_language_name = {"Python": "Record_set"} 

824 inputs = [ 

825 Field("record_input", "Record"), 

826 Field("field_name", "String"), 

827 Field("value", "Any"), 

828 ] 

829 outputs = [Field("record_output", "Record")] 

830 shorthand = "Record_set" 

831 documentation = "" 

832 

833 def exec(record_input: Record, field_name: str, value: Any) -> Record: 

834 for field in record_input.fields: 

835 if field.name == field_name: 

836 field.value = value # TODO: Do we need type checking here? 

837 

838 

839class new_Record(object): 

840 source_language_name = {"Python": "new_Record"} 

841 inputs = [Field("record_name", "String")] 

842 outputs = [Field("record_output", "Record")] 

843 shorthand = "new_Record" 

844 documentation = "" 

845 

846 def exec(record_name: str) -> Record: 

847 return Record(record_name) 

848 

849 

850class new_Field(object): 

851 source_language_name = {"Python": "new_Field"} 

852 inputs = [ 

853 Field("record_input", "Record"), 

854 Field("field_name", "String"), 

855 Field("value_type", "Type"), 

856 ] 

857 outputs = [Field("record_output", "Record")] 

858 shorthand = "new_Field" 

859 documentation = "" 

860 

861 def exec( 

862 record_input: Record, field_name: str, value_type: type 

863 ) -> Record: 

864 return record_input.fields.append( 

865 RecordField(field_name, value_type, None) 

866 ) # #TODO: Do we need to set a default value? 

867 

868 

869class IteratorSet_next(object): 

870 source_language_name = {"Python": "IteratorSet_next"} 

871 inputs = [Field("iterator_input", "IteratorSet")] 

872 outputs = [ 

873 Field("element", "Any"), 

874 Field("iterator_output", "IteratorSet"), 

875 Field("stop_condition", "Boolean"), 

876 ] 

877 shorthand = "IteratorSet_next" 

878 documentation = "" 

879 

880 def exec(iterator_input: Iterator[set]) -> Tuple[Any, Iterator[Set], bool]: 

881 current_element = None 

882 # We have to wrap this code in a try except block because of the call to next() 

883 # next() will throw an error if you've reached the end of the iterator 

884 # You can specify a default value for it to return instead of an exception, 

885 # but we can't use this since there is no way to differentiate between a regular value and the default value 

886 

887 try: 

888 current_element = next(iterator_input) 

889 return (current_element, iterator_input, False) 

890 except: 

891 return (None, iterator_input, True) 

892 

893 

894class IteratorTuple_next(object): 

895 source_language_name = {"Python": "IteratorTuple_next"} 

896 inputs = [Field("iterator_input", "IteratorTuple")] 

897 outputs = [ 

898 Field("element", "Any"), 

899 Field("iterator_output", "IteratorTuple"), 

900 Field("stop_condition", "Boolean"), 

901 ] 

902 shorthand = "IteratorTuple_next" 

903 documentation = "" 

904 

905 def exec( 

906 iterator_input: Iterator[tuple], 

907 ) -> Tuple[Any, Iterator[Tuple], bool]: 

908 current_element = None 

909 # We have to wrap this code in a try except block because of the call to next() 

910 # next() will throw an error if you've reached the end of the iterator 

911 # You can specify a default value for it to return instead of an exception, 

912 # but we can't use this since there is no way to differentiate between a regular value and the default value 

913 

914 try: 

915 current_element = next(iterator_input) 

916 return (current_element, iterator_input, False) 

917 except: 

918 return (None, iterator_input, True) 

919 

920 

921class IteratorArray_next(object): 

922 source_language_name = {"Python": "IteratorArray_next"} 

923 inputs = [Field("iterator_input", "IteratorArray")] 

924 outputs = [ 

925 Field("element", "Any"), 

926 Field("iterator_output", "IteratorArray"), 

927 Field("stop_condition", "Boolean"), 

928 ] 

929 shorthand = "IteratorArray_next" 

930 documentation = "" 

931 

932 def exec( 

933 iterator_input: Iterator, 

934 ) -> Tuple[ 

935 Any, Iterator, bool 

936 ]: # TODO: Can we say Iterator[numpy.ndarray] 

937 current_element = None 

938 # We have to wrap this code in a try except block because of the call to next() 

939 # next() will throw an error if you've reached the end of the iterator 

940 # You can specify a default value for it to return instead of an exception, 

941 # but we can't use this since there is no way to differentiate between a regular value and the default value 

942 

943 try: 

944 current_element = next(iterator_input) 

945 return (current_element, iterator_input, False) 

946 except: 

947 return (None, iterator_input, True) 

948 

949 

950class IteratorList_next(object): 

951 source_language_name = {"Python": "IteratorList_next"} 

952 inputs = [Field("iterator_input", "IteratorList")] 

953 outputs = [ 

954 Field("element", "Any"), 

955 Field("iterator_output", "IteratorList"), 

956 Field("stop_condition", "Boolean"), 

957 ] 

958 shorthand = "IteratorList_next" 

959 documentation = "" 

960 

961 def exec( 

962 iterator_input: Iterator[List], 

963 ) -> Tuple[Any, Iterator[List], bool]: 

964 current_element = None 

965 # We have to wrap this code in a try except block because of the call to next() 

966 # next() will throw an error if you've reached the end of the iterator 

967 # You can specify a default value for it to return instead of an exception, 

968 # but we can't use this since there is no way to differentiate between a regular value and the default value 

969 

970 try: 

971 current_element = next(iterator_input) 

972 return (current_element, iterator_input, False) 

973 except: 

974 return (None, iterator_input, True) 

975 

976 

977class IteratorMap_next(object): 

978 source_language_name = {"Python": "IteratorMap_next"} 

979 inputs = [Field("iterator_input", "IteratorMap")] 

980 outputs = [ 

981 Field("element", "Any"), 

982 Field("iterator_output", "IteratorMap"), 

983 Field("stop_condition", "Boolean"), 

984 ] 

985 shorthand = "IteratorMap_next" 

986 documentation = "" 

987 

988 def exec( 

989 iterator_input: Iterator[dict], 

990 ) -> Tuple[Any, Iterator[Dict], bool]: 

991 current_element = None 

992 # We have to wrap this code in a try except block because of the call to next() 

993 # next() will throw an error if you've reached the end of the iterator 

994 # You can specify a default value for it to return instead of an exception, 

995 # but we can't use this since there is no way to differentiate between a regular value and the default value 

996 

997 try: 

998 current_element = next(iterator_input) 

999 return (current_element, iterator_input, False) 

1000 except: 

1001 return (None, iterator_input, True) 

1002 

1003 

1004class CASTGenericGet: 

1005 source_language_name = {"CAST": "_get"} 

1006 inputs = [Field("indexible_input", "Indexable"), Field("index", "Any")] 

1007 outputs = [Field("element", "Any")] 

1008 shorthand = "_get" 

1009 documentation = "The cast currently uses generic primitive operators (_get, _set, iter, next) while the Gromet uses specific operators (IteratorMap_next). These primitive ops are a tempory fix for that mismatch" 

1010 

1011 

1012class CASTGenericSet: 

1013 source_language_name = {"CAST": "_set"} 

1014 inputs = [ 

1015 Field("indexible_input", "Indexable"), 

1016 Field("index", "Any"), 

1017 Field("value", "Any"), 

1018 ] 

1019 outputs = [Field("indexible_output", "Indexable")] 

1020 shorthand = "_set" 

1021 documentation = "The cast currently uses generic primitive operators (_get, _set, iter, next) while the Gromet uses specific operators (IteratorMap_next). These primitive ops are a tempory fix for that mismatch" 

1022 

1023 

1024class CASTGenericIter: 

1025 source_language_name = {"CAST": "iter"} 

1026 inputs = [Field("iterable_input", "Iterable")] 

1027 outputs = [Field("iterator_output", "Iterator")] 

1028 shorthand = "iter" 

1029 documentation = "The cast currently uses generic primitive operators (_get, _set, iter, next) while the Gromet uses specific operators (IteratorMap_next). These primitive ops are a tempory fix for that mismatch" 

1030 

1031 

1032class CASTGenericNext: 

1033 source_language_name = {"CAST": "next"} 

1034 inputs = [Field("iterator_input", "Iterator")] 

1035 outputs = [ 

1036 Field("element", "Any"), 

1037 Field("iterator_output", "Iterator"), 

1038 Field("stop_condition", "Boolean"), 

1039 ] 

1040 shorthand = "next" 

1041 documentation = "The cast currently uses generic primitive operators (_get, _set, iter, next) while the Gromet uses specific operators (IteratorMap_next). These primitive ops are a tempory fix for that mismatch" 

1042 

1043 

1044class Is(object): 

1045 source_language_name = { 

1046 "Python": "is", 

1047 "CAST": "Is", 

1048 } # TODO: Should Python/CAST be Is or is? 

1049 inputs = [Field("operand1", "Any"), Field("operand2", "Any")] 

1050 outputs = [Field("result", "Boolean")] 

1051 shorthand = "is" 

1052 documentation = "" 

1053 

1054 def exec(operand1: Any, operand2: Any) -> bool: 

1055 return operand1 is operand2 

1056 

1057 

1058class NotIs(object): 

1059 source_language_name = { 

1060 "Python": "is not", 

1061 "CAST": "NotIs", 

1062 } # TODO: What should Python name be here? 

1063 inputs = [Field("operand1", "Any"), Field("operand2", "Any")] 

1064 outputs = [Field("result", "Boolean")] 

1065 shorthand = "not is" 

1066 documentation = "" 

1067 

1068 def exec(operand1: Any, operand2: Any) -> bool: 

1069 return operand1 is not operand2 

1070 

1071 

1072class IsInstance(object): 

1073 source_language_name = {"Python": "isinstance"} 

1074 inputs = [ 

1075 Field("operand", "Any"), 

1076 Field("type", "Type"), 

1077 ] # TODO: Get confirmation on adding Type field 

1078 outputs = [Field("result", "Boolean")] 

1079 shorthand = "type" 

1080 documentation = "" 

1081 

1082 def exec( 

1083 operand: Any, type: type 

1084 ) -> bool: # TODO: Fix name of right argument 

1085 return isinstance(operand, type) 

1086 

1087 

1088class Type(object): 

1089 source_language_name = {"Python": "type"} 

1090 inputs = [Field("operand", "Any")] 

1091 outputs = [Field("result", "Type")] 

1092 shorthand = "type" 

1093 documentation = "" 

1094 

1095 def exec(operand: Any) -> type: 

1096 return type(operand) 

1097 

1098 

1099class Print: # TODO: How should print work? Will likely not be a CASTGeneric function 

1100 source_language_name = {"CAST": "print"} 

1101 inputs = [Field("input", "Any")] 

1102 outputs = [] 

1103 shorthand = "print" 

1104 documentation = "The cast currently uses generic primitive operators (_get, _set, iter, next) while the Gromet uses specific operators (IteratorMap_next). These primitive ops are a tempory fix for that mismatch" 

1105 

1106 def exec(input: Any) -> None: 

1107 print(input) 

1108 

1109 

1110class Range: 

1111 source_language_name = {"CAST": "range"} 

1112 inputs = [Field("input", "Integer")] # TODO: What is the input to range? 

1113 outputs = [Field("range_output", "Range")] 

1114 shorthand = "range" 

1115 documentation = "" 

1116 

1117 def exec(input: int) -> range: 

1118 return range(input) 

1119 

1120 

1121#### Interface for accessing fields of classes 

1122def get_class_obj( 

1123 op: str, language: str, debug=False 

1124) -> Any: # TODO: Update the type hints for this 

1125 global primitive_map 

1126 

1127 try: 

1128 return primitive_map[language][op] 

1129 except: 

1130 if debug: 

1131 print( 

1132 f"Operation not supported: {op} for language {language} ... Returning None" 

1133 ) 

1134 return None 

1135 

1136 

1137def get_shorthand(op: str, language: str) -> str: 

1138 class_obj = get_class_obj(op, language, debug=True) 

1139 

1140 if class_obj: 

1141 try: 

1142 return class_obj.shorthand 

1143 except: 

1144 print( 

1145 f"Operation has no shorthand: {op} for language {language} ... Returning None" 

1146 ) 

1147 

1148 return None 

1149 

1150 

1151def get_inputs(op: str, language: str) -> str: 

1152 class_obj = get_class_obj(op, language, debug=True) 

1153 

1154 if class_obj: 

1155 try: 

1156 return class_obj.inputs 

1157 except: 

1158 print( 

1159 f"Operation has no inputs: {op} for language {language} ... Returning None" 

1160 ) 

1161 

1162 return None 

1163 

1164 

1165def get_outputs(op: str, language: str, debug=True) -> str: 

1166 class_obj = get_class_obj(op, language) 

1167 

1168 if class_obj: 

1169 try: 

1170 return class_obj.outputs 

1171 except: 

1172 print( 

1173 f"Operation has no outputs: {op} for language {language} ... Returning None" 

1174 ) 

1175 

1176 return None 

1177 

1178 

1179def is_primitive(op: str, language: str): 

1180 return get_class_obj(op, language) is not None 

1181 

1182 

1183# Create table ob primitive op classes 

1184primitive_ops = inspect.getmembers( 

1185 sys.modules[__name__], predicate=inspect.isclass 

1186) 

1187 

1188# Create map between langauge names and python class objects 

1189python_primitive_dict = {} 

1190gcc_primitive_dict = {} 

1191cast_primitive_dict = {} 

1192for class_name, class_obj in primitive_ops: 

1193 if hasattr(class_obj, "source_language_name"): 

1194 if "Python" in class_obj.source_language_name: 

1195 python_primitive_dict[ 

1196 class_obj.source_language_name["Python"] 

1197 ] = class_obj 

1198 if "GCC" in class_obj.source_language_name: 

1199 gcc_primitive_dict[ 

1200 class_obj.source_language_name["GCC"] 

1201 ] = class_obj 

1202 if "CAST" in class_obj.source_language_name: 

1203 cast_primitive_dict[ 

1204 class_obj.source_language_name["CAST"] 

1205 ] = class_obj 

1206 

1207primitive_map = { 

1208 "Python": python_primitive_dict, 

1209 "GCC": gcc_primitive_dict, 

1210 "CAST": cast_primitive_dict, 

1211}