From 15fb03902ff5550b3a8c44bde3e08df876449f7a Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Thu, 18 Aug 2016 22:05:21 +0200 Subject: Third --- ast.c | 5 +++- ast.h | 10 +++++++ parser.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 113 insertions(+), 3 deletions(-) diff --git a/ast.c b/ast.c index 3d84d97..8120feb 100644 --- a/ast.c +++ b/ast.c @@ -41,7 +41,9 @@ AST* ast_copy(const AST *ast){ assert(ast->l.nodes); AST **nodes=malloc(ast->l.len,AST*); for(int i=0;il.len;i++)nodes[i]=ast_copy(ast->l.nodes[i]); - return ast_list(ast->l.len,nodes); + AST *l=ast_list(ast->l.len,nodes); + l->l.quoted=ast->l.quoted; + return l; } case AST_WORD: @@ -71,6 +73,7 @@ AST* ast_list(int len,AST **nodes){ ast->l.len=len; ast->l.nodes=malloc(len,AST*); memcpy(ast->l.nodes,nodes,len*sizeof(AST*)); + ast->l.quoted=false; return ast; } diff --git a/ast.h b/ast.h index 46c4b49..f55d798 100644 --- a/ast.h +++ b/ast.h @@ -1,10 +1,13 @@ #pragma once +#include + typedef enum ASTtype{ AST_LIST, AST_WORD, AST_NUMBER, + AST_STRING, AST_SYMBOL, } ASTtype; @@ -14,6 +17,7 @@ typedef struct AST AST; typedef struct ASTlist{ int len; AST **nodes; + bool quoted; } ASTlist; typedef struct ASTword{ @@ -24,6 +28,11 @@ typedef struct ASTnumber{ double num; } ASTnumber; +typedef struct ASTstring{ + char *str; + int len; +} ASTstring; + typedef struct ASTsymbol{ char *name; int symid; @@ -38,6 +47,7 @@ struct AST{ ASTlist l; ASTword w; ASTnumber n; + ASTstring S; ASTsymbol s; }; }; diff --git a/parser.c b/parser.c index 7e7a1c2..5069904 100644 --- a/parser.c +++ b/parser.c @@ -15,7 +15,9 @@ typedef enum Tokentype{ TT_EOF, //str=NULL, len=-1 TT_SYMBOL, TT_WORD, + TT_QUOTEDWORD, TT_NUMBER, + TT_STRING, TT_ERR=-1 //str is an error description, len=-1 } Tokentype; @@ -71,6 +73,28 @@ static Token nexttoken(Cursor *cursor){ return tt_make(TT_NUMBER,cursor->s-len,len); } + if(*cursor->s=='"'){ + int i; + for(i=0;il;i++){ + if(cursor->s[i]=='"')break; + if(cursor->s[i]=='\\')i++; + } + if(i==cursor->l){ + return tt_err("Unclosed string in source"); + } + advance(cursor,i); + return tt_make(TT_STRING,cursor->s-i,i); + } + + bool isquoted=false; + if(*cursor->s=='\''){ + isquoted=true; + advance(cursor,1); + if(cursor->l==0||!iswordchar(*cursor->s)){ + return tt_err("Lone single quote in source"); + } + } + int i; for(i=0;il;i++){ if(!iswordchar(cursor->s[i]))break; @@ -79,12 +103,85 @@ static Token nexttoken(Cursor *cursor){ return tt_err("Unrecognised character while looking for next token"); } advance(cursor,i); - return tt_make(TT_WORD,cursor->s-i,i); + return tt_make(isquoted?TT_QUOTEDWORD:TT_WORD,cursor->s-i,i); +} + + +static ParseRet pr_ast(AST *ast){ + ParseRet pr={ast,NULL}; + return pr; +} + +static ParseRet pr_err(char *errstr){ + ParseRet pr={NULL,errstr}; + return pr; } +static ParseRet pr_err_c(const char *errstr){ + return pr_err(copystring(errstr)); +} static ParseRet parse_(Cursor *cursor){ - ; + Token tok=nexttoken(cursor); + switch(tok.type){ + case TT_EOF: + return pr_err_c("Unexpected end-of-file"); + + case TT_SYMBOL:{ + char closing; + if(tok.len!=1)assert(false); + if(tok.str[0]=='(')closing=')'; + else if(tok.str[0]=='[')closing=']'; + else if(tok.str[0]==')'||tok.str[0]==']'){ + return pr_err_c("Unexpected closing paren in source"); + } else assert(false); + + int sz=2,len=0; + AST **nodes=malloc(sz,AST*); + while(true){ + Cursor cur2v=*cursor,*cur2=&cur2v; + Token t=nexttoken(cur2); + if(t.type==TT_SYMBOL&&t.len==1&&t.str[0]==closing){ + *cursor=cur2v; + break; + } + if(t.type==TT_EOF){ + for(int i=0;i