void testSymbol() { #if 0 // Operator int i = 0; for(; i < KeywordsCount; ++i) { printf("%s\n", Operators[i]); } #endif // test: isKeyword isLiteral isVar isSemicolon symbol_construct symbol_deconstruct #if 0 // not ok char *symbol[] = {"int", "i", "=", "12", ";"}; for(int i = 0; i < sizeof(symbol) / sizeof(symbol[0]); ++i) { // ok printf("symbol %s : isKeyword:%s isLiteral:%s isVar:%s isSemicolon:%s\n", symbol[i], TO_BOOL_STR(isKeyword(symbol[i])), TO_BOOL_STR(isLiteral(symbol[i])), TO_BOOL_STR(isVar(symbol[i])), TO_BOOL_STR(isSemicolon(symbol[i]))); Symbol *sb = symbol_construct(symbol[i]); if(sb) { // not ok printf("%x %x %x %x \n", IS_KEYWORD(sb->type), IS_LITERAL(sb->type), IS_VAR(sb->type), IS_SEMICOLON(sb->type)); symbol_deconstruct(sb); } } #endif // test: isCharLiteral isStringLiteral isDecNumber isOctNumber isHexNumber isFloatNumer // tes: isDoubleNumber #if 0 // ok int i = 0; const char *strArr[] = {"\'c\'", "\"abc\"", "453", "0453", "781", "a90", "0x34", "0X56", "9.34", "9.4e2", "9.5E5", "9e+2", "9e-3", "9.34f", "9.34F" }; for(; i < sizeof(strArr) / sizeof(strArr[0]); ++i) { printf("%s: isCharLiteral(%s)\n\t", strArr[i], TO_BOOL_STR(isCharLiteral(strArr[i]))); printf("isStringLiteral(%s)\n\t", TO_BOOL_STR(isStringLiteral(strArr[i]))); printf("isDecNumber(%s)\n\t", TO_BOOL_STR(isDecNumber(strArr[i]))); printf("isOctNumber(%s)\n\t", TO_BOOL_STR(isOctNumber(strArr[i]))); printf("isHexNumber(%s)\n\t", TO_BOOL_STR(isHexNumber(strArr[i]))); printf("isFloatNumber(%s)\n\t", TO_BOOL_STR(isFloatNumber(strArr[i]))); printf("isDoubleNumber(%s)\n", TO_BOOL_STR(isDoubleNumber(strArr[i]))); } /* // I don't know why, but it can't output all strings for(; i < sizeof(strArr) / sizeof(strArr[0]); ++i) { printf("%s: isCharLiteral(%s)\n\t isStringLiteral(%s)\n\t isDecNumber(%s)\n\t isOctNumber(%s)\n\t isHexNumber(%s)\n\t isFloatNumber(%s)\n\t isDoubleNumber(%s)\n", strArr[i], TO_BOOL_STR(isCharLiteral(strArr[i])), TO_BOOL_STR(isStringLiteral(strArr[i])), TO_BOOL_STR(isDecNumber(strArr[i])), TO_BOOL_STR(isOctNumber(strArr[i])), TO_BOOL_STR(isHexNumber(strArr[i])), TO_BOOL_STR(isFloatNumber(strArr[i])), TO_BOOL_STR(isDoubleNumber(strArr[i]))); } */ #endif }
internal Type *deref(Type *type) { if (IS_VAR(type)) { type = rep(type); if (type->terms) { return type->terms; } } return type; }
internal Type *canonical_type(Type *type, TypePool *pool) { type = deref(type); if (IS_VAR(type)) { return type; } if (type->symbol == SYMBOL_UNIT) { return pool->unit; } if (type->symbol == SYMBOL_NUMBER) { return pool->number; } if (type->symbol == SYMBOL_BOOL) { return pool->boolean; } }
internal void print_type_(Type *type, u32 prec, TypePtrB1Map *seen, TypePtrU64Map *vars, U8Array *buf) { if (IS_VAR(type)) { type = rep(type); if (type->terms == NULL) { TypePtrU64MapGetResult result = type_ptr_u64_map_get(vars, type); if (!result.found) { result.value = vars->size; type_ptr_u64_map_put_bucket(vars, type, result.value, result.bucket); } push_var(buf, result.value); return; } else if (type->terms->next == type->terms) { type = type->terms; } else { array_push(buf, '{'); Type *term = type->terms; do { // TODO consider printing out the full type if (term == type->terms) { array_push(buf, ','); } if (IS_SEALED(term->symbol)) { u8Array_push_cstring(buf, "sealed \" "); u8Array_push_many(buf, term->seal->data, term->seal->size); array_push(buf, '"'); } else { switch (term->symbol) { case SYMBOL_VOID: array_push(buf, '0'); break; case SYMBOL_UNIT: array_push(buf, '1'); break; case SYMBOL_NUMBER: array_push(buf, 'N'); break; case SYMBOL_PRODUCT: array_push(buf, '*'); break; case SYMBOL_SUM: array_push(buf, '+'); break; case SYMBOL_BLOCK: u8Array_push_cstring(buf, "=>"); break; case SYMBOL_BLOCK | POLYMORPHIC_BIT: u8Array_push_cstring(buf, "->"); break; case SYMBOL_BOOL: array_push(buf, 'B'); break; default: array_push(buf, '?'); break; } } term = term->next; } while (term != type->terms); array_push(buf, '}'); return; } } TypePtrB1MapGetResult seen_result = type_ptr_b1_map_get(seen, type); if (seen_result.found) { TypePtrU64MapGetResult vars_result = type_ptr_u64_map_get(vars, type); if (!vars_result.found) { vars_result.value = vars->size; type_ptr_u64_map_put_bucket(vars, type, vars_result.value, vars_result.bucket); } push_var(buf, vars_result.value); return; } type_ptr_b1_map_put_bucket(seen, type, true, seen_result.bucket); TypePtrU64MapGetResult vars_result = type_ptr_u64_map_get(vars, type); if (vars_result.found) { map_delete_bucket(vars, vars_result.bucket); } usize begin = buf->size; if (IS_SEALED(type->symbol)) { if (prec > 8) { array_push(buf, '('); } u8Array_push_cstring(buf, "sealed \""); u8Array_push_many(buf, type->seal->data, type->seal->size); u8Array_push_cstring(buf, "\" "); print_type_(type->child1, 9, seen, vars, buf); if (prec > 8) { array_push(buf, ')'); } } else { u8 sym = 0; b32 children = true; u32 newprec = 100; b32 block = false; switch (type->symbol) { case SYMBOL_VOID: sym = '0'; children = false; break; case SYMBOL_UNIT: sym = '1'; children = false; break; case SYMBOL_NUMBER: sym = 'N'; children = false; break; case SYMBOL_PRODUCT: sym = '*'; newprec = 7; break; case SYMBOL_SUM: sym = '+'; newprec = 6; break; case SYMBOL_BLOCK: case SYMBOL_BLOCK | POLYMORPHIC_BIT: block = true; break; case SYMBOL_BOOL: sym = 'B'; children = false; break; default: sym = '?'; } if (prec > newprec) { array_push(buf, '('); } else if (block) { array_push(buf, '['); } if (children) { print_type_(type->child1, newprec + 1, seen, vars, buf); } if (type->symbol == SYMBOL_BLOCK) { u8Array_push_cstring(buf, " => "); } else if (type->symbol == (SYMBOL_BLOCK | POLYMORPHIC_BIT)) { u8Array_push_cstring(buf, " -> "); } else { if (children) { array_push(buf, ' '); } array_push(buf, sym); if (children) { array_push(buf, ' '); } } if (children) { print_type_(type->child2, newprec, seen, vars, buf); } if (prec > newprec) { array_push(buf, ')'); } else if (block) { array_push(buf, ']'); } } map_delete_bucket(seen, seen_result.bucket); vars_result = type_ptr_u64_map_get(vars, type); if (vars_result.found) { u32 shift = sizeof("μ. ") - 1 + var_len(vars_result.value); if (prec > 0) { shift++; } array_bump(buf, shift); memmove(buf->data + begin + shift, buf->data + begin, buf->size - begin - shift); u8 *hole = buf->data + begin; if (prec > 0) { *hole++ = '('; } hole = mempcpy(hole, "μ", sizeof("μ") - 1); u32 len = var_len(vars_result.value); write_var(hole, vars_result.value, len); hole += len; hole = mempcpy(hole, ". ", sizeof(". ") - 1); if (prec > 0) { array_push(buf, ')'); } } }