none-None1

ThreadFuck (language) interpreter

Jan 17th, 2024 (edited)
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.55 KB | Source Code | 0 0
  1. """
  2. ThreadFuck interpreter
  3.  
  4. ThreadFuck - A multithreaded derivative of Brainfuck
  5.  
  6. ThreadFuck commands:
  7. >   Move the active pointer to the right
  8. <   Move the pointer to the left
  9. +   Increment the memory cell at the active pointer
  10. -   Decrement the memory cell at the active pointer
  11. .   Output the character signified by the cell at the active pointer
  12. ,   Input a character and store it in the cell at the active pointer
  13. [   Jump past the matching ] if the cell at the active pointer is 0
  14. ]   Jump back to the matching [ if the cell at the active pointer is nonzero
  15. ~   Switch active pointer
  16. !   Create a thread that executes the subprogram selected by the program selector of this thread
  17. ^   If the program selector is selecting the first subprogram, select the last subprogram, otherwise select the subprogram at the next line
  18. v   If the program selector is selecting the last subprogram, select the first subprogram, otherwise select the subprogram at the previous line
  19. *   Wait until all the other threads terminate
  20.  
  21. You can change the code to execute by changeing the co_de variable, examples are given as the
  22. example_*** variables, you can run examples or you own programs. You can also change the DEBUG
  23. variable to 0 to disable debug information, and 1 to enable.
  24.  
  25. More information see Esolang Wiki: https://esolangs.org/wiki/ThreadFuck
  26. """
  27. import sys
  28. builtin_enumerate=enumerate
  29. from threading import *
  30. public_p=0
  31. public_tape=[0]*1000000
  32. example_forkbomb='!!' # Fork bomb
  33. example_simutaneous='''v!!
  34. ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.''' # Undefined output (Two threads output simutaneously)
  35. example_threadunsafe='''v!!
  36. ~++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.''' # Undefined output (Thread unsafe)
  37. example_deadlock='''v!!
  38. *''' # Deadlock
  39. example_lock='''v!*++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
  40. ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.''' # Lock (Prints "Hello World!<LF>Hello World!<LF>")
  41. example_lock2='''~+v!v!
  42. +[>~[]~++++++++[>++++++++<-]>+.+.+.[-]<<~>-<+~]
  43. +[>~>[]<~++++++++[>++++++++<-]>++++.+.+.[-]<<~>+<-~]''' # Another example of lock (prints "DEFABCDEFABC...")
  44. co_de=example_lock
  45. if not co_de:
  46.     raise Exception('Empty program not allowed')
  47. pcl=co_de.split('\n')
  48. pc=0
  49. DEBUG=1
  50. def tf(code,pc,pcl):
  51.     def inner_tf():
  52.         nonlocal pc,pcl
  53.         s=[]
  54.         matches={}
  55.         ptape=[0]*1000000
  56.         for i,j in builtin_enumerate(code):
  57.             if j=='[':
  58.                 s.append(i)
  59.             if j==']':
  60.                 m=s.pop()
  61.                 matches[m]=i
  62.                 matches[i]=m
  63.         cp=0
  64.         pp=0
  65.         priv=True
  66.         tape=ptape
  67.         p=pp
  68.         while cp<len(code):
  69.             if code[cp]=='+':
  70.                 tape[p]=(tape[p]+1)%256
  71.             if code[cp]=='-':
  72.                 tape[p]=(tape[p]-1)%256
  73.             if code[cp]==',':
  74.                 c=sys.stdin.read(1)
  75.                 tape[p]=(ord(c) if c else 0)%256
  76.             if code[cp]=='.':
  77.                 print(chr(tape[p]),end='')
  78.                 sys.stdout.flush()
  79.             if code[cp]=='<':
  80.                 p-=1
  81.             if code[cp]=='>':
  82.                 p+=1
  83.             if code[cp]=='[':
  84.                 if not tape[p]:
  85.                     cp=matches[cp]
  86.             if code[cp]==']':
  87.                 if tape[p]:
  88.                     cp=matches[cp]
  89.             if code[cp]=='^':
  90.                 pc=(pc-1)%len(pcl)
  91.             if code[cp]=='v':
  92.                 pc=(pc+1)%len(pcl)
  93.             if code[cp]=='~':
  94.                 if priv:
  95.                     pp=p
  96.                     p=public_p
  97.                     tape=public_tape
  98.                 else:
  99.                     p=pp
  100.                     tape=ptape
  101.                 priv=(not priv)
  102.             if code[cp]=='*':
  103.                 while active_count()>2: # The main thread and current thread
  104.                     pass
  105.             if code[cp]=='!':
  106.                 t=Thread(target=tf(pcl[pc],pc,pcl))
  107.                 if DEBUG:
  108.                     sys.stderr.write(t.name+' starts\n')
  109.                 t.start()
  110.             cp+=1
  111.         if DEBUG:
  112.             sys.stderr.write(current_thread().name+' stops\n')
  113.     return inner_tf
  114. def interpret_threadfuck():
  115.     t=Thread(target=tf(pcl[pc],pc,pcl),name="Main Thread")
  116.     if DEBUG:
  117.         sys.stderr.write(t.name+' starts\n')
  118.     t.start()
  119. interpret_threadfuck()
  120.  
Advertisement
Add Comment
Please, Sign In to add comment