~kameliya/kyuubey

d9a0d7a434006111c22850e83377d22d3f2f22eb — Yuki Izumi 6 years ago fc1cb56
exprs (should be expr_imm or sth), print wip
4 files changed, 91 insertions(+), 4 deletions(-)

M lang.l
M lang.y
M parser.c
M parser.h
M lang.l => lang.l +2 -1
@@ 5,8 5,9 @@

%%

\"[^"\n]+\"?    { yylval.expr = ast_string_alloc(yytext + 1); return EXPR; }
REM[^\n]+       { yylval.comment = ast_comment_alloc(yytext + 3, 1); return COMMENT; }
'[^\n]+       { yylval.comment = ast_comment_alloc(yytext + 1, 0); return COMMENT; }
'[^\n]+         { yylval.comment = ast_comment_alloc(yytext + 1, 0); return COMMENT; }
[a-zA-Z]+       { yylval.token = ast_token_alloc(yytext); return TOKEN; }
[\t ]+          { }
.               { return yytext[0]; }

M lang.y => lang.y +14 -1
@@ 8,6 8,7 @@
%union {
    ast_comment_t *comment;
    ast_token_t *token;
    ast_expr_t *expr;

    ast_stmt_t *stmt;
}


@@ 17,9 18,11 @@
%token NL

%token <token> TOKEN
%token <expr> EXPR
%token <comment> COMMENT

%type <stmt> line stmt
%type <expr> exprlist opt_exprlist

%%



@@ 36,8 39,18 @@ line:           line_separator          { $$ = 0; }
              | stmt END_OF_FILE        { $$ = $1; }
;

stmt:           TOKEN                   { $$ = ast_stmt_alloc(STMT_CALL); $$->call.target = $1; }
stmt:           TOKEN opt_exprlist      { $$ = ast_stmt_alloc(STMT_CALL); $$->call.target = $1; $$->call.args = $2; }
              | COMMENT                 { $$ = ast_stmt_alloc(STMT_COMMENT); $$->comment = $1; }
;

exprlist:       EXPR                    { $$ = $1; }
              | exprlist ',' EXPR       { $$ = $1; $1->next = $3; $1->nexttype = ','; }
              | exprlist ';' EXPR       { $$ = $1; $1->next = $3; $1->nexttype = ';'; }
              | exprlist EXPR           { $$ = $1; $1->next = $2; $1->nexttype = ';'; }
;

opt_exprlist:   /* empty */             { $$ = 0; }
              | exprlist                { $$ = $1; }
;

/* vim: set sw=4 et: */

M parser.c => parser.c +53 -2
@@ 4,6 4,45 @@

#include "parser.h"

/* ast_expr_t */

ast_expr_t *ast_string_alloc(char const *value) {
    ast_expr_t *expr = malloc(sizeof(*expr));
    memset(expr, 0, sizeof(*expr));
    expr->type = EXPR_STRING;
    expr->string = strdup(value);

    int len = strlen(expr->string);
    if (len > 0 && expr->string[len - 1] == '"') {
        expr->string[len - 1] = 0;
    }

    return expr;
}

void ast_expr_pp(ast_expr_t *expr) {
    switch (expr->type) {
    case EXPR_STRING:
        printf("\"%s\"", expr->string);
        break;

    default:
        fprintf(stderr, "UNKNOWN EXPR TYPE %d\n", expr->type);
    }
}

void ast_expr_free(ast_expr_t *expr) {
    switch (expr->type) {
    case EXPR_STRING:
        free(expr->string);
        break;

    default:
        break;
    }
    free(expr);
}

/* ast_comment_t */

ast_comment_t *ast_comment_alloc(char const *value, int is_rem) {


@@ 45,7 84,19 @@ ast_stmt_t *ast_stmt_alloc(ast_stmt_type_t type) {
void ast_stmt_pp(ast_stmt_t *stmt) {
    switch (stmt->type) {
    case STMT_CALL:
        printf("%s\n", stmt->call.target->value);
        printf("%s", stmt->call.target->value);

        ast_expr_t *args = stmt->call.args;
        while (args) {
            printf(" ");
            ast_expr_pp(args);
            if (args->next) {
                printf("%c", args->nexttype);
            }
            args = args->next;
        }

        printf("\n");
        break;

    case STMT_COMMENT:


@@ 104,7 155,7 @@ int parser_test(void) {
    ast_t *ast = ast_alloc();

    begin_scan(
        "PRINT\n"
        "PRINT \"Hello\"; \"there\", \"pals\" \"!\"\n"
        "GOTO\n"
        "\n"
        "REM Okay, sure thing.\n"

M parser.h => parser.h +22 -0
@@ 1,6 1,27 @@
#ifndef PARSER_H
#define PARSER_H

/* ast_expr_t */

typedef enum {
    EXPR_STRING,
} ast_expr_type_t;

typedef struct ast_expr {
    ast_expr_type_t type;

    union {
        char *string;
    };

    struct ast_expr *next;
    char nexttype;
} ast_expr_t;

ast_expr_t *ast_string_alloc(char const *value);
void ast_expr_pp(ast_expr_t *expr);
void ast_expr_free(ast_expr_t *expr);

/* ast_comment_t */

typedef struct {


@@ 33,6 54,7 @@ typedef struct ast_stmt {
    union {
        struct {
            ast_token_t *target;
            ast_expr_t *args;
        } call;
        ast_comment_t *comment;
    };