/* StoreCode - store the function or method under construction */ void StoreCode(ParseContext *c) { int codeSize; /* check for unterminated blocks */ switch (CurrentBlockType(c)) { case BLOCK_IF: case BLOCK_ELSE: ParseError(c, "expecting END IF"); case BLOCK_FOR: ParseError(c, "expecting NEXT"); case BLOCK_DO: ParseError(c, "expecting LOOP"); case BLOCK_NONE: break; } /* fixup the RESERVE instruction at the start of the code */ if (c->codeType != CODE_TYPE_MAIN) { c->codeBuf[1] = c->localOffset; putcbyte(c, OP_RETURN); } /* make sure all referenced labels were defined */ CheckLabels(c); /* place string literals defined in this function */ PlaceStrings(c); /* determine the code size */ codeSize = (int)(c->cptr - c->codeBuf); #if 0 VM_printf("%s:\n", c->codeName); DecodeFunction((uint8_t *)c->image, (c->image->objectDataSize + GetObjSizeInWords(sizeof(VectorObjectHdr))) * sizeof(VMVALUE), c->codeBuf, codeSize); DumpSymbols(&c->arguments, "arguments"); DumpSymbols(&c->locals, "locals"); VM_printf("\n"); #endif /* store the vector object */ StoreBVectorData(c, c->code, PROTO_CODE, c->codeBuf, codeSize); /* empty the local heap */ c->nextLocal = c->sys->freeTop; InitSymbolTable(&c->arguments); InitSymbolTable(&c->locals); c->labels = NULL; /* reset to compile the next code */ c->codeType = CODE_TYPE_MAIN; c->cptr = c->codeBuf; }
CHEWING_API int chewing_Init( const char *dataPath, const char *hashPath ) { /* initialize Tree, Char, and Dict */ /* FIXME: check the validation of dataPath */ InitTree( dataPath ); InitChar( dataPath ); InitDict( dataPath ); /* initialize Hash */ /* FIXME: check the validation of hashPath */ InitHash( hashPath ); /* initialize SymbolTable */ if ( ! InitSymbolTable( (char*) hashPath ) ) InitSymbolTable( (char*) dataPath ); if ( ! InitEasySymbolInput( (char *) hashPath ) ) InitEasySymbolInput( (char *) dataPath ); /* initialize HanyuPinYin table */ if ( ! InitHanyuPinYin( hashPath ) ) InitHanyuPinYin( dataPath ); #ifdef ENABLE_DEBUG { char *dbg_path; int failsafe = 1; dbg_path = getenv( "CHEWING_DEBUG" ); if ( dbg_path ) { fp_g = fopen( dbg_path, "w+" ); if ( fp_g ) failsafe = 0; } if ( failsafe == 1 ) { dbg_path = FAILSAFE_OUTPUT; fp_g = fopen( dbg_path, "w+" ); if ( ! fp_g ) { fprintf( stderr, "Failed to record debug message in file.\n" "--> Output to stderr\n" ); } } /* register debug service */ if ( fp_g ) addTerminateService( TerminateDebug ); } #endif bTerminateCompleted = 0; return 0; }
static void Initialize(void) { CurrentHeap = &FileHeap; ErrorCount = WarningCount = 0; InitSymbolTable(); ASTFile = IRFile = ASMFile = NULL; }
/* 初始化 */ static void Initialize (void) { /* 用文件的堆初始化当前堆 */ CurrentHeap = &FileHeap; /* 初始化警告,错误数目 */ WarningCount = ErrorCount = 0; /* 初始化符号表 */ InitSymbolTable (); /* 几种文件描述符 */ ASTFile = IRFile = ASMFile = NULL; }
/* StartCode - start a function or method under construction */ void StartCode(ParseContext *c, CodeType type) { /* all methods must precede the main code */ if (type != CODE_TYPE_MAIN && c->codeFree > c->codeBuf) ParseError(c, "subroutines and functions must precede the main code"); /* don't allow nested functions or subroutines (for now anyway) */ if (type != CODE_TYPE_MAIN && c->codeType != CODE_TYPE_MAIN) ParseError(c, "nested subroutines and functions are not supported"); /* initialize the code object under construction */ InitSymbolTable(&c->arguments); InitSymbolTable(&c->locals); c->localOffset = 0; c->codeType = type; /* write the code prolog */ if (type != CODE_TYPE_MAIN) { putcbyte(c, OP_FRAME); putcbyte(c, 0); } }
CHEWING_API ChewingContext *chewing_new() { ChewingContext *ctx; int ret; char search_path[PATH_MAX]; char path[PATH_MAX]; ctx = ALC( ChewingContext, 1 ); if ( !ctx ) goto error; ctx->output = ALC ( ChewingOutput, 1 ); if ( !ctx->output ) goto error; ctx->data = allocate_ChewingData(); if ( !ctx->data ) goto error; chewing_Reset( ctx ); ret = get_search_path( search_path, sizeof( search_path ) ); if ( ret ) goto error; ret = find_path_by_files( search_path, DICT_FILES, path, sizeof( path ) ); if ( ret ) goto error; ret = InitDict( ctx->data, path ); if ( ret ) goto error; ret = InitTree( ctx->data, path ); if ( ret ) goto error; ret = InitHash( ctx->data ); if ( !ret ) goto error; ctx->cand_no = 0; ret = find_path_by_files( search_path, SYMBOL_TABLE_FILES, path, sizeof( path ) ); if ( ret ) goto error; ret = InitSymbolTable( ctx->data, path ); if ( ret ) goto error; ret = find_path_by_files( search_path, EASY_SYMBOL_FILES, path, sizeof( path ) ); if ( ret ) goto error; ret = InitEasySymbolInput( ctx->data, path ); if ( ret ) goto error; ret = find_path_by_files( search_path, PINYIN_FILES, path, sizeof( path ) ); if ( ret ) goto error; ret = InitPinyin( ctx->data, path ); if ( !ret ) goto error; return ctx; error: chewing_delete( ctx ); return NULL; }
/* Compile - compile a program */ ImageHdr *Compile(ParseContext *c) { System *sys = c->sys; ImageHdr *image = c->image; size_t maxHeapUsed = c->maxHeapUsed; VMVALUE *variables; VMUVALUE totalSize; Symbol *sym; /* setup an error target */ if (setjmp(c->errorTarget) != 0) return NULL; /* initialize the scratch buffer */ BufRewind(); /* allocate space for the object table */ image->objectCount = 0; image->objectDataSize = 0; /* use the rest of the free space for the compiler heap */ c->nextGlobal = sys->freeNext; c->nextLocal = sys->freeTop; c->heapSize = sys->freeTop - sys->freeNext; c->maxHeapUsed = 0; /* initialize the global variable count */ image->variableCount = 0; /* initialize block nesting table */ c->btop = (Block *)((char *)c->blockBuf + sizeof(c->blockBuf)); c->bptr = c->blockBuf - 1; /* initialize the code staging buffer */ c->ctop = c->codeBuf + sizeof(c->codeBuf); c->cptr = c->codeBuf; /* initialize the string and label tables */ c->strings = NULL; c->labels = NULL; /* start in the main code */ c->codeType = CODE_TYPE_MAIN; /* initialize the global symbol table */ InitSymbolTable(&c->globals); /* add the intrinsic functions */ AddIntrinsic(c, "ABS", FN_ABS); AddIntrinsic(c, "RND", FN_RND); AddIntrinsic(c, "printStr", FN_printStr); AddIntrinsic(c, "printInt", FN_printInt); AddIntrinsic(c, "printTab", FN_printTab); AddIntrinsic(c, "printNL", FN_printNL); AddIntrinsic(c, "printFlush", FN_printFlush); #ifdef PROPELLER AddIntrinsic(c, "IN", FN_IN); AddIntrinsic(c, "OUT", FN_OUT); AddIntrinsic(c, "HIGH", FN_HIGH); AddIntrinsic(c, "LOW", FN_LOW); AddIntrinsic(c, "TOGGLE", FN_TOGGLE); AddIntrinsic(c, "DIR", FN_DIR); AddIntrinsic(c, "GETDIR", FN_GETDIR); AddIntrinsic(c, "CNT", FN_CNT); AddIntrinsic(c, "PAUSE", FN_PAUSE); AddIntrinsic(c, "PULSEIN", FN_PULSEIN); AddIntrinsic(c, "PULSEOUT", FN_PULSEOUT); #endif /* initialize scanner */ c->inComment = VMFALSE; /* get the next line */ while (GetLine(c)) { Token tkn; if ((tkn = GetToken(c)) != T_EOL) ParseStatement(c, tkn); } /* end the main code with a halt */ putcbyte(c, OP_HALT); /* write the main code */ StartCode(c, "main", CODE_TYPE_MAIN); image->mainCode = c->code; StoreCode(c); /* allocate the global variable table */ if (!(variables = (VMVALUE *)AllocateFreeSpace(sys, image->variableCount * sizeof(VMVALUE)))) ParseError(c, "insufficient space for variable table"); /* store the initial values of the global variables */ for (sym = c->globals.head; sym != NULL; sym = sym->next) { if (!(sym->value & INTRINSIC_FLAG)) variables[sym->value] = sym->initialValue; } /* write out the variable and object tables */ if (!BufWriteWords(variables, image->variableCount) || !BufWriteWords(image->objects, image->objectCount)) ParseError(c, "insufficient scratch space"); /* free up the space the compiler was consuming */ sys->freeNext = c->freeMark; /* allocate space for the object data and variables */ totalSize = (image->objectDataSize + image->variableCount + image->objectCount) * sizeof(VMVALUE); if (!(image->objectData = (VMVALUE *)AllocateFreeSpace(sys, totalSize))) ParseError(c, "insufficient space for objects and variables"); image->variables = image->objectData + image->objectDataSize; image->objects = image->variables + image->variableCount; /* read the object data and variables from the scratch buffer */ BufRewind(); if (!BufReadWords(image->objectData, totalSize)) ParseError(c, "error reading objects and variables"); { int objectTableSize = image->objectCount * sizeof(VMVALUE); int objectDataSize = image->objectDataSize * sizeof(VMVALUE); int dataSize = objectTableSize + objectDataSize + image->variableCount * sizeof(VMVALUE); #if 0 DumpSymbols(&c->globals, "symbols"); #endif VM_printf("H:%d", maxHeapUsed); VM_printf(" O:%d", image->objectCount); VM_printf(" D:%d", objectDataSize); VM_printf(" V:%d", image->variableCount); VM_printf(" T:%d\n", dataSize); } /* return the image */ return image; }
/* Compile - compile a program */ int Compile(ParseContext *c, uint8_t *imageSpace, size_t imageSize, size_t textMax, size_t dataMax) { ImageHdr *image = (ImageHdr *)imageSpace; VMUVALUE textSize; /* setup an error target */ if (setjmp(c->errorTarget) != 0) return -1; /* initialize the image */ if (imageSize < sizeof(ImageHdr) + textMax + dataMax) return -1; memset(image, 0, sizeof(ImageHdr)); c->image = image; /* empty the heap */ c->localFree = c->heapBase; c->globalFree = c->heapTop; /* initialize the image */ c->textBase = c->textFree = imageSpace + sizeof(ImageHdr); c->textTop = c->textBase + textMax; c->dataBase = c->dataFree = c->textBase + textMax; c->dataTop = c->dataBase + dataMax; /* initialize the code buffer */ c->codeFree = c->codeBuf; c->codeTop = c->codeBuf + sizeof(c->codeBuf); /* initialize block nesting table */ c->btop = (Block *)((char *)c->blockBuf + sizeof(c->blockBuf)); c->bptr = c->blockBuf - 1; /* initialize the global symbol table and string table */ InitSymbolTable(&c->globals); /* enter the built-in functions */ EnterBuiltInFunction(c, "delayMs", bi_delayms, sizeof(bi_delayms)); EnterBuiltInFunction(c, "updateLeds", bi_updateleds, sizeof(bi_updateleds)); /* enter the built-in variables */ /* typedef struct { int32_t triggerTop; int32_t triggerBottom; int32_t numLeds; int32_t led[RGB_SIZE]; int32_t patternnum; } VM_variables; */ EnterBuiltInVariable(c, "triggerTop", sizeof(VMVALUE)); EnterBuiltInVariable(c, "triggerBottom", sizeof(VMVALUE)); EnterBuiltInVariable(c, "numLeds", sizeof(VMVALUE)); EnterBuiltInVariable(c, "led", sizeof(VMVALUE) * RGB_SIZE); EnterBuiltInVariable(c, "patternNum", sizeof(VMVALUE)); /* initialize the string table */ c->strings = NULL; /* initialize the label table */ c->labels = NULL; /* start in the main code */ c->codeType = CODE_TYPE_MAIN; /* initialize scanner */ c->inComment = VMFALSE; c->lineNumber = 0; /* compile each line */ while (GetLine(c)) { int tkn; if ((tkn = GetToken(c)) != T_EOL) ParseStatement(c, tkn); } /* end the main code with a halt */ putcbyte(c, OP_HALT); /* write the main code */ StartCode(c, CODE_TYPE_MAIN); image->entry = StoreCode(c); /* determine the text size */ textSize = c->textFree - c->textBase; /* fill in the image header */ image->dataOffset = sizeof(ImageHdr) + textSize; image->dataSize = c->dataFree - c->dataBase; image->imageSize = image->dataOffset + image->dataSize; /* make the data contiguous with the code */ memcpy(&imageSpace[image->dataOffset], c->dataBase, image->dataSize); #ifdef COMPILER_DEBUG VM_printf("entry "); PrintValue(image->entry); VM_printf("\n"); VM_printf("imageSize "); PrintValue(image->imageSize); VM_printf("\n"); VM_printf("textSize "); PrintValue(textSize); VM_printf("\n"); VM_printf("dataOffset "); PrintValue(image->dataOffset); VM_printf("\n"); VM_printf("dataSize "); PrintValue(image->dataSize); VM_printf("\n"); DumpSymbols(&c->globals, "symbols"); #endif /* return successfully */ return 0; }
/* StoreCode - store the function or method under construction */ VMVALUE StoreCode(ParseContext *c) { size_t codeSize; VMVALUE code; uint8_t *p; /* check for unterminated blocks */ switch (CurrentBlockType(c)) { case BLOCK_IF: case BLOCK_ELSE: ParseError(c, "expecting END IF"); case BLOCK_FOR: ParseError(c, "expecting NEXT"); case BLOCK_DO: ParseError(c, "expecting LOOP"); case BLOCK_NONE: break; } /* fixup the RESERVE instruction at the start of the code */ if (c->codeType != CODE_TYPE_MAIN) { c->codeBuf[1] = 2 + c->localOffset; putcbyte(c, OP_RETURN); } /* make sure all referenced labels were defined */ CheckLabels(c); /* allocate code space */ codeSize = (int)(c->codeFree - c->codeBuf); p = (uint8_t *)ImageTextAlloc(c, codeSize); memcpy(p, c->codeBuf, codeSize); /* get the address of the compiled code */ code = (VMVALUE)(p - (uint8_t *)c->image); #ifdef COMPILER_DEBUG { VM_printf("%s:\n", c->codeSymbol ? c->codeSymbol->name : "<main>"); DecodeFunction((uint8_t *)c->image, (uint8_t *)c->image + code, codeSize); DumpSymbols(&c->arguments, "arguments"); DumpSymbols(&c->locals, "locals"); VM_printf("\n"); } #endif /* prepare the buffer for the next function */ c->codeFree = c->codeBuf; /* empty the local heap */ c->localFree = c->heapBase; InitSymbolTable(&c->arguments); InitSymbolTable(&c->locals); c->labels = NULL; /* reset to compile the next code */ c->codeType = CODE_TYPE_MAIN; /* return the code vector */ return code; }