Number tőszámnév sorszámnév határozói szorzó disztributív kollektív tört
0 ნული (nuli)
1 ერთი (erti) პირველი (ṗirveli) ერთხელ (ertxel), ერთჯერ (ertǯer) ერთმაგი (ertmagi) ერთმაგად (ertmagad) ერთივე (ertive) მთლიანი (mtliani), სრული (sruli)
2 ორი (ori) მეორე (meore) ორჯერ (orǯer) ორმაგი (ormagi) ორმაგად (ormagad) ორივე (orive) ნახევარი (naxevari), მეორედი (meoredi)
3 სამი (sami) მესამე (mesame) სამჯერ (samǯer) სამმაგი (sammagi) სამმაგად (sammagad) სამივე (samive) მესამედი (mesamedi)
4 ოთხი (otxi) მეოთხე (meotxe) ოთხჯერ (otxǯer) ოთხმაგი (otxmagi) ოთხმაგად (otxmagad) ოთხივე (otxive) მეოთხედი (meotxedi)
5 ხუთი (xuti) მეხუთე (mexute) ხუთჯერ (xutǯer) ხუთმაგი (xutmagi) ხუთმაგად (xutmagad) ხუთივე (xutive) მეხუთედი (mexutedi)
6 ექვსი (ekvsi) მეექვსე (meekvse) ექვსჯერ (ekvsǯer) ექვსმაგი (ekvsmagi) ექვსმაგად (ekvsmagad) ექვსივე (ekvsive) მეექვსედი (meekvsedi)
7 შვიდი (švidi) მეშვიდე (mešvide) შვიდჯერ (švidǯer) შვიდმაგი (švidmagi) შვიდმაგად (švidmagad) შვიდივე (švidive) მეშვიდედი (mešvidedi)
8 რვა (rva) მერვე (merve) რვაჯერ (rvaǯer) რვამაგი (rvamagi) რვამაგად (rvamagad) რვავე (rvave) მერვედი (mervedi)
9 ცხრა (cxra) მეცხრე (mecxre) ცხრაჯერ (cxraǯer) ცხრამაგი (cxramagi) ცხრამაგად (cxramagad) ცხრავე (cxrave) მეცხრედი (mecxredi)
10 ათი (ati) მეათე (meate) ათჯერ (atǯer) ათმაგი (atmagi) ათმაგად (atmagad) ათივე (ative) მეათედი (meatedi)
11 თერთმეტი (tertmeṭi) მეთერთმეტე (metertmeṭe)
12 თორმეტი (tormeṭi) მეთორმეტე (metormeṭe)
13 ცამეტი (cameṭi) მეცამეტე (mecameṭe)
14 თოთხმეტი (totxmeṭi) მეთოთხმეტე (metotxmeṭe)
15 თხუთმეტი (txutmeṭi) მეთხუთმეტე (metxutmeṭe)
16 თექვსმეტი (tekvsmeṭi) მეთექვსმეტე (metekvsmeṭe)
17 ჩვიდმეტი (čvidmeṭi) მეჩვიდმეტე (mečvidmeṭe)
18 თვრამეტი (tvrameṭi) მეთვრამეტე (metvrameṭe)
19 ცხრამეტი (cxrameṭi) მეცხრამეტე (mecxrameṭe)
20 ოცი (oci) მეოცე (meoce) ოცმაგი (ocmagi)
21 ოცდაერთი (ocdaerti) ოცდამეერთე (ocdameerte)
22 ოცდაორი (ocdaori) ოცდამეორე (ocdameore)
23 ოცდასამი (ocdasami) ოცდამესამე (ocdamesame)
24 ოცდაოთხი (ocdaotxi) ოცდამეოთხე (ocdameotxe)
25 ოცდახუთი (ocdaxuti) ოცდამეხუთე (ocdamexute)
26 ოცდაექვსი (ocdaekvsi) ოცდამეექვსე (ocdameekvse)
27 ოცდაშვიდი (ocdašvidi) ოცდამეშვიდე (ocdamešvide)
28 ოცდარვა (ocdarva) ოცდამერვე (ocdamerve)
29 ოცდაცხრა (ocdacxra) ოცდამეცხრე (ocdamecxre)
30 ოცდაათი (ocdaati) ოცდამეათე (ocdameate)
31 ოცდათერთმეტი (ocdatertmeṭi) ოცდამეთერთმეტე (ocdametertmeṭe)
32 ოცდათორმეტი (ocdatormeṭi) ოცდამეთორმეტე (ocdametormeṭe)
33 ოცდაცამეტი (ocdacameṭi) ოცდამეცამეტე (ocdamecameṭe)
34 ოცდათოთხმეტი (ocdatotxmeṭi) ოცდამეთოთხმეტე (ocdametotxmeṭe)
35 ოცდათხუთმეტი (ocdatxutmeṭi) ოცდამეთხუთმეტე (ocdametxutmeṭe)
36 ოცდათექვსმეტი (ocdatekvsmeṭi) ოცდამეთექვსმეტე (ocdametekvsmeṭe)
37 ოცდაჩვიდმეტი (ocdačvidmeṭi) ოცდამეჩვიდმეტე (ocdamečvidmeṭe)
38 ოცდათვრამეტი (ocdatvrameṭi) ოცდამეთვრამეტე (ocdametvrameṭe)
39 ოცდაცხრამეტი (ocdacxrameṭi) ოცდამეცხრამეტე (ocdamecxrameṭe)
40 ორმოცი (ormoci) მეორმოცე (meormoce)
41 ორმოცდაერთი (ormocdaerti) ორმოცდამეერთე (ormocdameerte)
42 ორმოცდაორი (ormocdaori) ორმოცდამეორე (ormocdameore)
43 ორმოცდასამი (ormocdasami) ორმოცდამესამე (ormocdamesame)
44 ორმოცდაოთხი (ormocdaotxi) ორმოცდამეოთხე (ormocdameotxe)
45 ორმოცდახუთი (ormocdaxuti) ორმოცდამეხუთე (ormocdamexute)
46 ორმოცდაექვსი (ormocdaekvsi) ორმოცდამეექვსე (ormocdameekvse)
47 ორმოცდაშვიდი (ormocdašvidi) ორმოცდამეშვიდე (ormocdamešvide)
48 ორმოცდარვა (ormocdarva) ორმოცდამერვე (ormocdamerve)
49 ორმოცდაცხრა (ormocdacxra) ორმოცდამეცხრე (ormocdamecxre)
50 ორმოცდაათი (ormocdaati) ორმოცდამეათე (ormocdameate)
51 ორმოცდათერთმეტი (ormocdatertmeṭi) ორმოცდამეთერთმეტე (ormocdametertmeṭe)
52 ორმოცდათორმეტი (ormocdatormeṭi) ორმოცდამეთორმეტე (ormocdametormeṭe)
53 ორმოცდაცამეტი (ormocdacameṭi) ორმოცდამეცამეტე (ormocdamecameṭe)
54 ორმოცდათოთხმეტი (ormocdatotxmeṭi) ორმოცდამეთოთხმეტე (ormocdametotxmeṭe)
55 ორმოცდათხუთმეტი (ormocdatxutmeṭi) ორმოცდამეთხუთმეტე (ormocdametxutmeṭe)
56 ორმოცდათექვსმეტი (ormocdatekvsmeṭi) ორმოცდამეთექვსმეტე (ormocdametekvsmeṭe)
57 ორმოცდაჩვიდმეტი (ormocdačvidmeṭi) ორმოცდამეჩვიდმეტე (ormocdamečvidmeṭe)
58 ორმოცდათვრამეტი (ormocdatvrameṭi) ორმოცდამეთვრამეტე (ormocdametvrameṭe)
59 ორმოცდაცხრამეტი (ormocdacxrameṭi) ორმოცდამეცხრამეტე (ormocdamecxrameṭe)
60 სამოცი (samoci) მესამოცე (mesamoce)
61 სამოცდაერთი (samocdaerti) სამოცდამეერთე (samocdameerte)
62 სამოცდაორი (samocdaori) სამოცდამეორე (samocdameore)
63 სამოცდასამი (samocdasami) სამოცდამესამე (samocdamesame)
64 სამოცდაოთხი (samocdaotxi) სამოცდამეოთხე (samocdameotxe)
65 სამოცდახუთი (samocdaxuti) სამოცდამეხუთე (samocdamexute)
66 სამოცდაექვსი (samocdaekvsi) სამოცდამეექვსე (samocdameekvse)
67 სამოცდაშვიდი (samocdašvidi) სამოცდამეშვიდე (samocdamešvide)
68 სამოცდარვა (samocdarva) სამოცდამერვე (samocdamerve)
69 სამოცდაცხრა (samocdacxra) სამოცდამეცხრე (samocdamecxre)
70 სამოცდაათი (samocdaati) სამოცდამეათე (samocdameate)
71 სამოცდათერთმეტი (samocdatertmeṭi) სამოცდამეთერთმეტე (samocdametertmeṭe)
72 სამოცდათორმეტი (samocdatormeṭi) სამოცდამეთორმეტე (samocdametormeṭe)
73 სამოცდაცამეტი (samocdacameṭi) სამოცდამეცამეტე (samocdamecameṭe)
74 სამოცდათოთხმეტი (samocdatotxmeṭi) სამოცდამეთოთხმეტე (samocdametotxmeṭe)
75 სამოცდათხუთმეტი (samocdatxutmeṭi) სამოცდამეთხუთმეტე (samocdametxutmeṭe)
76 სამოცდათექვსმეტი (samocdatekvsmeṭi) სამოცდამეთექვსმეტე (samocdametekvsmeṭe)
77 სამოცდაჩვიდმეტი (samocdačvidmeṭi) სამოცდამეჩვიდმეტე (samocdamečvidmeṭe)
78 სამოცდათვრამეტი (samocdatvrameṭi) სამოცდამეთვრამეტე (samocdametvrameṭe)
79 სამოცდაცხრამეტი (samocdacxrameṭi) სამოცდამეცხრამეტე (samocdamecxrameṭe)
80 ოთხმოცი (otxmoci) მეოთხმოცე (meotxmoce)
81 ოთხმოცდაერთი (otxmocdaerti) ოთხმოცდამეერთე (otxmocdameerte)
82 ოთხმოცდაორი (otxmocdaori) ოთხმოცდამეორე (otxmocdameore)
83 ოთხმოცდასამი (otxmocdasami) ოთხმოცდამესამე (otxmocdamesame)
84 ოთხმოცდაოთხი (otxmocdaotxi) ოთხმოცდამეოთხე (otxmocdameotxe)
85 ოთხმოცდახუთი (otxmocdaxuti) ოთხმოცდამეხუთე (otxmocdamexute)
86 ოთხმოცდაექვსი (otxmocdaekvsi) ოთხმოცდამეექვსე (otxmocdameekvse)
87 ოთხმოცდაშვიდი (otxmocdašvidi) ოთხმოცდამეშვიდე (otxmocdamešvide)
88 ოთხმოცდარვა (otxmocdarva) ოთხმოცდამერვე (otxmocdamerve)
89 ოთხმოცდაცხრა (otxmocdacxra) ოთხმოცდამეცხრე (otxmocdamecxre)
90 ოთხმოცდაათი (otxmocdaati) ოთხმოცდამეათე (otxmocdameate)
91 ოთხმოცდათერთმეტი (otxmocdatertmeṭi) ოთხმოცდამეთერთმეტე (otxmocdametertmeṭe)
92 ოთხმოცდათორმეტი (otxmocdatormeṭi) ოთხმოცდამეთორმეტე (otxmocdametormeṭe)
93 ოთხმოცდაცამეტი (otxmocdacameṭi) ოთხმოცდამეცამეტე (otxmocdamecameṭe)
94 ოთხმოცდათოთხმეტი (otxmocdatotxmeṭi) ოთხმოცდამეთოთხმეტე (otxmocdametotxmeṭe)
95 ოთხმოცდათხუთმეტი (otxmocdatxutmeṭi) ოთხმოცდამეთხუთმეტე (otxmocdametxutmeṭe)
96 ოთხმოცდათექვსმეტი (otxmocdatekvsmeṭi) ოთხმოცდამეთექვსმეტე (otxmocdametekvsmeṭe)
97 ოთხმოცდაჩვიდმეტი (otxmocdačvidmeṭi) ოთხმოცდამეჩვიდმეტე (otxmocdamečvidmeṭe)
98 ოთხმოცდათვრამეტი (otxmocdatvrameṭi) ოთხმოცდამეთვრამეტე (otxmocdametvrameṭe)
99 ოთხმოცდაცხრამეტი (otxmocdacxrameṭi) ოთხმოცდამეცხრამეტე (otxmocdamecxrameṭe)
100 ასი (asi) მეასე (mease) ასმაგი (asmagi)
200 ორასი (orasi) მეორასე (meorase)
300 სამასი (samasi) მესამასე (mesamase)
400 ოთხასი (otxasi) მეოთხასე (meotxase)
500 ხუთასი (xutasi) მეხუთასე (mexutase)
600 ექვსასი (ekvsasi) მეექვსასე (meekvsase)
700 შვიდასი (švidasi) მეშვიდასე (mešvidase)
800 რვასი (rvasi) მერვასე (mervase)
900 ცხრასი (cxrasi) მეცხრასე (mecxrase)
1000 ათასი (atasi) მეათასე (meatase) ათასმაგი (atasmagi)
1000000 მილიონი (milioni) მემილიონე (memilione)

local export = {numbers = {}}

-- Automatically create new subtables of export.numbers through __index,
-- automatically add new fields of export.numbers
-- without overwriting old ones through __newindex.
local actual_numbers = export.numbers

local namespace = mw.title.getCurrentTitle().nsText
local function log(...)
	if namespace == "Module" then
		mw.log(...)
	end
end

local proxy_number_metatable = {
	__newindex = function (self, k, v)
		local old = rawget(self.__actual, k)
		if old then
			log("k: " .. k .. "; old " .. old .. "; new " .. v .. "; old == new: " .. tostring(old == v))
		end
		
		if type(old) == "table" then
			table.insert(old, v)
		elseif type(old) == "string" then
			if old ~= v then
				rawset(self.__actual, k, { old, v })
			end
		else
			rawset(self.__actual, k, v)
		end
	end,
	__index = function (self, k)
		return rawget(self.__actual, k)
	end,
}

local proxy_subtables = {}
local function get_proxy_number_table(k, actual_table)
	local t = proxy_subtables[k]
	if not t then
		t = setmetatable({ __actual = actual_table }, proxy_number_metatable)
		proxy_subtables[k] = t
	end
	return t
end

local function get_actual_number_table(k)
	local t = actual_numbers[k]
	if not t then
		t = {}
		actual_numbers[k] = t
	end
	return t
end

local proxy_numbers = setmetatable({}, {
	__newindex = function (self, k1, fields)
		local subtable = get_actual_number_table(k1)
		local proxy_subtable = get_proxy_number_table(k1, subtable)
		if not proxy_subtable then
			proxy_subtable = new_proxy_number_table(subtable)
			mw.log("new proxy_subtable for " .. k1)
			rawset(proxy_subtables, k1, proxy_subtable)
		end
		for k, v in pairs(fields) do
			proxy_subtable[k] = v
		end
	end,
	__index = function (self, k)
		local actual_table = get_actual_number_table(k)
		local proxy_table = get_proxy_number_table(k, actual_table)
		return proxy_table
	end,
})
local numbers = proxy_numbers

local adverbial_suffix = "ჯერ"
local multiplier_suffix = "მაგი"
local distributive_suffix = "ად"
local collective_suffix = "ვე"
local fractional_suffix = "დი"

numbers[0].cardinal = "ნული"

numbers[1] = {
	cardinal = "ერთი",
	ordinal = "პირველი",
	multiplier = "ერთმაგი",
	distributive = "ერთმაგად",
	adverbial = "ერთხელ",
	collective = "ერთივე",
	fractional = { "მთლიანი", "სრული" },
}

numbers[2] = {
	cardinal = "ორი",
	distributive = "ორმაგად",
	adverbial = "ორჯერ",
	collective = "ორივე",
	fractional = "ნახევარი", -- regular fractional added below
}

numbers[3] = {
	cardinal = "სამი",
	distributive = "სამმაგად",
	adverbial = "სამჯერ",
	collective = "სამივე",
	fractional = "მესამედი",
}

numbers[4] = {
	cardinal = "ოთხი",
	distributive = "ოთხმაგად",
	adverbial = "ოთხჯერ",
	collective = "ოთხივე",
	fractional = "მეოთხედი",
}

numbers[5] = {
	cardinal = "ხუთი",
	distributive = "ხუთმაგად",
	adverbial = "ხუთჯერ",
	collective = "ხუთივე",
	fractional = "მეხუთედი",
}

numbers[6] = {
	cardinal = "ექვსი",
	distributive = "ექვსმაგად",
	adverbial = "ექვსჯერ",
	collective = "ექვსივე",
	fractional = "მეექვსედი",
}

numbers[7] = {
	cardinal = "შვიდი",
	distributive = "შვიდმაგად",
	adverbial = "შვიდჯერ",
	collective = "შვიდივე",
	fractional = "მეშვიდედი",
}

numbers[8] = {
	cardinal = "რვა",
	distributive = "რვამაგად",
	adverbial = "რვაჯერ",
	collective = "რვავე",
	fractional = "მერვედი",
}

numbers[9] = {
	cardinal = "ცხრა",
	distributive = "ცხრამაგად",
	adverbial = "ცხრაჯერ",
	collective = "ცხრავე",
	fractional = "მეცხრედი",
}

numbers[10] = {
	cardinal = "ათი",
	distributive = "ათმაგად",
	adverbial = "ათჯერ",
	collective = "ათივე",
	fractional = "მეათედი",
}

numbers[11].cardinal = "თერთმეტი"

numbers[12].cardinal = "თორმეტი"

numbers[13].cardinal = "ცამეტი"

numbers[14].cardinal = "თოთხმეტი"

numbers[15].cardinal = "თხუთმეტი"

numbers[16].cardinal = "თექვსმეტი"

numbers[17].cardinal = "ჩვიდმეტი"

numbers[18].cardinal = "თვრამეტი"

numbers[19].cardinal = "ცხრამეტი"

numbers[20].multiplier = "ოც" .. multiplier_suffix

local function remove_final_vowel(word)
	return (mw.ustring.gsub(word, "[აეიოუ]$", ""))
end

local function remove_final_i(word)
	return word:gsub("ი$", "")
end

local function get_cardinal(number)
	return numbers[number].cardinal
end

local function get(number, type)
	return numbers[number][type]
end

local function circumfix_ordinal(cardinal)
	return "მე" .. remove_final_vowel(cardinal) .. "ე"
end

for number = 2, 19 do
	numbers[number].ordinal = circumfix_ordinal(get_cardinal(number))
end

for number = 1, 10 do
	numbers[number].adverbial = remove_final_i(get_cardinal(number))
		.. adverbial_suffix
end

for number = 2, 10 do
	numbers[number].multiplier = remove_final_i(get_cardinal(number))
		.. multiplier_suffix
	
	numbers[number].distributive = remove_final_i(get(number, "multiplier"))
		.. distributive_suffix
	
	numbers[number].collective = get_cardinal(number)
		.. collective_suffix
	
	numbers[number].fractional = remove_final_i(get(number, "ordinal"))
		.. fractional_suffix
end

local twenty = "ოცი"
-- Add cardinals and ordinals for 20-99.
for i = 1, 4 do
	local twenties = i * 20
	local twenties_cardinal
	if i ~= 1 then
		twenties_cardinal = (remove_final_vowel(get_cardinal(i)) .. "მ" .. twenty)
			:gsub("მმ", "მ")
	else
		twenties_cardinal = twenty
	end
	numbers[twenties] = {
		cardinal = twenties_cardinal,
		ordinal = circumfix_ordinal(twenties_cardinal),
	}
	
	local twenties_and = remove_final_vowel(twenties_cardinal) .. "და"
	
	for ones = 1, 19 do
		numbers[twenties + ones] = {
			cardinal = twenties_and .. get_cardinal(ones),
			ordinal = twenties_and .. circumfix_ordinal(get_cardinal(ones)),
		}
	end
end

local hundred_cardinal = "ასი"
numbers[100].multiplier = "ას" .. multiplier_suffix

for i = 1, 10 do
	local cardinal
	if i == 1 then
		cardinal = hundred_cardinal
	else
		cardinal = remove_final_vowel(get_cardinal(i)) .. hundred_cardinal
	end
	numbers[i * 100] = {
		cardinal = cardinal,
		ordinal = circumfix_ordinal(cardinal), -- is this right?
	}
end

numbers[1000].multiplier = "ათას" .. multiplier_suffix

numbers[1000000] = {
	cardinal = "მილიონი",
	ordinal = "მემილიონე"
}

return export