123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- /*
- * parser.c -- part of ZilUtils/ZilAsm
- *
- * Copyright (C) 2016 Jason Self <j@jxself.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
- #include <stdio.h> /* fopen, fgets */
- #include <string.h> /* strlen */
- #include "parser.h"
- #include "directives.h"
- #include "opcodes.h"
- #include "labels.h"
- #define iscomment(c) ((c) == '#')
- #define isbindigit(c) ((c) == '0' || (c) == '1')
- /* !!! TODO !!! */
- #define fatal_error(errmsg)
- #define PC NULL
- void checksep(const char *p)
- {
- if (!*p || iscomment(*p) || isspace(*p)) return;
- fatal_error("wrong chars");
- }
- const char *pass_spaces(const char *p)
- {
- while(p && isspace(*p)) p++;
- return (p && *p) ? p : NULL;
- }
- const char *pass_alnums(const char *p)
- {
- while(p && isalnum(*p)) p++;
- return (p && *p) ? p : NULL;
- }
- int tryparse_directive(const char *p)
- {
- if (*p != '.')
- return 0;
- const char *a = p+1;
- const char *b = pass_alnums(a);
- checksep(b);
- Directive_handler f = directive_lookup(a, b - a);
- if (!f) return 0;
- return (*f)(b);
- }
- int tryparse_assignment(const char *a, const char *b, const char *c)
- {
- return 0;
- }
- int tryparse_label(const char *a, const char *b, const char *c)
- {
- if (*(c+1) != ':') {
- symtable_add2(Local_labels, a, b - a, PC);
- } else if (*(c+2) != ':') {
- symtable_add2(Global_labels, a, b - a, PC);
- } else {
- fatal_error("wrong label type");
- }
- while (*c++ == ':');
- if (*c && ((c = pass_spaces(c)) != NULL) && *c)
- return tryparse_instruction(c);
- return 1;
- }
- int tryparse_name(const char *a)
- {
- const char *b = pass_alnums(a);
- const char *c = pass_spaces(b);
- if (!c) return 0;
- if (*c == '=') return tryparse_assignment(a, b, c + 1);
- if (*c == ':') return tryparse_label(a, b, c);
- return 0;
- }
- int tryparse_instruction(const char *a)
- {
- const char *b = pass_alnums(a);
- ZOpcode *op = symtable_lookup2(Opcodes, a, b - a);
- if (!op) return 0;
- ZOpcode_flags flags = op->flags;
- /* !!! TODO !!! */
- return 0;
- }
- /*
- * Line can be one from: Comment, Global label, Local label, Directive, Name=Value, Instruction
- */
- int parse_line(const char *p)
- {
- for (; *p; p++) {
- char c = *p;
- int n;
- if (isspace(c)) continue;
- if (iscomment(c)) return 0;
- if (n = tryparse_directive(p)) return n;
- if (n = tryparse_name(p)) return n; // ..label or assignment
- if (n = tryparse_instruction(p)) return n;
- fatal_error("wrong line");
- }
- return 0;
- }
- int parse_file(const char *filename)
- {
- FILE *fp = fopen(filename, "r");
- if (!fp) fatal_error("wrong file");
- const int MAX_LINESIZE = 1024;
- char line[MAX_LINESIZE];
- int newline_missing = 0;
- while (fgets(line, MAX_LINESIZE, fp)) {
- if (newline_missing) fatal_error("line too long");
- int n = strlen(line);
- if (!n) continue;
- parse_line(line);
- newline_missing = (line[n-1] != '\n');
- }
- close(fp);
- }
- /*
- line_passed() {
- skip_spaces();
- return (current_token == LINE_END || current_token == LINE_COMMENT);
- }
- if (line_passed()) continue;
- if (current_token == DIRECTIVE) {
- if (!try_next_token(NAME))
- fatal_error("directive contains incorrect chars")
- handler = get_directive_handler(current_token);
- if (!handler)
- fatal error("unknown directive");
- (*handler)(remaining_line);
- if (line_passed()) continue;
- fatal_error("unexpected line tail");
- } else if (current_token == NAME) {
- skip_spaces();
- if (current_token == ASSIGNMENT)
- }
-
- */
|