int addTranslation(TNODE ** dictionary, const char * pattern, const char * translation) { TNODE * node; if (* dictionary == NULL) { * dictionary = mallocNode(); } if (pattern[0] == '\0') return 0; node = *dictionary; unsigned int i, charIndex; for (i = 0; pattern[i] != '\0'; i++) { if (node->translation != NULL) return 0; charIndex = pattern[i] - FIRST_ASCII; if (node->child[charIndex] == NULL) { node->child[charIndex] = mallocNode(); } node = node->child[charIndex]; } if (node->translation != NULL) return 0; for (i = 0; i < LETTERS; i++) { if (node->child[i]) return 0; } node->translation = translation; return 1; }
void insertFront( Node **root, Card x ) { Node *ptr = (*root); (*root) = mallocNode(); setNode( (*root), x,ptr ); }
void insertRear( Node **root, Card x ){ Node *ptr = (*root); if( (*root) == NULL ) insertFront( &(*root), x); else{ while( ptr->next != NULL) ptr = ptr->next; ptr->next = mallocNode(); setNode(ptr->next, x, NULL); } }
void insertBTree(BTree *tree, int key) { if(tree->root == NULL) { tree->root = mallocNode(tree->arity, true); tree->root->n = 1; tree->root->keys[0] = key; } else { if(tree->root->n == tree->arity -1) { fork(tree, NULL, tree->root, true); } insertRecursive(tree, tree->root, key); } }
void fork(BTree* tree, Node* node, Node* full, bool root) { if(root) { Node* newRoot = mallocNode(tree->arity, false); Node* right = mallocNode(tree->arity, full->leaf); newRoot->keys[0] = full->keys[tree->arity/2-1]; for(int i=tree->arity/2;i<full->n;i++) { right->keys[i - tree->arity/2] = full->keys[i]; right->children[i-tree->arity/2] = full->children[i]; } right->children[tree->arity/2-1] = full->children[full->n]; full->n = tree->arity/2 -1; right->n = tree->arity/2 -1; newRoot->n = 1; newRoot->children[0] = full; newRoot->children[1] = right; tree->root = newRoot; } else { Node* right = mallocNode(tree->arity, full->leaf); for(int i=tree->arity/2;i<full->n;i++) { right->keys[i - tree->arity/2] = full->keys[i]; right->children[i - tree->arity/2] = full->children[i]; } right->children[tree->arity/2] = full->children[full->n]; int i=node->n; while(node->keys[i-1] > full->keys[tree->arity/2-1]) { node->keys[i] = node->keys[i-1]; node->children[i+1] = node->children[i]; i--; } node->keys[i] = full->keys[tree->arity/2-1]; node->children[i] = full; node->children[i+1] = right; node->n += 1; full->n = tree->arity/2-1; right->n = tree->arity -2 -full->n; } }
// This returns the parsed expression as a node, or NULL. If NULL is returned, error is made to point at an error message. All named indices less than or equal to global // are considered global; all other indices should be bound lambdas. u32 parseExpression( LNZprogram* p, const u8* string, u64 length, const char** error ){ *error = NULL; const u8* s = string; u64 l = length; // Eat up whitespace in front and back. while( l && isWhitespace( *s ) ){ --l; ++s; } while( l && isWhitespace( s[ l - 1 ] ) ) --l; if( !l ){ *error = "Syntax error: null expression."; return s - string; } // Handle lambdas if( *s == '\\' ){ ++s; --l; while( l && isWhitespace( *s ) ){ --l; ++s; } if( !l || !isName( *s ) ){ *error = "Syntax error: malformed lambda, expected an identifier."; return s - string; } // Eat identifiers, add them to the nametables, and build up an empty lambda at // top. u64 lambdaCount = 0; u32 cur, top; do{ u64 namelen = 0; while( namelen < l && isName( s[ namelen ] ) ) ++namelen; u32 newnode = mallocNode( p ); p->heap[ newnode ].type = LNZ_LAMBDA_TYPE; p->heap[ newnode ].references = 1; if( lambdaCount ) p->heap[ cur ].data = newnode; else top = newnode; ++lambdaCount; cur = newnode; addNamePointerPair( p, s, namelen, newnode ); // Eat trailing namespace while( namelen < l && isWhitespace( s[ namelen ] ) ) ++namelen; if( namelen == l || ( s[ namelen ] != '.' && !isName( s[ namelen ] ) ) ){ *error = "Syntax error: malformed lambda, expected '.' or an identifier."; return ( s - string ) + namelen; } s += namelen; l -= namelen; }while( *s != '.' ); // Parse the body. u32 pe = parseExpression( p, s + 1, l - 1, error ); if( *error != NULL ) return ( s - string ) + 1 + pe; p->heap[ cur ].data = pe; // Pop scope. while( lambdaCount ){ --lambdaCount; popNamePointerPair( p ); } return top; } // Handle applications,free variables, numbers and strings. u64 applicationCount = 0; u32 top; // Read one expression at a time; must be parenthetical or a name. do{ u32 arg; u64 namelen = 0; // Handle strings. if( s[ namelen ] == '\'' ){ ++namelen; u32 nullstring = mallocNode( p ); p->heap[ nullstring ].type = LNZ_DATA_TYPE; p->heap[ nullstring ].references = 0; // size. p->heap[ nullstring ].data = 0; arg = mallocNode( p ); p->heap[ arg ].type = LNZ_STRING_TYPE; p->heap[ arg ].references = 1; // size. p->heap[ arg ].data = ( (u64)nullstring ) << 32; p->heap[ arg ].data += ( (u64)nullstring ); u64 bsc = 0; while( namelen < l ){ if( s[ namelen ] == '\'' ){ while( bsc >= 2 ){ bsc -= 2; addStringChar( p, arg, '\\' ); } if( bsc ){ addStringChar( p, arg, '\'' ); bsc = 0; }else break; }else if( s[ namelen ] == '\\' ){ ++bsc; }else{ while( bsc >= 2 ){ bsc -= 2; addStringChar( p, arg, '\\' ); } bsc = 0; addStringChar( p, arg, s[ namelen ] ); } ++namelen; } if( namelen == l || s[ namelen ] != '\'' ){ *error = "Syntax error: malformed string."; return ( s - string ) + namelen; } ++namelen; // Handle parenthetical subexpressions. }else if( *s == '[' ){ namelen = 1; u64 f = 1; // scan for parentheses. u64 bsc = 0; u64 qm = 0; while( namelen < l ){ if( s[ namelen ] == '\\' ) ++bsc; else if( s[ namelen ] == '\'' ){ if( !( bsc % 2 ) && qm ) qm = 0; else if( !( bsc % 2 ) && !qm ) qm = 1; bsc = 0; }else{ if( !qm && s[ namelen ] == '[' ) ++f; if( !qm && s[ namelen ] == ']' ) --f; bsc = 0; } ++namelen; if( !f ) break; } if( f || namelen < 2 ){ *error = "Syntax error: unbalanced parentheses."; return s - string; } arg = parseExpression( p, s + 1, namelen - 2, error ); if( *error != NULL ) return ( s - string ) + 1 + arg; }else{ if( !l || !isName( *s ) ){ *error = "Syntax error: malformed expression."; return s - string; } // Handle identifiers and integers. while( namelen < l && isName( s[ namelen ] ) ) ++namelen; u64 isint = 1; u64 isminus = 0; u64 i = 0; if( s[ i ] == '-' ){ ++i; isminus = 1; if( namelen == 1 ) isint = 0; } for( ; i < namelen; ++i ) if( !isNumber( s[ i ] ) ) isint = 0; if( isint ){ arg = mallocNode( p ); u32 dn = mallocNode( p ); p->heap[ arg ].type = LNZ_INT_TYPE + isminus; p->heap[ arg ].references = 1; p->heap[ arg ].data = ( ( (u64)dn ) << 32 ) + ( (u64)dn ); p->heap[ dn ].type = LNZ_DATA_TYPE; p->heap[ dn ].references = 1; p->heap[ dn ].data = 0; i = 0; if( s[ i ] == '-' ) ++i; while( i < namelen && isNumber( s[ i ] ) ){ multiplyNumberByInt( p, arg, 10 ); addIntToNumber( p, arg, s[ i ] - '0' ); ++i; } }else{ u64 nind = getIndex( p->names, s, namelen ); if( !nind ){ *error = "Unknown identifier."; return s - string; } u32 pntr = getPointerFromName( p, s, namelen ); // if global or not a lambda, treat as an identifier, otherwise a free variable. if( nind <= p->global || p->heap[ pntr ].type != LNZ_LAMBDA_TYPE ) arg = *( ( u32* )( getName( p->pointers, nind, NULL ) ) ); else{ arg = mallocNode( p ); p->heap[ arg ].type = LNZ_FREE_TYPE; p->heap[ arg ].references = 1; p->heap[ arg ].data = *( ( u32* )( getName( p->pointers, nind, NULL ) ) ); } } } u32 newnode; if( applicationCount == 1 ) newnode = top; else{ newnode = mallocNode( p ); p->heap[ newnode ].data = 0; } p->heap[ newnode ].type = LNZ_APPLICATION_TYPE; p->heap[ newnode ].references = 1; p->heap[ newnode ].data += ( (u64)arg ) << 32; if( applicationCount > 1 ){ p->heap[ newnode ].data += top; } else if( !applicationCount ) p->heap[ newnode ].data >>= 32; top = newnode; ++applicationCount; // Eat up trailing whitespace. while( namelen < l && isWhitespace( s[ namelen ] ) ) ++namelen; s += namelen; l -= namelen; }while( l ); if( applicationCount == 1 ){ u32 ans = p->heap[ top ].data; freeNode( p, top ); return ans; }else{ return top; } }