blob: 4cafb88e2d96ea5ebcd875fb4b513fe187d6b8ae [file] [log] [blame]
Damien92c06562013-10-22 22:32:27 +01001#include "misc.h"
Damien George136f6752014-01-07 14:54:15 +00002#include "mpconfig.h"
Damien92c06562013-10-22 22:32:27 +01003#include "repl.h"
4
Damien George136f6752014-01-07 14:54:15 +00005#if MICROPY_ENABLE_REPL_HELPERS
6
Damien92c06562013-10-22 22:32:27 +01007bool str_startswith_word(const char *str, const char *head) {
8 int i;
9 for (i = 0; str[i] && head[i]; i++) {
10 if (str[i] != head[i]) {
11 return false;
12 }
13 }
Damien George8cc96a32013-12-30 18:23:50 +000014 return head[i] == '\0' && (str[i] == '\0' || !unichar_isalpha(str[i]));
Damien92c06562013-10-22 22:32:27 +010015}
16
Damien George97790452014-04-08 11:04:29 +000017bool mp_repl_continue_with_input(const char *input) {
18 // check for blank input
19 if (input[0] == '\0') {
20 return false;
Damien92c06562013-10-22 22:32:27 +010021 }
22
Damien George97790452014-04-08 11:04:29 +000023 // check if input starts with a certain keyword
24 bool starts_with_compound_keyword =
25 input[0] == '@'
26 || str_startswith_word(input, "if")
27 || str_startswith_word(input, "while")
28 || str_startswith_word(input, "for")
29 || str_startswith_word(input, "try")
30 || str_startswith_word(input, "with")
31 || str_startswith_word(input, "def")
32 || str_startswith_word(input, "class")
33 ;
34
35 // check for unmatched open bracket or triple quote
36 // TODO don't look at triple quotes inside single quotes
Damien92c06562013-10-22 22:32:27 +010037 int n_paren = 0;
38 int n_brack = 0;
39 int n_brace = 0;
Damien Georgea28507a2014-04-07 13:01:30 +010040 int in_triple_quote = 0;
Damien George97790452014-04-08 11:04:29 +000041 const char *i;
42 for (i = input; *i; i++) {
43 switch (*i) {
Damien92c06562013-10-22 22:32:27 +010044 case '(': n_paren += 1; break;
45 case ')': n_paren -= 1; break;
46 case '[': n_brack += 1; break;
47 case ']': n_brack -= 1; break;
48 case '{': n_brace += 1; break;
49 case '}': n_brace -= 1; break;
Damien George97790452014-04-08 11:04:29 +000050 case '\'':
51 if (in_triple_quote != '"' && i[1] == '\'' && i[2] == '\'') {
52 i += 2;
53 in_triple_quote = '\'' - in_triple_quote;
54 }
55 break;
Damien Georgea28507a2014-04-07 13:01:30 +010056 case '"':
Damien George97790452014-04-08 11:04:29 +000057 if (in_triple_quote != '\'' && i[1] == '"' && i[2] == '"') {
58 i += 2;
59 in_triple_quote = '"' - in_triple_quote;
Damien Georgea28507a2014-04-07 13:01:30 +010060 }
61 break;
Damien92c06562013-10-22 22:32:27 +010062 }
63 }
Damien George97790452014-04-08 11:04:29 +000064
65 // continue if unmatched brackets or quotes
66 if (n_paren > 0 || n_brack > 0 || n_brace > 0 || in_triple_quote != 0) {
67 return true;
68 }
69
70 // continue if compound keyword and last line was not empty
71 if (starts_with_compound_keyword && i[-1] != '\n') {
72 return true;
73 }
74
75 // otherwise, don't continue
76 return false;
Damien92c06562013-10-22 22:32:27 +010077}
Damien George136f6752014-01-07 14:54:15 +000078
79#endif // MICROPY_ENABLE_REPL_HELPERS