summaryrefslogtreecommitdiffhomepage
path: root/dev/LibCompiler/src/Detail/AsmUtils.h
blob: 4d3e19c2173c1f2e4001ac8cf9e0220bfefc1f49 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/* -------------------------------------------

	Copyright (C) 2024 Amlal EL Mahrouss, all rights reserved

------------------------------------------- */

#pragma once

#include <LibCompiler/AAL/AssemblyInterface.h>
#include <LibCompiler/Parser.h>

using namespace LibCompiler;

namespace Detail
{
	extern void print_error(std::string reason, std::string file) noexcept;
	extern void print_warning(std::string reason, std::string file) noexcept;
} // namespace Detail

/// @brief Get Number from lineBuffer.
/// @param lineBuffer the lineBuffer to fetch from.
/// @param numberKey where to seek that number.
/// @return
static NumberCast32 GetNumber32(std::string lineBuffer, std::string numberKey)
{
	auto pos = lineBuffer.find(numberKey) + numberKey.size();

	while (lineBuffer[pos] == ' ')
	{
		++pos;
	}

	switch (lineBuffer[pos + 1])
	{
	case 'x': {
		if (auto res = strtol(lineBuffer.substr(pos).c_str(), nullptr, 16); !res)
		{
			if (errno != 0)
			{
				Detail::print_error("invalid hex number: " + lineBuffer, "LibCompiler");
				throw std::runtime_error("invalid_hex");
			}
		}

		NumberCast32 numOffset(strtol(lineBuffer.substr(pos).c_str(), nullptr, 16));

		if (kVerbose)
		{
			kStdOut << "asm: found a base 16 number here: " << lineBuffer.substr(pos)
					<< "\n";
		}

		return numOffset;
	}
	case 'b': {
		if (auto res = strtol(lineBuffer.substr(pos).c_str(), nullptr, 2); !res)
		{
			if (errno != 0)
			{
				Detail::print_error("invalid binary number:" + lineBuffer, "LibCompiler");
				throw std::runtime_error("invalid_bin");
			}
		}

		NumberCast32 numOffset(strtol(lineBuffer.substr(pos).c_str(), nullptr, 2));

		if (kVerbose)
		{
			kStdOut << "asm: found a base 2 number here:" << lineBuffer.substr(pos)
					<< "\n";
		}

		return numOffset;
	}
	case 'o': {
		if (auto res = strtol(lineBuffer.substr(pos).c_str(), nullptr, 7); !res)
		{
			if (errno != 0)
			{
				Detail::print_error("invalid octal number: " + lineBuffer, "LibCompiler");
				throw std::runtime_error("invalid_octal");
			}
		}

		NumberCast32 numOffset(strtol(lineBuffer.substr(pos).c_str(), nullptr, 7));

		if (kVerbose)
		{
			kStdOut << "asm: found a base 8 number here:" << lineBuffer.substr(pos)
					<< "\n";
		}

		return numOffset;
	}
	default: {
		if (auto res = strtol(lineBuffer.substr(pos).c_str(), nullptr, 10); !res)
		{
			if (errno != 0)
			{
				Detail::print_error("invalid hex number: " + lineBuffer, "LibCompiler");
				throw std::runtime_error("invalid_hex");
			}
		}

		NumberCast32 numOffset(strtol(lineBuffer.substr(pos).c_str(), nullptr, 10));

		if (kVerbose)
		{
			kStdOut << "asm: found a base 10 number here:" << lineBuffer.substr(pos)
					<< "\n";
		}

		return numOffset;
	}
	}
}