Long time no see
This commit is contained in:
Executable
+373
@@ -0,0 +1,373 @@
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include <locale.h>
|
||||
|
||||
#define MAXINPUTARRAY 1000
|
||||
#define MAXKNOWN 30
|
||||
#define MAXKNOWNSYMB 32
|
||||
#define MAXROW 80
|
||||
#define CMDLIST 4
|
||||
|
||||
// --- GLOBAL DATA ---
|
||||
wchar_t G_knownint[MAXKNOWN][MAXKNOWNSYMB] = {0};
|
||||
int G_knownCount = 0;
|
||||
|
||||
// --- FUNCTION DECLARATIONS ---
|
||||
int it_is_what(wchar_t ch);
|
||||
int are_strings_equal(const wchar_t *s1, const wchar_t *s2);
|
||||
int is_variable_known(const wchar_t *name);
|
||||
void put_wchar_string(const wchar_t *s);
|
||||
void put_char_string(const char *s);
|
||||
|
||||
|
||||
// --- MAIN TRANSLATOR LOGIC ---
|
||||
int main() {
|
||||
setlocale(LC_ALL, "");
|
||||
|
||||
wchar_t massive[MAXINPUTARRAY] = {0};
|
||||
int CellsInMainArray = 0;
|
||||
|
||||
{ // GET INPUT
|
||||
wchar_t ch;
|
||||
while ((ch = getwchar()) != WEOF) {
|
||||
if (CellsInMainArray >= MAXINPUTARRAY) { return 1001; }
|
||||
massive[CellsInMainArray++] = ch;
|
||||
}
|
||||
}
|
||||
|
||||
{ // PRE-SCAN: DECLARE ALL VARIABLES AS INT
|
||||
put_char_string("#include <stdio.h>\n");
|
||||
put_char_string("int main(){\n");
|
||||
|
||||
int k = 0;
|
||||
while (k < CellsInMainArray) {
|
||||
if (it_is_what(massive[k]) == 0 || it_is_what(massive[k]) == 1) {
|
||||
wchar_t tempName[MAXKNOWNSYMB] = {0};
|
||||
int len = 0;
|
||||
int startK = k;
|
||||
|
||||
{ // EXTRACT NAME
|
||||
while (startK < CellsInMainArray && (it_is_what(massive[startK]) >= 0)) {
|
||||
if (len < MAXKNOWNSYMB - 1) tempName[len++] = massive[startK];
|
||||
startK++;
|
||||
}
|
||||
}
|
||||
|
||||
{ // CHECK KEYWORDS AND DECLARE
|
||||
int isKeyword = 0;
|
||||
if (are_strings_equal(tempName, L"if") || are_strings_equal(tempName, L"while") ||
|
||||
are_strings_equal(tempName, L"for") || are_strings_equal(tempName, L"print") ||
|
||||
are_strings_equal(tempName, L"in") || are_strings_equal(tempName, L"range") ||
|
||||
are_strings_equal(tempName, L"int") || are_strings_equal(tempName, L"input")) isKeyword = 1;
|
||||
|
||||
if (!isKeyword && tempName[0] != L'\0') {
|
||||
if (!is_variable_known(tempName) && G_knownCount < MAXKNOWN) {
|
||||
for (int c = 0; c < len; c++) G_knownint[G_knownCount][c] = tempName[c];
|
||||
G_knownCount++;
|
||||
|
||||
// DECLARE VARIABLE
|
||||
put_char_string("int ");
|
||||
put_wchar_string(tempName);
|
||||
put_char_string(" = 0;\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
k = startK;
|
||||
} else {
|
||||
k++;
|
||||
}
|
||||
}
|
||||
putwchar(L'\n');
|
||||
}
|
||||
|
||||
// --- SECOND PASS: LEXICAL ANALYSIS AND TRANSLATION ---
|
||||
int massiveCursor = 0;
|
||||
wchar_t row[MAXROW] = {0};
|
||||
int deathMark = 1;
|
||||
int blockLevel = 0;
|
||||
|
||||
do {
|
||||
if (massiveCursor >= CellsInMainArray) break;
|
||||
|
||||
int command = 0;
|
||||
int rowCursor = 0;
|
||||
int initialSpaceCount = 0;
|
||||
|
||||
{ // GET ROW AND INDENTATION
|
||||
for (int i = 0; i < MAXROW; i++) row[i] = 0;
|
||||
rowCursor = 0;
|
||||
|
||||
while (massiveCursor < CellsInMainArray && rowCursor < MAXROW - 1) {
|
||||
wchar_t cur = massive[massiveCursor];
|
||||
if (cur == L'\n') { massiveCursor++; break; }
|
||||
if (cur == WEOF || massiveCursor == CellsInMainArray - 1) { deathMark = 0; }
|
||||
row[rowCursor++] = cur;
|
||||
massiveCursor++;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
while (row[i] == L' ' || row[i] == L'\t') { initialSpaceCount++; i++; }
|
||||
|
||||
// CLOSE BLOCK
|
||||
if (blockLevel == 1 && initialSpaceCount == 0 && rowCursor > 0) {
|
||||
put_char_string("}\n");
|
||||
blockLevel = 0;
|
||||
}
|
||||
|
||||
// PRINT INDENTATION
|
||||
for (int j = 0; j < initialSpaceCount; j++) putwchar(L' ');
|
||||
|
||||
// TRIM ROW
|
||||
if (initialSpaceCount > 0) {
|
||||
for (int j = 0; j < rowCursor - initialSpaceCount; j++) {
|
||||
row[j] = row[j + initialSpaceCount];
|
||||
}
|
||||
rowCursor -= initialSpaceCount;
|
||||
for (int j = rowCursor; j < MAXROW; j++) row[j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
{ // HANDLE PYTHON COMMENTS (#)
|
||||
int hashPos = -1;
|
||||
for (int i = 0; i < rowCursor; i++) {
|
||||
if (row[i] == L'#') { hashPos = i; break; }
|
||||
}
|
||||
if (hashPos != -1) {
|
||||
put_char_string("//");
|
||||
for (int k = 0; k < rowCursor; k++) {
|
||||
if (row[k] == L'#') break;
|
||||
putwchar(row[k]);
|
||||
}
|
||||
for (int k = hashPos + 1; k < rowCursor; k++) putwchar(row[k]);
|
||||
putwchar(L'\n');
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// SKIP EMPTY LINES
|
||||
if (rowCursor == 0) {
|
||||
putwchar(L'\n');
|
||||
continue;
|
||||
}
|
||||
|
||||
{ // DETERMINE COMMAND TYPE
|
||||
wchar_t cmd_list[CMDLIST][10] = {L"if", L"while", L"for", L"print"};
|
||||
for (int i = 0; i < CMDLIST; i++) {
|
||||
int lenCmd = 0;
|
||||
while (cmd_list[i][lenCmd] != L'\0') lenCmd++;
|
||||
|
||||
if (rowCursor >= lenCmd) {
|
||||
int match = 1;
|
||||
for (int k = 0; k < lenCmd; k++) {
|
||||
if (row[k] != cmd_list[i][k]) { match = 0; break; }
|
||||
}
|
||||
|
||||
if (match) {
|
||||
int pos = lenCmd;
|
||||
while(row[pos] == L' ') pos++;
|
||||
|
||||
if (i == 3) { // PRINT
|
||||
if (row[pos] == L'(') { command = 4; break; }
|
||||
} else { // IF, WHILE, FOR
|
||||
int colonPos = -1;
|
||||
for (int p = pos; p < rowCursor; p++) {
|
||||
if (row[p] == L':') { colonPos = p; break; }
|
||||
}
|
||||
if (colonPos != -1) { command = i + 1; break; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{ // HANDLE ASSIGNMENT / OPERATION (command == 0)
|
||||
if (command == 0) {
|
||||
int eqPos = -1;
|
||||
int plusEqPos = -1;
|
||||
int varNameEnd = -1;
|
||||
|
||||
for (int i = 0; i < rowCursor; i++) {
|
||||
if (row[i] == L'=') {
|
||||
eqPos = i;
|
||||
if (i > 0 && row[i - 1] == L'+') plusEqPos = i;
|
||||
varNameEnd = i - 1;
|
||||
while(varNameEnd >= 0 && row[varNameEnd] == L' ') varNameEnd--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If assignment found and not comparison
|
||||
if (eqPos > 0 && row[eqPos + 1] != L'=' && plusEqPos == -1) {
|
||||
|
||||
// 1. Check for input pattern
|
||||
wchar_t inputPattern[] = L"int(input())";
|
||||
int isInput = 1;
|
||||
int checkIdx = 0;
|
||||
int valPos = eqPos + 1;
|
||||
while (row[valPos] == L' ') valPos++;
|
||||
|
||||
while (inputPattern[checkIdx] != L'\0') {
|
||||
if (row[valPos + checkIdx] != inputPattern[checkIdx]) { isInput = 0; break; }
|
||||
checkIdx++;
|
||||
}
|
||||
|
||||
if (isInput) {
|
||||
// INPUT (scanf)
|
||||
put_char_string("scanf(\"%d\", &");
|
||||
for (int j = 0; j <= varNameEnd; j++) putwchar(row[j]);
|
||||
put_char_string(");\n");
|
||||
} else {
|
||||
// REGULAR ASSIGNMENT (x = -5, x = a + 1)
|
||||
for (int i = 0; i < rowCursor; i++) { putwchar(row[i]); }
|
||||
put_char_string(";\n");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Augmented Assignment (x += 1) or other unknown lines
|
||||
for (int i = 0; i < rowCursor; i++) { putwchar(row[i]); }
|
||||
put_char_string(";\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
{ // TRANSLATE COMMAND (switch)
|
||||
switch (command) {
|
||||
case 1: // IF
|
||||
case 2: // WHILE
|
||||
case 3: { // FOR
|
||||
wchar_t *start_word;
|
||||
int len_cmd;
|
||||
if (command == 1) { start_word = L"if("; len_cmd = 2; }
|
||||
else if (command == 2) { start_word = L"while("; len_cmd = 5; }
|
||||
else { start_word = L"for("; len_cmd = 3; }
|
||||
|
||||
put_wchar_string(start_word);
|
||||
int pos = len_cmd;
|
||||
while (row[pos] == L' ') pos++;
|
||||
|
||||
if (command == 3) { // FOR (i in range(10))
|
||||
wchar_t iterVar[MAXKNOWNSYMB] = {0};
|
||||
int ivLen = 0;
|
||||
|
||||
// GET ITERATOR NAME
|
||||
while (row[pos] != L' ' && row[pos] != L'\0' && pos < rowCursor && row[pos] != L':') {
|
||||
iterVar[ivLen++] = row[pos];
|
||||
pos++;
|
||||
}
|
||||
// SKIP 'in range'
|
||||
while (pos < rowCursor && row[pos] != L'(') pos++;
|
||||
pos++;
|
||||
|
||||
// C FORMAT: for(i = 0; i < limit; i++)
|
||||
put_wchar_string(iterVar); put_char_string(" = 0;");
|
||||
put_wchar_string(iterVar); put_char_string(" < ");
|
||||
|
||||
// GET LIMIT
|
||||
while (pos < rowCursor && row[pos] != L')' && row[pos] != L':') { putwchar(row[pos++]); }
|
||||
|
||||
put_char_string(";");
|
||||
put_wchar_string(iterVar); put_char_string("++");
|
||||
|
||||
} else {
|
||||
// IF / WHILE CONDITION (Handling x >= y conditions)
|
||||
while (pos < rowCursor && row[pos] != L':') {
|
||||
if (row[pos] == L'>' && row[pos+1] == L'=') {
|
||||
put_char_string(" >= ");
|
||||
pos += 2;
|
||||
} else if (row[pos] == L'<' && row[pos+1] == L'=') {
|
||||
put_char_string(" <= ");
|
||||
pos += 2;
|
||||
} else if (row[pos] == L'!' && row[pos+1] == L'=') {
|
||||
put_char_string(" != ");
|
||||
pos += 2;
|
||||
} else if (row[pos] == L'=' && row[pos+1] == L'=') {
|
||||
put_char_string(" == ");
|
||||
pos += 2;
|
||||
} else {
|
||||
putwchar(row[pos++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
put_char_string(")\n");
|
||||
|
||||
// OPEN BLOCK
|
||||
put_char_string("{\n");
|
||||
blockLevel = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: { // PRINT (print(x) or print("hello"))
|
||||
put_char_string("printf(");
|
||||
int pos = 5;
|
||||
while (row[pos] != L'(') pos++;
|
||||
pos++;
|
||||
|
||||
int isString = (row[pos] == L'\"');
|
||||
|
||||
if (isString) {
|
||||
putwchar(L'\"');
|
||||
pos++;
|
||||
while (pos < rowCursor && row[pos] != L')') {
|
||||
if (row[pos] == L'\"' && isString) break;
|
||||
putwchar(row[pos++]);
|
||||
}
|
||||
putwchar(L'\"');
|
||||
} else {
|
||||
put_char_string("\"%d\", ");
|
||||
while (pos < rowCursor && row[pos] != L')') {
|
||||
putwchar(row[pos++]);
|
||||
}
|
||||
}
|
||||
put_char_string(");\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (deathMark);
|
||||
|
||||
{ // FINAL BRACKETS
|
||||
if (blockLevel == 1) {
|
||||
put_char_string("}\n");
|
||||
}
|
||||
put_char_string("}\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// --- AUXILIARY FUNCTION DEFINITIONS ---
|
||||
void put_wchar_string(const wchar_t *s) {
|
||||
int i = 0;
|
||||
while (s[i] != L'\0') { putwchar(s[i++]); }
|
||||
}
|
||||
void put_char_string(const char *s) {
|
||||
int i = 0;
|
||||
while (s[i] != '\0') { putwchar(s[i++]); }
|
||||
}
|
||||
int it_is_what(wchar_t ch) {
|
||||
if (ch >= L'a' && ch <= L'z') return 0;
|
||||
if (ch >= L'A' && ch <= L'Z') return 1;
|
||||
if (ch >= L'0' && ch <= L'9') return 2;
|
||||
if (ch == L'_') return 3;
|
||||
return -1;
|
||||
}
|
||||
int are_strings_equal(const wchar_t *s1, const wchar_t *s2) {
|
||||
int i = 0;
|
||||
while (s1[i] != L'\0' || s2[i] != L'\0') {
|
||||
if (s1[i] != s2[i]) return 0;
|
||||
i++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
int is_variable_known(const wchar_t *name) {
|
||||
if (name[0] == L'\0') return 1;
|
||||
for (int r = 0; r < G_knownCount; r++) {
|
||||
if (are_strings_equal(G_knownint[r], name)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user