main.dart 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import 'dart:io';
  2. import 'package:flutter/material.dart';
  3. import 'package:pocketpy/pocketpy.dart' as pkpy;
  4. void main() {
  5. runApp(const MaterialApp(home: MyApp()));
  6. }
  7. class MyApp extends StatefulWidget {
  8. const MyApp({super.key});
  9. @override
  10. State<MyApp> createState() => _MyAppState();
  11. }
  12. class _MyAppState extends State<MyApp> {
  13. late final pkpy.VM vm;
  14. late final pkpy.REPL repl;
  15. bool needMoreLines = false;
  16. final TextEditingController _controller = TextEditingController();
  17. final StringBuffer buffer = StringBuffer();
  18. @override
  19. void initState() {
  20. super.initState();
  21. // create a pocketpy virtual machine
  22. vm = pkpy.VM();
  23. // create a REPL
  24. repl = pkpy.REPL(vm);
  25. // create a binding
  26. vm.bind<int>("builtins", "add", (int x, int y) => x + y);
  27. vm.bind<String>("builtins", "test", (String x) => x.split(',').join('|'));
  28. WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
  29. refresh();
  30. });
  31. }
  32. void addMessage(String text) {
  33. setState(() {
  34. buffer.write(text);
  35. });
  36. }
  37. void submitCode() {
  38. var text = _controller.text;
  39. _controller.clear();
  40. setState(() {
  41. buffer.write(needMoreLines ? '... $text' : '>>> $text\n');
  42. });
  43. if (text == "exit()") exit(0);
  44. needMoreLines = repl.input(text) == 0;
  45. refresh();
  46. }
  47. void refresh() {
  48. // ignore: no_leading_underscores_for_local_identifiers
  49. var _o = vm.read_output();
  50. if (_o.stdout.isNotEmpty) buffer.write(_o.stdout);
  51. if (_o.stderr.isNotEmpty) buffer.write(_o.stderr);
  52. setState(() {});
  53. }
  54. @override
  55. Widget build(BuildContext context) {
  56. var style = const TextStyle(fontSize: 16);
  57. return Scaffold(
  58. appBar: AppBar(
  59. title: const Text('Demo'),
  60. ),
  61. body: Padding(
  62. padding: const EdgeInsets.all(8.0),
  63. child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
  64. Expanded(
  65. child: SingleChildScrollView(
  66. reverse: true,
  67. child: Text(
  68. buffer.toString(),
  69. style: style,
  70. textAlign: TextAlign.left,
  71. ),
  72. ),
  73. ),
  74. const SizedBox(
  75. height: 16,
  76. ),
  77. SizedBox(
  78. height: 50,
  79. child: TextFormField(
  80. controller: _controller,
  81. style: style,
  82. maxLines: 1,
  83. decoration: const InputDecoration(
  84. border: OutlineInputBorder(),
  85. hintText: 'Enter Python code',
  86. ),
  87. ),
  88. ),
  89. Container(
  90. height: 60,
  91. alignment: Alignment.centerRight,
  92. child: MaterialButton(
  93. onPressed: submitCode,
  94. color: Colors.blue,
  95. textColor: Colors.white,
  96. child: const Text('Run')),
  97. ),
  98. ]),
  99. ),
  100. );
  101. }
  102. }