Start work on preprocessor
diff --git a/as/pp.c b/as/pp.c
new file mode 100644
index 0000000..03936a7
--- /dev/null
+++ b/as/pp.c
@@ -0,0 +1,77 @@
+#include "as.h"
+#include "map.h"
+
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+enum /* State */
+{
+ NORMAL, /* Default State */
+ MACRO_DEF /* In Macro Definition */
+};
+
+enum /* Flags */
+{
+ PRESERVE_MACRO_ARGS,
+};
+
+int preproc(char *in, FILE *out, map_t *macros, int flags)
+{
+ int line_no = 1,
+ err = 0,
+ state = NORMAL;
+ char *line = strtok_fix(in, "\n"),
+ *macro_name = NULL;
+
+ while (line)
+ {
+ skip_ws(&line);
+
+ if (*line == '%')
+ {
+ // Line is preprocessor directive
+
+ char *directive = parse_label_name(&line);
+ if (!directive)
+ {
+ fprintf(stderr, ERR "Expected preprocessor directive on line %d\n" RESET,
+ line_no);
+ err = EINVAL;
+ goto cleanup;
+ }
+ else
+ {
+ if (!strcasecmp(directive, "macro"))
+ {
+ skip_ws(&line);
+ macro_name = parse_label_name(&line);
+ if (!macro_name)
+ {
+ fprintf(stderr, ERR "Expected name after %%macro on line %d\n" RESET,
+ line_no);
+ err = EINVAL;
+ goto cleanup;
+ }
+
+ if (!ws_end(&line))
+ {
+ fprintf(stderr, ERR "Expected new line after macro definition\n" RESET);
+ err = EINVAL;
+ goto cleanup;
+ }
+
+ state = MACRO_DEF;
+ }
+ }
+ }
+
+ fprintf(out, "%s\n", line);
+
+ line = strtok_fix(NULL, "\n");
+ line_no++;
+ }
+
+cleanup:
+ return err;
+}