- Assert `.section` in full test
- Add `.bank.` directive allowing users to set the current bank number (ulas.bank) which can be used for symbol files.
- Allow nested begin and end scope calls
-- Add `forth-like` mode. This mode should allow defining words similar to forth. It should have a built-in word for `assembly output` that can be implemented by the user.
- Add `.extern` directive allowing the user to define external labels
- Add `.scope` for `.def` and `.de.` variables
- Add `#cop n, ...` preprocessor directive. It should work just like .rep but just insert the line n times into the source code and then preprocess the result.
return ULAS_PPDIR_NONE;
}
+// checks if the last printable char in a string is '\'
+// side-effect: also replaced that what with \0 if it is found
+int ulas_last_print_is_escape(char *buf, int n) {
+ int found_escape = 0;
+ // check if last printable char is an escape char
+ unsigned int buf_len = strnlen(buf, n);
+ if (buf_len == 0) {
+ return 0;
+ }
+
+ for (int i = buf_len - 1; i >= 0; i--) {
+ if (isprint(buf[i])) {
+ found_escape = buf[i] == '\\';
+ if (found_escape) {
+ buf[i] = '\0';
+ }
+ break;
+ }
+ }
+
+ return found_escape;
+}
+
+// call fgets and concats into buf until either buf is full (fatal error)
+// or a non-escape character is *not* the last chracter of a line
+// returns number of lines read
+int ulas_fgets(char *buf, int n, FILE *src) {
+ char internal_buf[ULAS_LINEMAX+1];
+ buf[0] = '\0';
+ internal_buf[ULAS_LINEMAX] = '\0';
+
+ int lines_read = 0;
+
+ do {
+ char *res = fgets(internal_buf, ULAS_LINEMAX, src);
+
+ // bail early
+ if (res == NULL) {
+ break;
+ }
+
+ strncat(buf, internal_buf, n);
+
+ lines_read++;
+ } while(ulas_last_print_is_escape(buf, n));
+
+ return lines_read;
+}
+
int ulas_preprocnext(struct ulas_preproc *pp, FILE *dst, FILE *src, char *buf,
int n) {
int rc = 1;
- if (fgets(buf, n, src) != NULL) {
- ulas.line++;
+ int lines_read = 0;
+ if ((lines_read = ulas_fgets(buf, n, src)) != 0) {
+ ulas.line += lines_read;
unsigned long buflen = strlen(buf);
int ulas_asmnext(FILE *dst, FILE *src, char *buf, int n) {
int rc = 1;
- if (fgets(buf, n, src) != NULL) {
+ if (ulas_fgets(buf, n, src) != 0) {
unsigned long buflen = strlen(buf);
if (ulas_asmline(dst, src, buf, buflen) == -1) {
rc = -1;