#include <EXTERN.h> #include <perl.h> #include <XSUB.h> #include "compiler.h" #include "parser.h" #include "../Type/type.h" /* Apparently we are expected to provide this type as named. */ typedef struct _amd_parser { void *foo; } *Anarres__Mud__Driver__Compiler; typedef char *Anarres__Mud__Driver__Compiler__Type; typedef struct _keyword_t { char *keyword; int token; AMD_YYSTYPE lval; } keyword_t; #define LVAL_NONE { .number = 0 } /* We have to allocate static storage for all of these. */ static const char LVAL_BOOL[] = { C_BOOL, 0 }; static const char LVAL_CLOSURE[] = { C_CLOSURE, 0 }; static const char LVAL_INTEGER[] = { C_INTEGER, 0 }; static const char LVAL_MAPPING[] = { C_M_MAPPING, C_UNKNOWN, 0 }; static const char LVAL_UNKNOWN[] = { C_UNKNOWN, 0 }; static const char LVAL_OBJECT[] = { C_OBJECT, 0 }; static const char LVAL_STRING[] = { C_STRING, 0 }; static const char LVAL_VOID[] = { C_VOID, 0 }; static keyword_t keywords[] = { { "bool", L_BASIC_TYPE, { .str = LVAL_BOOL } }, { "break", L_BREAK, LVAL_NONE }, { "case", L_CASE, LVAL_NONE }, { "class", L_CLASS, LVAL_NONE }, { "continue", L_CONTINUE, LVAL_NONE }, { "default", L_DEFAULT, LVAL_NONE }, { "do", L_DO, LVAL_NONE }, { "efun", L_EFUN, LVAL_NONE }, { "else", L_ELSE, LVAL_NONE }, { "for", L_FOR, LVAL_NONE }, { "foreach", L_FOREACH, LVAL_NONE }, { "function", L_BASIC_TYPE, { .str = LVAL_CLOSURE } }, { "if", L_IF, LVAL_NONE }, { "in", L_IN, LVAL_NONE }, { "inherit", L_INHERIT, LVAL_NONE }, { "int", L_BASIC_TYPE, { .str = LVAL_INTEGER } }, { "mapping", L_BASIC_TYPE, { .str = LVAL_MAPPING } }, { "mixed", L_BASIC_TYPE, { .str = LVAL_UNKNOWN } }, { "nil", L_NIL, LVAL_NONE }, { "new", L_NEW, LVAL_NONE }, { "nomask", L_TYPE_MODIFIER, { .number = M_NOMASK } }, { "nosave", L_TYPE_MODIFIER, { .number = M_NOSAVE } }, { "object", L_BASIC_TYPE, { .str = LVAL_OBJECT } }, { "private", L_TYPE_MODIFIER, { .number = M_PRIVATE } }, { "protected", L_TYPE_MODIFIER, { .number = M_PROTECTED } }, { "public", L_TYPE_MODIFIER, { .number = M_PUBLIC } }, { "return", L_RETURN, LVAL_NONE }, { "rlimits", L_RLIMITS, LVAL_NONE }, { "sscanf", L_SSCANF, LVAL_NONE }, { "string", L_BASIC_TYPE, { .str = LVAL_STRING } }, { "static", L_TYPE_MODIFIER, { .number = M_STATIC } }, { "switch", L_SWITCH, LVAL_NONE }, { "varargs", L_TYPE_MODIFIER, { .number = M_VARARGS } }, // { "virtual", L_TYPE_MODIFIER, { .number = M_VIRTUAL } }, { "void", L_VOID, { .str = LVAL_VOID } }, { "while", L_WHILE, LVAL_NONE }, }; MODULE = Anarres::Mud::Driver::Compiler PACKAGE = Anarres::Mud::Driver::Compiler PROTOTYPES: ENABLE BOOT: { { SV *sv; int size; int i; size = sizeof(keywords) / sizeof(keywords[0]); /* Don't put this into Perl-space or it can get fucked with. */ /* One day we might want to allow that. */ amd_kwtab = newHV(); amd_lvaltab = newHV(); for (i = 0; i < size; i++) { hv_store(amd_kwtab, keywords[i].keyword, strlen(keywords[i].keyword), newSViv(keywords[i].token), 0); if (keywords[i].lval.number) { sv = newSViv(PTR2IV((void *)(&keywords[i].lval) )); hv_store(amd_lvaltab, keywords[i].keyword, strlen(keywords[i].keyword), sv, 0); } } } { /* The parser needs these to build the tree. */ amd_require(_AMD "::Compiler::Type"); amd_require(_AMD "::Compiler::Node"); amd_require(_AMD "::Program"); } } Anarres::Mud::Driver::Compiler new(class) SV * class CODE: RETVAL = Newz(0, RETVAL, 1, struct _amd_parser); OUTPUT: RETVAL int lex(class, str) SV * class char * str CODE: test_lexer(str); RETVAL = 0; OUTPUT: RETVAL int parse(class, prog, str) SV * class SV * prog char * str CODE: amd_yyparser_parse(prog, str); RETVAL = 0; OUTPUT: RETVAL void DESTROY(self) Anarres::Mud::Driver::Compiler self CODE: Safefree(self);