strans/ko.c

322 lines
7.0 KiB
C

#include "dat.h"
#include "fn.h"
enum
{
Sbase = 0xAC00,
Jbase = 0x3131,
Jrange = 51,
Ncho = 19,
Njung = 21,
Njong = 28,
};
static Rune cho[] = {
L'', L'', L'', L'', L'',
L'', L'', L'', L'', L'',
L'', L'', L'', L'', L'',
L'', L'', L'', L'',
};
static Rune jung[] = {
L'', L'', L'', L'', L'',
L'', L'', L'', L'', L'',
L'', L'', L'', L'', L'',
L'', L'', L'', L'', L'',
L'',
};
static Rune jong[] = {
0, L'', L'', L'', L'',
L'', L'', L'', L'', L'',
L'', L'', L'', L'', L'',
L'', L'', L'', L'', L'',
L'', L'', L'', L'', L'',
L'', L'', L'',
};
static int choidx[Jrange] = {
[L''-Jbase] = 1, [L''-Jbase] = 2, [L''-Jbase] = 3,
[L''-Jbase] = 4, [L''-Jbase] = 5, [L''-Jbase] = 6,
[L''-Jbase] = 7, [L''-Jbase] = 8, [L''-Jbase] = 9,
[L''-Jbase] = 10, [L''-Jbase] = 11, [L''-Jbase] = 12,
[L''-Jbase] = 13, [L''-Jbase] = 14, [L''-Jbase] = 15,
[L''-Jbase] = 16, [L''-Jbase] = 17, [L''-Jbase] = 18,
[L''-Jbase] = 19,
};
static int jungidx[Jrange] = {
[L''-Jbase] = 1, [L''-Jbase] = 2, [L''-Jbase] = 3,
[L''-Jbase] = 4, [L''-Jbase] = 5, [L''-Jbase] = 6,
[L''-Jbase] = 7, [L''-Jbase] = 8, [L''-Jbase] = 9,
[L''-Jbase] = 10, [L''-Jbase] = 11, [L''-Jbase] = 12,
[L''-Jbase] = 13, [L''-Jbase] = 14, [L''-Jbase] = 15,
[L''-Jbase] = 16, [L''-Jbase] = 17, [L''-Jbase] = 18,
[L''-Jbase] = 19, [L''-Jbase] = 20, [L''-Jbase] = 21,
};
static int jongidx[Jrange] = {
[L''-Jbase] = 2, [L''-Jbase] = 3, [L''-Jbase] = 4,
[L''-Jbase] = 5, [L''-Jbase] = 6, [L''-Jbase] = 7,
[L''-Jbase] = 8, [L''-Jbase] = 9, [L''-Jbase] = 10,
[L''-Jbase] = 11, [L''-Jbase] = 12, [L''-Jbase] = 13,
[L''-Jbase] = 14, [L''-Jbase] = 15, [L''-Jbase] = 16,
[L''-Jbase] = 17, [L''-Jbase] = 18, [L''-Jbase] = 19,
[L''-Jbase] = 20, [L''-Jbase] = 21, [L''-Jbase] = 22,
[L''-Jbase] = 23, [L''-Jbase] = 24, [L''-Jbase] = 25,
[L''-Jbase] = 26, [L''-Jbase] = 27, [L''-Jbase] = 28,
};
#define Choidx(r) (choidx[(r) - Jbase] - 1)
#define Jungidx(r) (jungidx[(r) - Jbase] - 1)
#define Jongidx(r) (jongidx[(r) - Jbase] - 1)
static Rune jamomap[128] = {
['r'] = L'', ['R'] = L'',
['s'] = L'', ['S'] = L'',
['e'] = L'', ['E'] = L'',
['f'] = L'', ['F'] = L'',
['a'] = L'', ['A'] = L'',
['q'] = L'', ['Q'] = L'',
['t'] = L'', ['T'] = L'',
['d'] = L'', ['D'] = L'',
['w'] = L'', ['W'] = L'',
['c'] = L'', ['C'] = L'',
['z'] = L'', ['Z'] = L'',
['x'] = L'', ['X'] = L'',
['v'] = L'', ['V'] = L'',
['g'] = L'', ['G'] = L'',
['k'] = L'', ['K'] = L'',
['o'] = L'', ['O'] = L'',
['i'] = L'', ['I'] = L'',
['j'] = L'', ['J'] = L'',
['p'] = L'', ['P'] = L'',
['u'] = L'', ['U'] = L'',
['h'] = L'', ['H'] = L'',
['y'] = L'', ['Y'] = L'',
['n'] = L'', ['N'] = L'',
['b'] = L'', ['B'] = L'',
['m'] = L'', ['M'] = L'',
['l'] = L'', ['L'] = L'',
};
typedef struct Cpair Cpair;
struct Cpair
{
Rune b;
Rune a;
Rune r;
};
static Cpair cvow[] = {
{L'', L'', L''},
{L'', L'', L''},
{L'', L'', L''},
{L'', L'', L''},
{L'', L'', L''},
{L'', L'', L''},
{L'', L'', L''},
};
static Cpair cjong[] = {
{L'', L'', L''},
{L'', L'', L''},
{L'', L'', L''},
{L'', L'', L''},
{L'', L'', L''},
{L'', L'', L''},
{L'', L'', L''},
{L'', L'', L''},
{L'', L'', L''},
{L'', L'', L''},
{L'', L'', L''},
};
static Rune
keytojamo(int c)
{
if(c >= 0 && c < 128)
return jamomap[c];
return 0;
}
static Rune
combine(Cpair *t, int n, Rune b, Rune a)
{
int i;
for(i = 0; i < n; i++)
if(t[i].b == b && t[i].a == a)
return t[i].r;
return 0;
}
static int
splitpair(Cpair *t, int n, Rune c, Rune *stay, Rune *next)
{
int i;
for(i = 0; i < n; i++){
if(t[i].r == c){
*stay = t[i].b;
*next = t[i].a;
return 1;
}
}
return 0;
}
static Rune
compose(int c, int j, int jo)
{
return Sbase + c*Njung*Njong + j*Njong + jo;
}
static void
decompose(Rune s, int *c, int *j, int *jo)
{
int i;
i = s - Sbase;
*c = i / (Njung * Njong);
*j = (i / Njong) % Njung;
*jo = i % Njong;
}
static int
issyl(Rune r)
{
return r >= Sbase && r < Sbase + Ncho*Njung*Njong;
}
Emit
transko(Im *im, Rune c)
{
Emit e;
Rune jm, jc, last, comb, stay, next;
int ci, ji, joi, ni, si, vi;
memset(&e, 0, sizeof e);
jm = keytojamo(c);
if(jm == 0){
if(im->pre.n > 0){
e.s = im->pre;
sclear(&im->pre);
}
sputr(&e.s, c);
return e;
}
e.eat = 1;
last = slastr(&im->pre);
if(last == 0){
sputr(&e.next, jm);
return e;
}
if(!issyl(last)){
ci = Choidx(last);
ji = Jungidx(jm);
if(ci >= 0 && ji >= 0){
spopr(&im->pre);
sputr(&e.next, compose(ci, ji, 0));
return e;
}
if(Jungidx(last) >= 0 && ji >= 0){
comb = combine(cvow, nelem(cvow), last, jm);
if(comb){
spopr(&im->pre);
sputr(&e.next, comb);
return e;
}
}
e.s = im->pre;
sputr(&e.next, jm);
return e;
}
decompose(last, &ci, &ji, &joi);
if(joi == 0){
ni = Jongidx(jm);
if(ni > 0){
spopr(&im->pre);
sputr(&e.next, compose(ci, ji, ni));
return e;
}
vi = Jungidx(jm);
if(vi >= 0){
comb = combine(cvow, nelem(cvow), jung[ji], jm);
if(comb){
ni = Jungidx(comb);
spopr(&im->pre);
sputr(&e.next, compose(ci, ni, 0));
return e;
}
}
}
if(joi > 0){
comb = combine(cjong, nelem(cjong), jong[joi], jm);
if(comb){
ni = Jongidx(comb);
if(ni > 0){
spopr(&im->pre);
sputr(&e.next, compose(ci, ji, ni));
return e;
}
}
vi = Jungidx(jm);
if(vi >= 0){
jc = jong[joi];
if(splitpair(cjong, nelem(cjong), jc, &stay, &next)){
si = Jongidx(stay);
ni = Choidx(next);
spopr(&im->pre);
sputr(&e.s, compose(ci, ji, si));
sputr(&e.next, compose(ni, vi, 0));
return e;
}
ni = Choidx(jc);
if(ni >= 0){
spopr(&im->pre);
sputr(&e.s, compose(ci, ji, 0));
sputr(&e.next, compose(ni, vi, 0));
return e;
}
}
}
e.s = im->pre;
sputr(&e.next, jm);
return e;
}
void
backko(Im *im)
{
Rune last;
int c, j, jo;
Rune stay, next;
last = slastr(&im->pre);
if(!issyl(last)){
if(splitpair(cvow, nelem(cvow), last, &stay, &next)){
spopr(&im->pre);
sputr(&im->pre, stay);
return;
}
spopr(&im->pre);
return;
}
decompose(last, &c, &j, &jo);
spopr(&im->pre);
if(jo > 0 && splitpair(cjong, nelem(cjong), jong[jo], &stay, &next)){
sputr(&im->pre, compose(c, j, Jongidx(stay)));
return;
}
if(jo > 0){
sputr(&im->pre, compose(c, j, 0));
return;
}
if(splitpair(cvow, nelem(cvow), jung[j], &stay, &next)){
sputr(&im->pre, compose(c, Jungidx(stay), 0));
return;
}
sputr(&im->pre, cho[c]);
}