Add multithreading
This commit is contained in:
parent
b49d0f1868
commit
144a33a603
5
Makefile
5
Makefile
|
@ -1,7 +1,8 @@
|
||||||
FILES = *.c */*.c
|
FILES = *.c */*.c
|
||||||
INCLUDES = -I. -I./parser/ -I./compiler -I./vm -I./tokenizer
|
LIBRARIES = -lpthread
|
||||||
|
INCLUDES = -I. -I./parser/ -I./compiler/ -I./vm/ -I./tokenizer/
|
||||||
CFLAGS = -std=c99 -g
|
CFLAGS = -std=c99 -g
|
||||||
OUTFILE = jack-compiler
|
OUTFILE = jack-compiler
|
||||||
|
|
||||||
main: ${FILES}
|
main: ${FILES}
|
||||||
${CC} ${CFLAGS} ${INCLUDES} -o ${OUTFILE} ${FILES}
|
${CC} ${CFLAGS} ${LIBRARIES} ${INCLUDES} -o ${OUTFILE} ${FILES}
|
||||||
|
|
|
@ -391,16 +391,6 @@ LINEBLOCK* compileclass(COMPILER* c, CLASS* class) {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
void compile(COMPILER* c) {
|
|
||||||
LINEBLOCK* output = NULL;
|
|
||||||
CLASS* curr = c->classes;
|
|
||||||
while(curr != NULL) {
|
|
||||||
output = mergelnblks(output, compileclass(c, curr));
|
|
||||||
curr = curr->next;
|
|
||||||
}
|
|
||||||
c->output = output;
|
|
||||||
}
|
|
||||||
|
|
||||||
COMPILER* mkcompiler(CLASS* classes) {
|
COMPILER* mkcompiler(CLASS* classes) {
|
||||||
COMPILER* c = (COMPILER*)malloc(sizeof(COMPILER));
|
COMPILER* c = (COMPILER*)malloc(sizeof(COMPILER));
|
||||||
c->globalscope = mkscope(NULL);
|
c->globalscope = mkscope(NULL);
|
||||||
|
|
|
@ -7,10 +7,8 @@
|
||||||
typedef struct {
|
typedef struct {
|
||||||
CLASS* classes;
|
CLASS* classes;
|
||||||
SCOPE* globalscope;
|
SCOPE* globalscope;
|
||||||
LINEBLOCK* output;
|
|
||||||
} COMPILER;
|
} COMPILER;
|
||||||
|
|
||||||
COMPILER* mkcompiler(CLASS* classes);
|
COMPILER* mkcompiler(CLASS* classes);
|
||||||
void compile(COMPILER* c);
|
LINEBLOCK* compileclass(COMPILER* c, CLASS* class);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,177 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "util.h"
|
||||||
|
#include "io.h"
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <linux/limits.h>
|
||||||
|
#else
|
||||||
|
#define PATH_MAX 512
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char* strtail(char* str, int len, int count) {
|
||||||
|
int index = len - count;
|
||||||
|
if (index <= 0) return str;
|
||||||
|
return str + (sizeof(char) * (index));
|
||||||
|
}
|
||||||
|
|
||||||
|
char* strhead(char* str, int count) {
|
||||||
|
return str + (sizeof(char) * count);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* trimstr(char* str, int len, int end) {
|
||||||
|
int count = len - end;
|
||||||
|
char oldchar = str[count];
|
||||||
|
str[count] = '\0';
|
||||||
|
char* newstr = (char*)malloc(sizeof(char) * (1 + count));
|
||||||
|
strcpy(newstr, str);
|
||||||
|
str[count] = oldchar;
|
||||||
|
return newstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* getname(char* f, int len) {
|
||||||
|
int startind = 0;
|
||||||
|
int endind = len - 1;
|
||||||
|
bool readsmt = false;
|
||||||
|
|
||||||
|
for(int i = endind; i >= 0; i--) {
|
||||||
|
if(f[i] == '/') {
|
||||||
|
if(!readsmt) {
|
||||||
|
endind = i-1;
|
||||||
|
f[i] = '\0';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
startind = i+1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(f[i] == '.')
|
||||||
|
endind = i-1;
|
||||||
|
readsmt = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sz = sizeof(char)*(endind - startind + 2);
|
||||||
|
char* startstr = strhead(f, startind);
|
||||||
|
char* retstr = (char*)malloc(sz);
|
||||||
|
snprintf(retstr, sz, "%s", startstr);
|
||||||
|
return retstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* getfullname(char* fname, char* dirname, int dirlen) {
|
||||||
|
int fnamelen = strlen(fname);
|
||||||
|
int sz = sizeof(char)*(fnamelen+dirlen+2);
|
||||||
|
char* fullname = (char*)malloc(sz);
|
||||||
|
sprintf(fullname, "%s/%s", dirname, fname);
|
||||||
|
return fullname;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isdotjack(char* f, int len) {
|
||||||
|
const char* ext = ".jack";
|
||||||
|
return strcmp(strtail(f, len, strlen(ext)), ext) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isdir(char* f, int len) {
|
||||||
|
bool readsmt = false;
|
||||||
|
for(int i = len-1; i >= 0; i--) {
|
||||||
|
if(f[i] == '.')
|
||||||
|
if(readsmt)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
if(f[i] == '/')
|
||||||
|
return 1;
|
||||||
|
readsmt = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* getoutname(char* fullname, int len) {
|
||||||
|
char* trimmed = trimstr(fullname, len, 4);
|
||||||
|
int sz = sizeof(char) * (len-1);
|
||||||
|
char* outname = (char*)malloc(sz);
|
||||||
|
sprintf(outname, "%svm", trimmed);
|
||||||
|
return outname;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILELIST* addfile(FILELIST* l, char* fullname, char* name) {
|
||||||
|
FILELIST* new = (FILELIST*)malloc(sizeof(FILELIST));
|
||||||
|
new->name = name;
|
||||||
|
new->fullname = fullname;
|
||||||
|
new->next = l;
|
||||||
|
new->outname = getoutname(fullname, strlen(fullname));
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILELIST* getfilesfromdir(char* dir) {
|
||||||
|
FILELIST* filelist = NULL;
|
||||||
|
DIR* d = opendir(dir);
|
||||||
|
|
||||||
|
if(d == NULL) {
|
||||||
|
eprintf("Error while opening directory '%s': %s\n", dir, strerror(errno));
|
||||||
|
exit(errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
int len = strlen(dir);
|
||||||
|
struct dirent* thisfile;
|
||||||
|
while(thisfile = readdir(d), thisfile != NULL) {
|
||||||
|
if(isdotjack(thisfile->d_name, strlen(thisfile->d_name))) {
|
||||||
|
char* fullname = getfullname(thisfile->d_name, dir, len);
|
||||||
|
char* name = getname(thisfile->d_name, len);
|
||||||
|
filelist = addfile(filelist, fullname, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(d);
|
||||||
|
|
||||||
|
if(filelist == NULL) {
|
||||||
|
eprintf("Directory '%s' doesn't have any .jack file\n", dir);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return filelist;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILELIST* getsinglefile(char* file) {
|
||||||
|
int len = strlen(file);
|
||||||
|
if(isdotjack(file, len)){
|
||||||
|
char* name = getname(file, len);
|
||||||
|
char* fullname = heapstr(file, len);
|
||||||
|
|
||||||
|
FILE* input = fopen(fullname, "r");
|
||||||
|
if(input == NULL) {
|
||||||
|
eprintf("Error while reading file '%s': %s\n", file, strerror(errno));
|
||||||
|
exit(errno);
|
||||||
|
}
|
||||||
|
fclose(input);
|
||||||
|
|
||||||
|
return addfile(NULL, fullname, name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
eprintf("Input file must be named like 'Xxx.vm'\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FILELIST* getfiles(char* input) {
|
||||||
|
int inplen = strlen(input);
|
||||||
|
bool isitdir = isdir(input, inplen);
|
||||||
|
|
||||||
|
if(isitdir)
|
||||||
|
return getfilesfromdir(input);
|
||||||
|
else
|
||||||
|
return getsinglefile(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freefilelist(FILELIST* fs) {
|
||||||
|
free(fs->name);
|
||||||
|
free(fs->fullname);
|
||||||
|
if(fs->next != NULL)
|
||||||
|
freefilelist(fs->next);
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef IO_H
|
||||||
|
#define IO_H
|
||||||
|
|
||||||
|
typedef struct flist {
|
||||||
|
char* name;
|
||||||
|
char* fullname;
|
||||||
|
char* outname;
|
||||||
|
struct flist* next;
|
||||||
|
} FILELIST;
|
||||||
|
|
||||||
|
|
||||||
|
FILELIST* getfiles(char* input);
|
||||||
|
void freefilelist(FILELIST* fs);
|
||||||
|
#endif
|
121
main.c
121
main.c
|
@ -2,31 +2,126 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
|
#include "io.h"
|
||||||
|
|
||||||
void printcompiler(COMPILER* c) {
|
typedef struct unit {
|
||||||
printlns(c->output->head, stdout);
|
FILELIST* file;
|
||||||
|
TOKEN* tokens;
|
||||||
|
CLASS* parsed;
|
||||||
|
COMPILER* compiler;
|
||||||
|
LINEBLOCK* compiled;
|
||||||
|
struct unit* next;
|
||||||
|
} COMPILEUNIT;
|
||||||
|
|
||||||
|
void* parseunit(void* input) {
|
||||||
|
COMPILEUNIT* unit = (COMPILEUNIT*)input;
|
||||||
|
|
||||||
|
unit->parsed = parse(unit->tokens, unit->file->name);
|
||||||
|
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* compileunit(void* input) {
|
||||||
|
COMPILEUNIT* unit = (COMPILEUNIT*)input;
|
||||||
|
|
||||||
|
unit->compiled = compileclass(unit->compiler, unit->parsed);
|
||||||
|
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void waitthreads(pthread_t* threads, int amount) {
|
||||||
|
void* status;
|
||||||
|
int code;
|
||||||
|
for(int i = 0; i < amount; i++) {
|
||||||
|
code = pthread_join(threads[i], &status);
|
||||||
|
if(code) {
|
||||||
|
eprintf("Error while joining thread %i: %s\n", i, strerror(code));
|
||||||
|
exit(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void actonunits(COMPILEUNIT* units, void*(*fun)(void*)) {
|
||||||
|
pthread_t mythreads[_SC_THREAD_THREADS_MAX];
|
||||||
|
pthread_attr_t attr;
|
||||||
|
pthread_attr_init(&attr);
|
||||||
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
|
||||||
|
|
||||||
|
COMPILEUNIT* curr = units;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
int code;
|
||||||
|
do {
|
||||||
|
i = 0;
|
||||||
|
while(curr != NULL && i < _SC_THREAD_THREADS_MAX) {
|
||||||
|
code = pthread_create(&mythreads[i], NULL, fun, curr);
|
||||||
|
|
||||||
|
if(code) {
|
||||||
|
eprintf("Error while creating thread %i: %s\n", i, strerror(code));
|
||||||
|
exit(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
curr = curr->next;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
waitthreads(mythreads, i);
|
||||||
|
} while(i == _SC_THREAD_THREADS_MAX);
|
||||||
|
|
||||||
|
pthread_attr_destroy(&attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
if(argc < 2) {
|
if(argc < 2) {
|
||||||
fprintf(stderr, "Usage: %s {input file}\n", argv[0]);
|
eprintf("Usage: %s {input file(s)}\n", argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* input = fopen(argv[1], "r");
|
FILELIST* files = getfiles(argv[1]);
|
||||||
|
FILELIST* curr = files->next;
|
||||||
|
|
||||||
if(input == NULL) {
|
COMPILEUNIT* head = (COMPILEUNIT*)malloc(sizeof(COMPILEUNIT));
|
||||||
fprintf(stderr, "%s\n", strerror(errno));
|
|
||||||
return errno;
|
head->file = files;
|
||||||
|
head->tokens = tokenize(files->fullname);
|
||||||
|
|
||||||
|
COMPILEUNIT* currunit = head;
|
||||||
|
while(curr != NULL) {
|
||||||
|
COMPILEUNIT* newunit = (COMPILEUNIT*)malloc(sizeof(COMPILEUNIT));
|
||||||
|
newunit->file = curr;
|
||||||
|
newunit->tokens = tokenize(curr->fullname);
|
||||||
|
currunit->next = newunit;
|
||||||
|
currunit = newunit;
|
||||||
|
curr = curr->next;
|
||||||
|
}
|
||||||
|
currunit->next = NULL;
|
||||||
|
|
||||||
|
actonunits(head, parseunit);
|
||||||
|
|
||||||
|
CLASS* headclass = head->parsed;
|
||||||
|
CLASS* currclass = headclass;
|
||||||
|
currunit = head->next;
|
||||||
|
while(currunit != NULL) {
|
||||||
|
currclass->next = currunit->parsed;
|
||||||
|
currclass = currunit->parsed;
|
||||||
|
currunit = currunit->next;
|
||||||
|
}
|
||||||
|
currclass->next = NULL;
|
||||||
|
COMPILER* compiler = mkcompiler(headclass);
|
||||||
|
|
||||||
|
currunit = head;
|
||||||
|
while(currunit != NULL) {
|
||||||
|
currunit->compiler = compiler;
|
||||||
|
currunit = currunit->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
PARSER* p = mkparser(tokenize(input), argv[1]);
|
actonunits(head, compileunit);
|
||||||
parse(p);
|
|
||||||
COMPILER* c = mkcompiler(p->output);
|
printlns(head->compiled->head, stdout);
|
||||||
compile(c);
|
|
||||||
printcompiler(c);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,19 +43,11 @@ CLASS* parseclass(PARSER* p) {
|
||||||
class->subroutdecs = parsesubroutdecs(p);
|
class->subroutdecs = parsesubroutdecs(p);
|
||||||
|
|
||||||
checkcontent(p, "}");
|
checkcontent(p, "}");
|
||||||
return class;
|
|
||||||
}
|
|
||||||
|
|
||||||
CLASS* parseclasses(PARSER* p) {
|
if(p->current != NULL)
|
||||||
CLASS* head = parseclass(p);
|
unexpected(p);
|
||||||
CLASS* curr = head;
|
|
||||||
while(p->current != NULL && equals(p, "class")) {
|
return class;
|
||||||
curr->next = parseclass(p);
|
|
||||||
curr = curr->next;
|
|
||||||
}
|
|
||||||
if(curr != NULL)
|
|
||||||
curr->next = NULL;
|
|
||||||
return head;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int parsepossibilities(PARSER* p, STRINGARRAY* poss) {
|
int parsepossibilities(PARSER* p, STRINGARRAY* poss) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef PARSER_STRUCTURE_H
|
#ifndef PARSER_STRUCTURE_H
|
||||||
#define PARSER_STRUCTURE_H
|
#define PARSER_STRUCTURE_H
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
CLASS* parseclasses(PARSER* p);
|
CLASS* parseclass(PARSER* p);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,15 +5,10 @@
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "parser-structure.h"
|
#include "parser-structure.h"
|
||||||
|
|
||||||
// Statements
|
CLASS* parse(TOKEN* tokens, char* file) {
|
||||||
PARSER* mkparser(TOKEN* tokens, char* file) {
|
|
||||||
PARSER* parser = (PARSER*)malloc(sizeof(PARSER));
|
PARSER* parser = (PARSER*)malloc(sizeof(PARSER));
|
||||||
parser->tokens = tokens;
|
parser->tokens = tokens;
|
||||||
parser->current = tokens;
|
parser->current = tokens;
|
||||||
parser->file = file;
|
parser->file = file;
|
||||||
return parser;
|
return parseclass(parser);
|
||||||
}
|
|
||||||
|
|
||||||
void parse(PARSER* p) {
|
|
||||||
p->output = parseclasses(p);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,7 @@ typedef struct {
|
||||||
TOKEN* current;
|
TOKEN* current;
|
||||||
TOKEN* checkpoint;
|
TOKEN* checkpoint;
|
||||||
char* file;
|
char* file;
|
||||||
CLASS* output;
|
|
||||||
} PARSER;
|
} PARSER;
|
||||||
|
|
||||||
PARSER* mkparser(TOKEN* tokens, char* file);
|
CLASS* parse(TOKEN* tokens, char* file);
|
||||||
void parse(PARSER* p);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,7 +23,7 @@ void freestr(STRING* str);
|
||||||
|
|
||||||
// Token manipulation;
|
// Token manipulation;
|
||||||
TOKEN* appendtokenraw(TOKEN* curitem, STRING* token, int definedat, TOKENTYPE type);
|
TOKEN* appendtokenraw(TOKEN* curitem, STRING* token, int definedat, TOKENTYPE type);
|
||||||
TOKEN* appendtoken(TOKEN* curitem, STRING* token, int definedat);
|
TOKEN* appendtoken(TOKEN* curitem, STRING* token, char* file, int definedat);
|
||||||
#define mktoken() (TOKEN*)malloc(sizeof(TOKEN))
|
#define mktoken() (TOKEN*)malloc(sizeof(TOKEN))
|
||||||
|
|
||||||
// Char types
|
// Char types
|
||||||
|
@ -33,7 +33,7 @@ bool issymbol(STRING* tk);
|
||||||
bool isint(char* str);
|
bool isint(char* str);
|
||||||
bool isintcons(STRING* tk);
|
bool isintcons(STRING* tk);
|
||||||
bool isidentifier(STRING* tk);
|
bool isidentifier(STRING* tk);
|
||||||
TOKENTYPE gettokentype(STRING* tk, int definedat);
|
TOKENTYPE gettokentype(STRING* tk, char* file, int definedat);
|
||||||
|
|
||||||
// Stream handling
|
// Stream handling
|
||||||
void skipln(FILE* input);
|
void skipln(FILE* input);
|
||||||
|
@ -78,9 +78,9 @@ TOKEN* appendtokenraw(TOKEN* curitem, STRING* token, int definedat, TOKENTYPE ty
|
||||||
return nextitem;
|
return nextitem;
|
||||||
}
|
}
|
||||||
|
|
||||||
TOKEN* appendtoken(TOKEN* curitem, STRING* token, int definedat) {
|
TOKEN* appendtoken(TOKEN* curitem, STRING* token, char* file, int definedat) {
|
||||||
append(token, '\0');
|
append(token, '\0');
|
||||||
return appendtokenraw(curitem, token, definedat, gettokentype(token, definedat));
|
return appendtokenraw(curitem, token, definedat, gettokentype(token, file, definedat));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Char types
|
// Char types
|
||||||
|
@ -128,12 +128,12 @@ bool isidentifier(STRING* tk) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TOKENTYPE gettokentype(STRING* tk, int definedat) {
|
TOKENTYPE gettokentype(STRING* tk, char* file, int definedat) {
|
||||||
if(iskeyword(tk)) return keyword;
|
if(iskeyword(tk)) return keyword;
|
||||||
if(issymbol(tk)) return symbol;
|
if(issymbol(tk)) return symbol;
|
||||||
if(isintcons(tk)) return integer;
|
if(isintcons(tk)) return integer;
|
||||||
if(isidentifier(tk)) return identifier;
|
if(isidentifier(tk)) return identifier;
|
||||||
eprintf("Unexpected token '%s'; line %i\n", tk->str, definedat);
|
eprintf("Unexpected token '%s'; file '%s', line %i\n", tk->str, file, definedat);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ void readstr(FILE* input, STRING* tmp, int definedat) {
|
||||||
append(tmp, '\0');
|
append(tmp, '\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
TOKEN* tokenize(FILE* input) {
|
TOKEN* tokenize(char* file) {
|
||||||
TOKEN* head = mktoken();
|
TOKEN* head = mktoken();
|
||||||
TOKEN* lastitem = head;
|
TOKEN* lastitem = head;
|
||||||
TOKEN* curitem = head;
|
TOKEN* curitem = head;
|
||||||
|
@ -198,6 +198,7 @@ TOKEN* tokenize(FILE* input) {
|
||||||
CHARTYPE curtype;
|
CHARTYPE curtype;
|
||||||
|
|
||||||
int lnscount = 1;
|
int lnscount = 1;
|
||||||
|
FILE* input = fopen(file, "r");
|
||||||
|
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
while(c = fgetc(input), !feof(input)) {
|
while(c = fgetc(input), !feof(input)) {
|
||||||
|
@ -208,7 +209,7 @@ TOKEN* tokenize(FILE* input) {
|
||||||
continue;
|
continue;
|
||||||
else if(c == '"') {
|
else if(c == '"') {
|
||||||
if(lasttype != space)
|
if(lasttype != space)
|
||||||
curitem = appendtoken(curitem, tmptoken, lnscount);
|
curitem = appendtoken(curitem, tmptoken, file, lnscount);
|
||||||
readstr(input, tmptoken, lnscount);
|
readstr(input, tmptoken, lnscount);
|
||||||
lastitem = curitem;
|
lastitem = curitem;
|
||||||
curitem = appendtokenraw(curitem, tmptoken, lnscount, string);
|
curitem = appendtokenraw(curitem, tmptoken, lnscount, string);
|
||||||
|
@ -221,13 +222,13 @@ TOKEN* tokenize(FILE* input) {
|
||||||
if(curtype == common) {
|
if(curtype == common) {
|
||||||
if(lasttype == charsymbol) {
|
if(lasttype == charsymbol) {
|
||||||
lastitem = curitem;
|
lastitem = curitem;
|
||||||
curitem = appendtoken(curitem, tmptoken, lnscount);
|
curitem = appendtoken(curitem, tmptoken, file, lnscount);
|
||||||
}
|
}
|
||||||
append(tmptoken, c);
|
append(tmptoken, c);
|
||||||
} else {
|
} else {
|
||||||
if(lasttype != space){
|
if(lasttype != space){
|
||||||
lastitem = curitem;
|
lastitem = curitem;
|
||||||
curitem = appendtoken(curitem, tmptoken, lnscount);
|
curitem = appendtoken(curitem, tmptoken, file, lnscount);
|
||||||
}
|
}
|
||||||
if(curtype == charsymbol)
|
if(curtype == charsymbol)
|
||||||
append(tmptoken, c);
|
append(tmptoken, c);
|
||||||
|
|
|
@ -16,6 +16,6 @@ typedef struct token {
|
||||||
struct token* next;
|
struct token* next;
|
||||||
} TOKEN;
|
} TOKEN;
|
||||||
|
|
||||||
TOKEN* tokenize(FILE* input);
|
TOKEN* tokenize(char* filename);
|
||||||
void freetokenlist(TOKEN* list);
|
void freetokenlist(TOKEN* list);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue