Commit Diff


commit - 2be87f778a56964007d4c5ccf7171fa000149f79
commit + 9828682d540b975b38136ea29d9e2d4821f3442b
blob - 771e0898b66bd3ce7b85cd60ab72614d746765e4
blob + cf4055f93e6f1181a01b395d5b0428d13ee87d33
--- tools/6c
+++ tools/6c
@@ -3,7 +3,7 @@
 -----------------------------------------------------------------------
 -- TOKEN MATCHING
 -----------------------------------------------------------------------
-local mnemonics = { "mov", "cli", "hlt", "ret", "sti" }
+local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int" }
 
 -- This is kinda a double definition but fix later :^)
 local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" }
@@ -208,6 +208,9 @@ local function intval(intstr)
 
 	for i = 1, len do
 		local s = intstr:sub(len - i + 1, len - i + 1)
+		if s:match("[0-9]") == false then
+			return nil
+		end
 		s = s * (10 ^ (i - 1))
 		res = res + s
 	end
@@ -255,7 +258,179 @@ function bitval(b)
 
 	return result
 end
+
+
 -----------------------------------------------------------------------
+-- EXPRESSION SOLVING
+-----------------------------------------------------------------------
+
+local function subarray(array, start, last)
+	if last == nil then
+		last = #array
+	end
+
+	local sub = { }
+
+	for i, v in ipairs(array) do
+		if i >= start and i <= last then
+			table.insert(sub, array[i])
+		end
+	end
+
+	return sub
+end
+
+local function finddepth(array, spos)
+	local epos = nil
+	local depth = 1
+
+	for j = spos, #array do
+		if array[j] == "(" then depth = depth + 1 end
+		if array[j] == ")" then depth = depth - 1 end
+
+		if depth == 0 then
+			epos = j
+			break
+		end
+	end
+
+	if depth ~= 0 then
+		perror("invalid nesting")
+	end
+
+	if epos == nil then perror("Mismatched paranthesis") end
+
+	return epos
+end
+
+-- Use this once the syntax validation is completed
+local function evaluate_expression(array)
+	local i = 1
+	local eval = { }
+	while i <= #array do
+		if array[i] == "(" then
+			local spos = i
+			local epos = finddepth(array, spos + 1)
+
+			local sub = { }
+			for k = spos + 1, epos - 1 do
+				table.insert(sub, array[k])
+			end
+
+			local result = evaluate_expression(sub)
+
+			for _, val in ipairs(result) do
+				table.insert(eval, val)
+			end
+
+			i = epos + 1
+		elseif array[i] == "*" then
+			local left = table.remove(eval)
+			local right = array[i + 1]
+			local epos = i + 2
+
+			if right == "(" then
+				local sub = subarray(array, i + 1)
+				right = evaluate_expression(sub)[1]
+				epos = finddepth(array, i + 2) + 1
+			end
+
+			if type(left) == "string" and type(right) == "string" then
+				if tonumber(left) ~= nil and tonumber(right) ~= nil then
+					table.insert(eval, tostring(tonumber(left) * tonumber(right)))
+
+				elseif tonumber(left) == nil and tonumber(right) ~= nil then
+					table.insert(eval, { left, tonumber(right) })
+
+				elseif tonumber(left) ~= nil and tonumber(right) == nil then
+					table.insert(eval, { right, tonumber(left) })
+
+				end
+			elseif type(left) == "table" and type(right) == "string" then
+				if tonumber(right) ~= nil then
+					table.insert(eval, { left[1], left[2] * tonumber(right) })
+				end
+			end
+
+			i = epos
+		else
+			table.insert(eval, array[i])
+			i = i + 1
+		end
+	end
+
+	local k = 1
+	local total = 0
+	local final = {}
+
+	while k < #eval do
+		local cur = eval[k]
+		local opr = eval[k + 1]
+		local nxt = eval[k + 2]
+
+		local n1 = tonumber(cur)
+		local n2 = tonumber(nxt)
+
+		if n1 ~= nil then
+			total = n1 + total
+			k = k + 1
+		elseif cur == "+" or cur == "-" then
+			if tonumber(opr) ~= nil then
+				if cur == "+" then
+					total = tonumber(opr) + total
+				elseif cur == "-" then
+					total = total - tonumber(opr)
+				end
+
+				k = k + 2
+			else
+				if type(opr) == "string" then
+					table.insert(final, {opr, 1})
+				else
+					table.insert(final, opr)
+				end
+				k = k + 2
+			end
+
+		elseif type(cur) == "string" and n2 ~= nil then
+			table.insert(final, { cur, 1 })
+			total = total + n2
+			k = k + 3
+
+		elseif type(cur) == "table" and n2 ~= nil then
+			table.insert(final, cur)
+			if opr == "-" then
+				total = total - n2
+			else
+				total = total + n2
+			end
+			k = k + 3
+
+		elseif type(cur) == "table" and type(nxt) == "string" then
+			k = k + 3
+
+		elseif type(cur) == "string" and type(nxt) == "string" then
+			table.insert(final, { cur, 1 })
+			table.insert(final, { nxt, 1 })
+			k = k + 3
+
+		elseif type(cur) == "string" and type(nxt) == "table" then
+			table.insert(final, { cur, 1 })
+			table.insert(final, nxt)
+			k = k + 3
+
+		else
+			k = k + 3
+		end
+	end
+
+	if total ~= 0 then
+		table.insert(final, tostring(total))
+	end
+
+	return final
+end
+-----------------------------------------------------------------------
 -- Checking arguments and setting read and write file
 -----------------------------------------------------------------------
 
@@ -357,7 +532,7 @@ end
 -- Tokenizing
 -----------------------------------------------------------------------
 
-local nline = 0
+local nline = 1
 while true do
 	local line = src:read("*l")
 	if line == nil then
blob - c40eacaa915eea26d8db27517a070e966ab2c204
blob + 037ae3288d68a6b0a53ce2301d8fade58d65088c
--- tools/6l
+++ tools/6l
@@ -3,7 +3,7 @@
 -----------------------------------------------------------------------
 -- TOKEN MATCHING
 -----------------------------------------------------------------------
-local mnemonics = { "mov", "cli", "hlt", "ret", "sti" }
+local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int" }
 
 -- This is kinda a double definition but fix later :^)
 local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" }
@@ -208,6 +208,9 @@ local function intval(intstr)
 
 	for i = 1, len do
 		local s = intstr:sub(len - i + 1, len - i + 1)
+		if s:match("[0-9]") == false then
+			return nil
+		end
 		s = s * (10 ^ (i - 1))
 		res = res + s
 	end
@@ -255,7 +258,179 @@ function bitval(b)
 
 	return result
 end
+
+
 -----------------------------------------------------------------------
+-- EXPRESSION SOLVING
+-----------------------------------------------------------------------
+
+local function subarray(array, start, last)
+	if last == nil then
+		last = #array
+	end
+
+	local sub = { }
+
+	for i, v in ipairs(array) do
+		if i >= start and i <= last then
+			table.insert(sub, array[i])
+		end
+	end
+
+	return sub
+end
+
+local function finddepth(array, spos)
+	local epos = nil
+	local depth = 1
+
+	for j = spos, #array do
+		if array[j] == "(" then depth = depth + 1 end
+		if array[j] == ")" then depth = depth - 1 end
+
+		if depth == 0 then
+			epos = j
+			break
+		end
+	end
+
+	if depth ~= 0 then
+		perror("invalid nesting")
+	end
+
+	if epos == nil then perror("Mismatched paranthesis") end
+
+	return epos
+end
+
+-- Use this once the syntax validation is completed
+local function evaluate_expression(array)
+	local i = 1
+	local eval = { }
+	while i <= #array do
+		if array[i] == "(" then
+			local spos = i
+			local epos = finddepth(array, spos + 1)
+
+			local sub = { }
+			for k = spos + 1, epos - 1 do
+				table.insert(sub, array[k])
+			end
+
+			local result = evaluate_expression(sub)
+
+			for _, val in ipairs(result) do
+				table.insert(eval, val)
+			end
+
+			i = epos + 1
+		elseif array[i] == "*" then
+			local left = table.remove(eval)
+			local right = array[i + 1]
+			local epos = i + 2
+
+			if right == "(" then
+				local sub = subarray(array, i + 1)
+				right = evaluate_expression(sub)[1]
+				epos = finddepth(array, i + 2) + 1
+			end
+
+			if type(left) == "string" and type(right) == "string" then
+				if tonumber(left) ~= nil and tonumber(right) ~= nil then
+					table.insert(eval, tostring(tonumber(left) * tonumber(right)))
+
+				elseif tonumber(left) == nil and tonumber(right) ~= nil then
+					table.insert(eval, { left, tonumber(right) })
+
+				elseif tonumber(left) ~= nil and tonumber(right) == nil then
+					table.insert(eval, { right, tonumber(left) })
+
+				end
+			elseif type(left) == "table" and type(right) == "string" then
+				if tonumber(right) ~= nil then
+					table.insert(eval, { left[1], left[2] * tonumber(right) })
+				end
+			end
+
+			i = epos
+		else
+			table.insert(eval, array[i])
+			i = i + 1
+		end
+	end
+
+	local k = 1
+	local total = 0
+	local final = {}
+
+	while k < #eval do
+		local cur = eval[k]
+		local opr = eval[k + 1]
+		local nxt = eval[k + 2]
+
+		local n1 = tonumber(cur)
+		local n2 = tonumber(nxt)
+
+		if n1 ~= nil then
+			total = n1 + total
+			k = k + 1
+		elseif cur == "+" or cur == "-" then
+			if tonumber(opr) ~= nil then
+				if cur == "+" then
+					total = tonumber(opr) + total
+				elseif cur == "-" then
+					total = total - tonumber(opr)
+				end
+
+				k = k + 2
+			else
+				if type(opr) == "string" then
+					table.insert(final, {opr, 1})
+				else
+					table.insert(final, opr)
+				end
+				k = k + 2
+			end
+
+		elseif type(cur) == "string" and n2 ~= nil then
+			table.insert(final, { cur, 1 })
+			total = total + n2
+			k = k + 3
+
+		elseif type(cur) == "table" and n2 ~= nil then
+			table.insert(final, cur)
+			if opr == "-" then
+				total = total - n2
+			else
+				total = total + n2
+			end
+			k = k + 3
+
+		elseif type(cur) == "table" and type(nxt) == "string" then
+			k = k + 3
+
+		elseif type(cur) == "string" and type(nxt) == "string" then
+			table.insert(final, { cur, 1 })
+			table.insert(final, { nxt, 1 })
+			k = k + 3
+
+		elseif type(cur) == "string" and type(nxt) == "table" then
+			table.insert(final, { cur, 1 })
+			table.insert(final, nxt)
+			k = k + 3
+
+		else
+			k = k + 3
+		end
+	end
+
+	if total ~= 0 then
+		table.insert(final, tostring(total))
+	end
+
+	return final
+end
+-----------------------------------------------------------------------
 -- Checking arguments
 -----------------------------------------------------------------------
 progname = "6l"
@@ -375,7 +550,8 @@ local function operlyze(op, ret)
 	-- You cannot multiply the base reg (not allowed according to manual)
 	-- You can only multiply index reg by a factor of 2 up to max value 8 (1, 2, 4, 8)
 	elseif op.type == tk_type["["] then
-		local brackets = { opened = 0, closed = 0 }
+		local expr = { }
+		local depth = 0
 
 		while true do
 			local pre = op
@@ -395,25 +571,54 @@ local function operlyze(op, ret)
 						" line " .. op.line)
 				end
 
-				if #ret.memblock.regs == 0 and typematch(pre, { "+", "-" }) == false then
+				if #ret.memblock.regs == 0 and typematch(pre, { "+", "-" , "[", "(" }) == false then
 					perror("Base register `" .. gettokenkey(op) .. 
 						"` can only be applied + or - on it line " .. op.line)
-				elseif #ret.memblock.regs == 1 and typematch(pre, { "+", "-", "*" }) == false then
+				elseif #ret.memblock.regs == 1 and typematch(pre, { "+", "-", "*", "(", "[" }) == false then
 					perror("Index register `" .. gettokenkey(op) .. 
 						"` can only be applied +, - or * on it line " .. op.line)
 				end
 				table.insert(ret.memblock.regs, gettokenkey(op))
+				table.insert(expr, gettokenkey(op))
 
 			elseif typematch(op, { "hexadecimal", "integer" }) then
 				if typematch(pre, { "[", arithmetics }) == false then
 					perror("missing arithmetic/paranthesis prefix for whole number " .. op.raw ..
 						" line " .. op.line)
 				end
+
+				if op.type == tk_type["hexadecimal"] then
+					table.insert(expr, tostring(hexval(op.raw)))
+				elseif op.type == tk_type["integer"] then
+					table.insert(expr, tostring(intval(op.raw)))
+				end
+
 			-- Other arithmetic symbols
 			elseif isarithmetic(op) == true then
-				if typematch(pre, { regs8, "hexadecimal", "integer" }) == false then
+				if typematch(pre, { regs8, "hexadecimal", "integer", ")" }) == false then
 					perror("illegal token before " .. gettokenkey(op) .. " at line " .. op.line)
 				end
+
+				if #ret.memblock.regs == 1 and typematch(pre, { regs8 }) == true and typematch(op, { "+", "-" } ) == false then
+					perror("Base register `" .. gettokenkey(pre) .. 
+						"` can only be applied + or - on it line " .. op.line)
+				end
+				table.insert(expr, gettokenkey(op))
+
+			elseif op.type == tk_type["("] then
+				if typematch(pre, { regs8, arithmetics, "(", "[" , "hexadecimal", "integer" }) == false then
+					perror("illegal token befor `(` at line " .. op.line)
+				end
+
+				table.insert(expr, "(")
+				depth = depth + 1
+			elseif op.type == tk_type[")"] then
+				if typematch(pre, { regs8, "hexadecimal", ")", "integer" }) == false then
+					perror("illegal token before `)` at line " .. op.line)
+				end
+
+				table.insert(expr, ")")
+				depth = depth - 1
 			else
 				perror("illegal token " .. gettokenkey(op) .. " at line " .. op.line)
 			end
@@ -423,12 +628,34 @@ local function operlyze(op, ret)
 			end
 		end
 
+		if depth ~= 0 then
+			perror("Mismatching paranthesis at line " .. op.line)
+		end
+
 		if op.type ~= tk_type["]"] then
 			perror("Missing closing `]` at line " .. op.line)
 		end
 
+		local e = evaluate_expression(expr)
+		--[[
+		for _,v in ipairs(e) do
+			if type(v) == "string" then
+				io.write(v, " ")
+			else
+				io.write("{")
+				io.write(v[1], ", ")
+				io.write(v[2], "")
+				io.write("} ")
+			end
+		end
+		io.write("\n")
+		io.write("\n")
+		]]--
+
+		ret.memblock.expression = e
 		table.insert(ret.details, ASM_MEM8)
 		ret.opcount = 1
+
 	elseif op.type == tk_type["\n"] then
 		ret.opcount = 0
 	else
@@ -447,6 +674,7 @@ local function asmlyze(first)
 				regs = { },
 				dispsize = 0,
 				blevel = 0,
+				expression = nil
 			}
 		}
 
@@ -516,6 +744,7 @@ local function instvaluate(inst)
 		return ret
 	elseif opcount == 1 then
 	-- amslyze caps it at 2
+		return ret
 	else
 		if inst.details[1] == ASM_R8 and inst.details[2] == ASM_R8 then
 			local dstmap = regmap[gettokenkey(inst.operands[1])]
@@ -534,6 +763,8 @@ local function instvaluate(inst)
 		-- 10 memory 32 bit displacement
 		-- 11 register to register
 		elseif inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8 then
+			local mod = "00"
+
 			return ret
 		end
 	end
@@ -661,6 +892,25 @@ while true do
 
 					elseif hdr.type == tk_type["cli"] then
 						writeu8(dst, hexval("0hFA"))
+
+					elseif hdr.type == tk_type["int"] then
+						local opcount = #inst.details
+
+						if opcount ~= 1 then
+							perror("int takes 1 operand at line " .. hdr.line)
+						end
+
+						if inst.details[1] ~= ASM_IMM8 then
+							perror("int requires an immediate 8 byte value")
+						end
+
+						writeu8(dst, hexval("0hCD"))
+
+						if inst.operands[1].type == tk_type["hexadecimal"] then
+							writeu8(dst, hexval(inst.operands[1].raw))
+						elseif inst.operands[1].type == tk_type["integer"] then
+							writeu8(dst, intval(inst.operands[1].raw))
+						end
 					end
 				end
 			end
blob - 6d39970a0aa2f1314e3971c97ecf869d5bff94ec
blob + 5ab188ebc6559ddc93627d47140bf87ce8a562de
--- tools/boot.sc
+++ tools/boot.sc
@@ -1,4 +1,8 @@
 asm {
 _start:
+	mov ah, 0h0e
+	mov al, 0h61
+	int 0h10
+	mov [ al + 0h100 ], bl
 	hlt
 }
blob - 73c6a396f089b292270ae57e9209b940ccaa8b91
blob + 4f1f15f1abbc7a87e724565092403922576b4833
--- tools/compiler.lua
+++ tools/compiler.lua
@@ -100,7 +100,7 @@ end
 -- Tokenizing
 -----------------------------------------------------------------------
 
-local nline = 0
+local nline = 1
 while true do
 	local line = src:read("*l")
 	if line == nil then
blob - 88127113ea6e94d8819871d58c5f49c92ed74cda
blob + aff9c78043627789dc3802f77df40ac91a3b049b
--- tools/linker.lua
+++ tools/linker.lua
@@ -118,7 +118,8 @@ local function operlyze(op, ret)
 	-- You cannot multiply the base reg (not allowed according to manual)
 	-- You can only multiply index reg by a factor of 2 up to max value 8 (1, 2, 4, 8)
 	elseif op.type == tk_type["["] then
-		local brackets = { opened = 0, closed = 0 }
+		local expr = { }
+		local depth = 0
 
 		while true do
 			local pre = op
@@ -138,25 +139,54 @@ local function operlyze(op, ret)
 						" line " .. op.line)
 				end
 
-				if #ret.memblock.regs == 0 and typematch(pre, { "+", "-" }) == false then
+				if #ret.memblock.regs == 0 and typematch(pre, { "+", "-" , "[", "(" }) == false then
 					perror("Base register `" .. gettokenkey(op) .. 
 						"` can only be applied + or - on it line " .. op.line)
-				elseif #ret.memblock.regs == 1 and typematch(pre, { "+", "-", "*" }) == false then
+				elseif #ret.memblock.regs == 1 and typematch(pre, { "+", "-", "*", "(", "[" }) == false then
 					perror("Index register `" .. gettokenkey(op) .. 
 						"` can only be applied +, - or * on it line " .. op.line)
 				end
 				table.insert(ret.memblock.regs, gettokenkey(op))
+				table.insert(expr, gettokenkey(op))
 
 			elseif typematch(op, { "hexadecimal", "integer" }) then
 				if typematch(pre, { "[", arithmetics }) == false then
 					perror("missing arithmetic/paranthesis prefix for whole number " .. op.raw ..
 						" line " .. op.line)
 				end
+
+				if op.type == tk_type["hexadecimal"] then
+					table.insert(expr, tostring(hexval(op.raw)))
+				elseif op.type == tk_type["integer"] then
+					table.insert(expr, tostring(intval(op.raw)))
+				end
+
 			-- Other arithmetic symbols
 			elseif isarithmetic(op) == true then
-				if typematch(pre, { regs8, "hexadecimal", "integer" }) == false then
+				if typematch(pre, { regs8, "hexadecimal", "integer", ")" }) == false then
 					perror("illegal token before " .. gettokenkey(op) .. " at line " .. op.line)
 				end
+
+				if #ret.memblock.regs == 1 and typematch(pre, { regs8 }) == true and typematch(op, { "+", "-" } ) == false then
+					perror("Base register `" .. gettokenkey(pre) .. 
+						"` can only be applied + or - on it line " .. op.line)
+				end
+				table.insert(expr, gettokenkey(op))
+
+			elseif op.type == tk_type["("] then
+				if typematch(pre, { regs8, arithmetics, "(", "[" , "hexadecimal", "integer" }) == false then
+					perror("illegal token befor `(` at line " .. op.line)
+				end
+
+				table.insert(expr, "(")
+				depth = depth + 1
+			elseif op.type == tk_type[")"] then
+				if typematch(pre, { regs8, "hexadecimal", ")", "integer" }) == false then
+					perror("illegal token before `)` at line " .. op.line)
+				end
+
+				table.insert(expr, ")")
+				depth = depth - 1
 			else
 				perror("illegal token " .. gettokenkey(op) .. " at line " .. op.line)
 			end
@@ -166,12 +196,34 @@ local function operlyze(op, ret)
 			end
 		end
 
+		if depth ~= 0 then
+			perror("Mismatching paranthesis at line " .. op.line)
+		end
+
 		if op.type ~= tk_type["]"] then
 			perror("Missing closing `]` at line " .. op.line)
 		end
 
+		local e = evaluate_expression(expr)
+		--[[
+		for _,v in ipairs(e) do
+			if type(v) == "string" then
+				io.write(v, " ")
+			else
+				io.write("{")
+				io.write(v[1], ", ")
+				io.write(v[2], "")
+				io.write("} ")
+			end
+		end
+		io.write("\n")
+		io.write("\n")
+		]]--
+
+		ret.memblock.expression = e
 		table.insert(ret.details, ASM_MEM8)
 		ret.opcount = 1
+
 	elseif op.type == tk_type["\n"] then
 		ret.opcount = 0
 	else
@@ -190,6 +242,7 @@ local function asmlyze(first)
 				regs = { },
 				dispsize = 0,
 				blevel = 0,
+				expression = nil
 			}
 		}
 
@@ -259,6 +312,7 @@ local function instvaluate(inst)
 		return ret
 	elseif opcount == 1 then
 	-- amslyze caps it at 2
+		return ret
 	else
 		if inst.details[1] == ASM_R8 and inst.details[2] == ASM_R8 then
 			local dstmap = regmap[gettokenkey(inst.operands[1])]
@@ -277,6 +331,8 @@ local function instvaluate(inst)
 		-- 10 memory 32 bit displacement
 		-- 11 register to register
 		elseif inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8 then
+			local mod = "00"
+
 			return ret
 		end
 	end
@@ -404,6 +460,25 @@ while true do
 
 					elseif hdr.type == tk_type["cli"] then
 						writeu8(dst, hexval("0hFA"))
+
+					elseif hdr.type == tk_type["int"] then
+						local opcount = #inst.details
+
+						if opcount ~= 1 then
+							perror("int takes 1 operand at line " .. hdr.line)
+						end
+
+						if inst.details[1] ~= ASM_IMM8 then
+							perror("int requires an immediate 8 byte value")
+						end
+
+						writeu8(dst, hexval("0hCD"))
+
+						if inst.operands[1].type == tk_type["hexadecimal"] then
+							writeu8(dst, hexval(inst.operands[1].raw))
+						elseif inst.operands[1].type == tk_type["integer"] then
+							writeu8(dst, intval(inst.operands[1].raw))
+						end
 					end
 				end
 			end
blob - ae98f98922a5a8d6611cabb8da4d82c4cefa68c7
blob + fb968cda91cacb539c610a579f1f4f914ebc3164
--- tools/util.lua
+++ tools/util.lua
@@ -1,7 +1,7 @@
 -----------------------------------------------------------------------
 -- TOKEN MATCHING
 -----------------------------------------------------------------------
-local mnemonics = { "mov", "cli", "hlt", "ret", "sti" }
+local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int" }
 
 -- This is kinda a double definition but fix later :^)
 local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" }
@@ -206,6 +206,9 @@ local function intval(intstr)
 
 	for i = 1, len do
 		local s = intstr:sub(len - i + 1, len - i + 1)
+		if s:match("[0-9]") == false then
+			return nil
+		end
 		s = s * (10 ^ (i - 1))
 		res = res + s
 	end
@@ -253,3 +256,175 @@ function bitval(b)
 
 	return result
 end
+
+
+-----------------------------------------------------------------------
+-- EXPRESSION SOLVING
+-----------------------------------------------------------------------
+
+local function subarray(array, start, last)
+	if last == nil then
+		last = #array
+	end
+
+	local sub = { }
+
+	for i, v in ipairs(array) do
+		if i >= start and i <= last then
+			table.insert(sub, array[i])
+		end
+	end
+
+	return sub
+end
+
+local function finddepth(array, spos)
+	local epos = nil
+	local depth = 1
+
+	for j = spos, #array do
+		if array[j] == "(" then depth = depth + 1 end
+		if array[j] == ")" then depth = depth - 1 end
+
+		if depth == 0 then
+			epos = j
+			break
+		end
+	end
+
+	if depth ~= 0 then
+		perror("invalid nesting")
+	end
+
+	if epos == nil then perror("Mismatched paranthesis") end
+
+	return epos
+end
+
+-- Use this once the syntax validation is completed
+local function evaluate_expression(array)
+	local i = 1
+	local eval = { }
+	while i <= #array do
+		if array[i] == "(" then
+			local spos = i
+			local epos = finddepth(array, spos + 1)
+
+			local sub = { }
+			for k = spos + 1, epos - 1 do
+				table.insert(sub, array[k])
+			end
+
+			local result = evaluate_expression(sub)
+
+			for _, val in ipairs(result) do
+				table.insert(eval, val)
+			end
+
+			i = epos + 1
+		elseif array[i] == "*" then
+			local left = table.remove(eval)
+			local right = array[i + 1]
+			local epos = i + 2
+
+			if right == "(" then
+				local sub = subarray(array, i + 1)
+				right = evaluate_expression(sub)[1]
+				epos = finddepth(array, i + 2) + 1
+			end
+
+			if type(left) == "string" and type(right) == "string" then
+				if tonumber(left) ~= nil and tonumber(right) ~= nil then
+					table.insert(eval, tostring(tonumber(left) * tonumber(right)))
+
+				elseif tonumber(left) == nil and tonumber(right) ~= nil then
+					table.insert(eval, { left, tonumber(right) })
+
+				elseif tonumber(left) ~= nil and tonumber(right) == nil then
+					table.insert(eval, { right, tonumber(left) })
+
+				end
+			elseif type(left) == "table" and type(right) == "string" then
+				if tonumber(right) ~= nil then
+					table.insert(eval, { left[1], left[2] * tonumber(right) })
+				end
+			end
+
+			i = epos
+		else
+			table.insert(eval, array[i])
+			i = i + 1
+		end
+	end
+
+	local k = 1
+	local total = 0
+	local final = {}
+
+	while k < #eval do
+		local cur = eval[k]
+		local opr = eval[k + 1]
+		local nxt = eval[k + 2]
+
+		local n1 = tonumber(cur)
+		local n2 = tonumber(nxt)
+
+		if n1 ~= nil then
+			total = n1 + total
+			k = k + 1
+		elseif cur == "+" or cur == "-" then
+			if tonumber(opr) ~= nil then
+				if cur == "+" then
+					total = tonumber(opr) + total
+				elseif cur == "-" then
+					total = total - tonumber(opr)
+				end
+
+				k = k + 2
+			else
+				if type(opr) == "string" then
+					table.insert(final, {opr, 1})
+				else
+					table.insert(final, opr)
+				end
+				k = k + 2
+			end
+
+		elseif type(cur) == "string" and n2 ~= nil then
+			table.insert(final, { cur, 1 })
+			total = total + n2
+			k = k + 3
+
+		elseif type(cur) == "table" and n2 ~= nil then
+			table.insert(final, cur)
+			if opr == "-" then
+				total = total - n2
+			else
+				total = total + n2
+			end
+			k = k + 3
+
+		elseif type(cur) == "table" and type(nxt) == "string" then
+			k = k + 3
+
+		elseif type(cur) == "string" and type(nxt) == "string" then
+			table.insert(final, { cur, 1 })
+			table.insert(final, { nxt, 1 })
+			k = k + 3
+
+		elseif type(cur) == "string" and type(nxt) == "table" then
+			table.insert(final, { cur, 1 })
+			table.insert(final, nxt)
+			k = k + 3
+
+		else
+			k = k + 3
+		end
+	end
+
+	if total ~= 0 then
+		table.insert(final, tostring(total))
+	end
+
+	return final
+end