aboutsummaryrefslogtreecommitdiff
path: root/src/parse.c
diff options
context:
space:
mode:
authorkoekeishiya <aasvi93@hotmail.com>2017-10-07 23:31:15 +0200
committerkoekeishiya <aasvi93@hotmail.com>2017-10-07 23:31:15 +0200
commit94c26f456f095ec8334d9c313943c2747d27c0c2 (patch)
tree248a10b142f0a59192c931da57643b90ad3b9d4a /src/parse.c
parent679ae51b23bd936485e1c5c1e868e4dec4995e97 (diff)
downloadskhd-94c26f456f095ec8334d9c313943c2747d27c0c2.tar.gz
skhd-94c26f456f095ec8334d9c313943c2747d27c0c2.zip
#15 modal support
Diffstat (limited to 'src/parse.c')
-rw-r--r--src/parse.c147
1 files changed, 126 insertions, 21 deletions
diff --git a/src/parse.c b/src/parse.c
index 6a12963..bf5a48d 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -137,34 +137,75 @@ parse_modifier(struct parser *parser)
if (parser_match(parser, Token_Modifier)) {
flags |= parse_modifier(parser);
} else {
- parser_report_error(parser, "expected modifier");
+ parser_report_error(parser, Error_Unexpected_Token, "expected modifier");
}
}
return flags;
}
+internal void
+parse_mode(struct parser *parser, struct hotkey *hotkey)
+{
+ struct token identifier = parser_previous(parser);
+
+ char *name = copy_string_count(identifier.text, identifier.length);
+ struct mode *mode = table_find(parser->mode_map, name);
+ free(name);
+
+ if (!mode) {
+ parser_report_error(parser, Error_Undeclared_Ident, "undeclared identifier");
+ return;
+ }
+
+ hotkey->mode_list[hotkey->mode_count++] = mode;
+ printf("\tmode: '%s'\n", mode->name);
+
+ if (parser_match(parser, Token_Comma)) {
+ if (parser_match(parser, Token_Identifier)) {
+ parse_mode(parser, hotkey);
+ } else {
+ parser_report_error(parser, Error_Unexpected_Token, "expected identifier");
+ return;
+ }
+ }
+}
+
internal struct hotkey *
parse_hotkey(struct parser *parser)
{
struct hotkey *hotkey = malloc(sizeof(struct hotkey));
- int found_modifier;
+ memset(hotkey, 0, sizeof(struct hotkey));
+ bool found_modifier;
printf("(#%d) hotkey :: {\n", parser->current_token.line);
- if (parser_match(parser, Token_Modifier)) {
- hotkey->flags = parse_modifier(parser);
+ if (parser_match(parser, Token_Identifier)) {
+ parse_mode(parser, hotkey);
if (parser->error) {
return NULL;
}
- found_modifier = 1;
+ }
+
+ if (hotkey->mode_count > 0) {
+ if (!parser_match(parser, Token_Insert)) {
+ parser_report_error(parser, Error_Unexpected_Token, "expected '<'");
+ return NULL;
+ }
} else {
- hotkey->flags = found_modifier = 0;
+ hotkey->mode_list[hotkey->mode_count++] = table_find(parser->mode_map, "default");
+ }
+
+ if ((found_modifier = parser_match(parser, Token_Modifier))) {
+ hotkey->flags = parse_modifier(parser);
+ if (parser->error) {
+ return NULL;
+ }
}
if (found_modifier) {
if (!parser_match(parser, Token_Dash)) {
- parser_report_error(parser, "expected '-'");
+ parser_report_error(parser, Error_Unexpected_Token, "expected '-'");
return NULL;
}
}
@@ -176,7 +217,7 @@ parse_hotkey(struct parser *parser)
} else if (parser_match(parser, Token_Literal)) {
parse_key_literal(parser, hotkey);
} else {
- parser_report_error(parser, "expected key-literal");
+ parser_report_error(parser, Error_Unexpected_Token, "expected key-literal");
return NULL;
}
@@ -186,8 +227,15 @@ parse_hotkey(struct parser *parser)
if (parser_match(parser, Token_Command)) {
hotkey->command = parse_command(parser);
+ } else if (parser_match(parser, Token_Activate)) {
+ hotkey->flags |= Hotkey_Flag_Activate;
+ hotkey->command = parse_command(parser);
+ if (!table_find(parser->mode_map, hotkey->command)) {
+ parser_report_error(parser, Error_Undeclared_Ident, "undeclared identifier");
+ return NULL;
+ }
} else {
- parser_report_error(parser, "expected ':' followed by command");
+ parser_report_error(parser, Error_Unexpected_Token, "expected ':' followed by command or ';' followed by mode");
return NULL;
}
@@ -196,22 +244,69 @@ parse_hotkey(struct parser *parser)
return hotkey;
}
-void parse_config(struct parser *parser, struct table *hotkey_map)
+internal struct mode *
+parse_mode_decl(struct parser *parser)
+{
+ /* :: focus : chunkc border::color 0xff202020 */
+ struct mode *mode = malloc(sizeof(struct mode));
+
+ struct token identifier = parser_previous(parser);
+ mode->line = identifier.line;
+ mode->cursor = identifier.cursor;
+ mode->name = copy_string_count(identifier.text, identifier.length);
+
+ table_init(&mode->hotkey_map,
+ 131,
+ (table_hash_func) hash_hotkey,
+ (table_compare_func) same_hotkey);
+
+ if (parser_match(parser, Token_Command)) {
+ mode->command = copy_string_count(parser->previous_token.text, parser->previous_token.length);
+ } else {
+ mode->command = NULL;
+ }
+
+ return mode;
+}
+
+void parse_config(struct parser *parser)
{
+ struct mode *mode;
struct hotkey *hotkey;
+
while (!parser_eof(parser)) {
- if ((parser_check(parser, Token_Modifier)) ||
- (parser_check(parser, Token_Literal)) ||
- (parser_check(parser, Token_Key_Hex)) ||
- (parser_check(parser, Token_Key))) {
+ if (parser_match(parser, Token_Decl)) {
+ if (parser_match(parser, Token_Identifier)) {
+ mode = parse_mode_decl(parser);
+ if (table_find(parser->mode_map, mode->name)) {
+ parser_report_error(parser, Error_Duplicate_Ident,
+ "(#%d:%d) duplicate declaration '%s'\n",
+ mode->line, mode->cursor, mode->name);
+ return;
+ } else {
+ table_add(parser->mode_map, mode->name, mode);
+ }
+ } else {
+ parser_report_error(parser, Error_Unexpected_Token, "expected identifier");
+ return;
+ }
+ } else if ((parser_check(parser, Token_Identifier)) ||
+ (parser_check(parser, Token_Modifier)) ||
+ (parser_check(parser, Token_Literal)) ||
+ (parser_check(parser, Token_Key_Hex)) ||
+ (parser_check(parser, Token_Key))) {
hotkey = parse_hotkey(parser);
if (parser->error) {
- free_hotkeys(hotkey_map);
+ free_mode_map(parser->mode_map);
return;
}
- table_add(hotkey_map, hotkey, hotkey);
+
+ for (int i = 0; i < hotkey->mode_count; ++i) {
+ mode = hotkey->mode_list[i];
+ table_add(&mode->hotkey_map, hotkey, hotkey);
+ }
} else {
- parser_report_error(parser, "expected modifier or key-literal");
+ parser_report_error(parser, Error_Unexpected_Token, "expected decl, modifier or key-literal");
return;
}
}
@@ -261,13 +356,23 @@ bool parser_match(struct parser *parser, enum token_type type)
return false;
}
-void parser_report_error(struct parser *parser, const char *format, ...)
+void parser_report_error(struct parser *parser, enum parse_error_type error_type, const char *format, ...)
{
va_list args;
va_start(args, format);
- fprintf(stderr, "(#%d:%d) ", parser->current_token.line, parser->current_token.cursor);
- vfprintf(stderr, format, args);
- fprintf(stderr, ", but got '%.*s'\n", parser->current_token.length, parser->current_token.text);
+
+ if (error_type == Error_Unexpected_Token) {
+ fprintf(stderr, "(#%d:%d) ", parser->current_token.line, parser->current_token.cursor);
+ vfprintf(stderr, format, args);
+ fprintf(stderr, ", but got '%.*s'\n", parser->current_token.length, parser->current_token.text);
+ } else if (error_type == Error_Undeclared_Ident) {
+ fprintf(stderr, "(#%d:%d) ", parser->previous_token.line, parser->previous_token.cursor);
+ vfprintf(stderr, format, args);
+ fprintf(stderr, " '%.*s'\n", parser->previous_token.length, parser->previous_token.text);
+ } else if (error_type == Error_Duplicate_Ident) {
+ vfprintf(stderr, format, args);
+ }
+
va_end(args);
parser->error = true;
}