common.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. from lark import Transformer
  2. def indent(multiline_string, how_much):
  3. lines = multiline_string.split('\n')
  4. return '\n'.join([' '*how_much+l for l in lines])
  5. def display_value(val: any, type_name: str, indentation=0, newline_character='\n'):
  6. if type_name == "ActionCode":
  7. if '\n' in val:
  8. orig = '```\n'+indent(val, indentation+4)+'\n'+' '*indentation+'```'
  9. escaped = orig.replace('\n', newline_character)
  10. return escaped
  11. else:
  12. return '`'+val+'`'
  13. elif type_name == "String":
  14. return '"'+val+'"'.replace('\n', newline_character)
  15. elif type_name == "Integer" or type_name == "Boolean":
  16. return str(val)
  17. elif type_name == "Bytes":
  18. return val
  19. else:
  20. raise Exception("don't know how to display value" + type_name)
  21. def display_name(raw_name: str) -> str:
  22. if raw_name[0:2] == "__":
  23. return "" # hide names that start with '__', they are anonymous (by convention)
  24. else:
  25. return raw_name
  26. # internal use only
  27. # just a dumb wrapper to distinguish between code and string
  28. class _Code:
  29. def __init__(self, code):
  30. self.code = code
  31. class TBase(Transformer):
  32. def IDENTIFIER(self, token):
  33. return str(token)
  34. def INT(self, token):
  35. return int(token)
  36. def BOOL(self, token):
  37. return token == "True"
  38. def STR(self, token):
  39. return str(token[1:-1]) # strip the "" or ''
  40. def CODE(self, token):
  41. return _Code(str(token[1:-1])) # strip the ``
  42. def BYTES(self, token):
  43. return (bytes(token[2:-1], "utf-8"), token.line) # Strip b"" or b''
  44. def INDENTED_CODE(self, token):
  45. skip = 4 # strip the ``` and the following newline character
  46. space_count = 0
  47. while token[skip+space_count] == " ":
  48. space_count += 1
  49. lines = token.split('\n')[1:-1]
  50. for line in lines:
  51. if len(line) >= space_count and line[0:space_count] != ' '*space_count:
  52. raise Exception("wrong indentation of INDENTED_CODE")
  53. unindented_lines = [l[space_count:] for l in lines]
  54. return _Code('\n'.join(unindented_lines))
  55. def literal(self, el):
  56. return el[0]