Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local Pawn = {}
- -- Pawn token types
- local TokenType = {
- KEYWORD = 1,
- IDENTIFIER = 2,
- NUMBER = 3,
- STRING = 4,
- OPERATOR = 5,
- PREPROCESSOR = 6,
- COMMENT = 7
- }
- -- Pawn keywords
- local KEYWORDS = {
- "new", "enum", "public", "stock", "static", "const", "forward",
- "native", "if", "else", "for", "while", "do", "switch", "case",
- "default", "return", "break", "continue", "sizeof", "state",
- "goto", "tagof", "char", "bool", "int", "float", "void"
- }
- -- Preprocessor directives
- local PREPROCESSOR_DIRECTIVES = {
- "#define", "#include", "#if", "#else", "#endif", "#ifdef", "#ifndef",
- "#pragma", "#error", "#warning"
- }
- function Pawn.tokenize(code)
- local tokens = {}
- local pos = 1
- local len = #code
- while pos <= len do
- local char = code:sub(pos, pos)
- -- Skip whitespace
- if char:match("%s") then
- pos = pos + 1
- -- Comments
- elseif char == "/" and code:sub(pos + 1, pos + 1) == "/" then
- local start = pos
- while pos <= len and code:sub(pos, pos) ~= "\n" do
- pos = pos + 1
- end
- table.insert(tokens, {
- type = TokenType.COMMENT,
- value = code:sub(start, pos - 1)
- })
- -- Multi-line comments
- elseif char == "/" and code:sub(pos + 1, pos + 1) == "*" then
- local start = pos
- pos = pos + 2
- while pos <= len and not (code:sub(pos, pos) == "*" and code:sub(pos + 1, pos + 1) == "/") do
- pos = pos + 1
- end
- pos = pos + 2
- table.insert(tokens, {
- type = TokenType.COMMENT,
- value = code:sub(start, pos - 1)
- })
- -- Preprocessor directives
- elseif char == "#" then
- local start = pos
- while pos <= len and not code:sub(pos, pos):match("%s") and code:sub(pos, pos) ~= "\n" do
- pos = pos + 1
- end
- local directive = code:sub(start, pos - 1)
- table.insert(tokens, {
- type = TokenType.PREPROCESSOR,
- value = directive
- })
- -- Strings
- elseif char == '"' then
- local start = pos
- pos = pos + 1
- while pos <= len and code:sub(pos, pos) ~= '"' do
- if code:sub(pos, pos) == "\\" then
- pos = pos + 1 -- Skip escape sequences
- end
- pos = pos + 1
- end
- pos = pos + 1
- table.insert(tokens, {
- type = TokenType.STRING,
- value = code:sub(start, pos - 1)
- })
- -- Numbers
- elseif char:match("%d") or (char == "." and code:sub(pos + 1, pos + 1):match("%d")) then
- local start = pos
- while pos <= len and (code:sub(pos, pos):match("%d") or code:sub(pos, pos) == "." or code:sub(pos, pos):match("[eE]") or (code:sub(pos, pos) == "-" and code:sub(pos - 1, pos - 1):match("[eE]"))) do
- pos = pos + 1
- end
- table.insert(tokens, {
- type = TokenType.NUMBER,
- value = code:sub(start, pos - 1)
- })
- -- Identifiers and keywords
- elseif char:match("[%a_]") then
- local start = pos
- while pos <= len and code:sub(pos, pos):match("[%w_]") do
- pos = pos + 1
- end
- local identifier = code:sub(start, pos - 1)
- local isKeyword = false
- for _, kw in ipairs(KEYWORDS) do
- if kw == identifier then
- isKeyword = true
- break
- end
- end
- table.insert(tokens, {
- type = isKeyword and TokenType.KEYWORD or TokenType.IDENTIFIER,
- value = identifier
- })
- -- Operators
- else
- local operators = {"++", "--", "+=", "-=", "*=", "/=", "%=", "==", "!=", ">=", "<=", "&&", "||", ">>", "<<"}
- local found = false
- for _, op in ipairs(operators) do
- if code:sub(pos, pos + #op - 1) == op then
- table.insert(tokens, {
- type = TokenType.OPERATOR,
- value = op
- })
- pos = pos + #op
- found = true
- break
- end
- end
- if not found then
- table.insert(tokens, {
- type = TokenType.OPERATOR,
- value = char
- })
- pos = pos + 1
- end
- end
- end
- return tokens
- end
- function Pawn.transpileToLua(pawnCode)
- local tokens = Pawn.tokenize(pawnCode)
- local luaCode = ""
- local i = 1
- while i <= #tokens do
- local token = tokens[i]
- if token.type == TokenType.PREPROCESSOR then
- if token.value == "#define" then
- -- Handle #define MACRO value
- local name = tokens[i + 1] and tokens[i + 1].value or ""
- local value = tokens[i + 2] and tokens[i + 2].value or ""
- if name:match("^[%a_][%w_]*$") then
- luaCode = luaCode .. "local " .. name .. " = " .. value .. "\n"
- i = i + 3
- else
- luaCode = luaCode .. "-- " .. token.value .. "\n"
- i = i + 1
- end
- else
- luaCode = luaCode .. "-- " .. token.value .. "\n"
- i = i + 1
- end
- elseif token.type == TokenType.KEYWORD and token.value == "enum" then
- -- Handle enum
- i = i + 1 -- skip enum
- local enumName = tokens[i].value
- i = i + 2 -- skip name and {
- local enumValues = {}
- local currentValue = 0
- while i <= #tokens and tokens[i].value ~= "}" do
- if tokens[i].type == TokenType.IDENTIFIER then
- local name = tokens[i].value
- i = i + 1
- if tokens[i] and tokens[i].value == "=" then
- i = i + 1
- currentValue = tonumber(tokens[i].value) or 0
- i = i + 1
- end
- table.insert(enumValues, {name = name, value = currentValue})
- currentValue = currentValue + 1
- if tokens[i] and tokens[i].value == "," then
- i = i + 1
- end
- else
- i = i + 1
- end
- end
- i = i + 1 -- skip }
- -- Convert enum to Lua table
- luaCode = luaCode .. "local " .. enumName .. " = {\n"
- for _, ev in ipairs(enumValues) do
- luaCode = luaCode .. " " .. ev.name .. " = " .. ev.value .. ",\n"
- end
- luaCode = luaCode .. "}\n"
- elseif token.type == TokenType.KEYWORD and token.value == "new" then
- -- Handle variable declaration
- i = i + 1 -- skip new
- local varName = tokens[i].value
- i = i + 1
- if tokens[i] and tokens[i].value == "[" then
- -- Array declaration
- i = i + 1
- local size = tokens[i].value
- i = i + 2 -- skip size and ]
- luaCode = luaCode .. "local " .. varName .. " = {}\n"
- luaCode = luaCode .. "for i = 1, " .. size .. " do\n"
- luaCode = luaCode .. " " .. varName .. "[i] = 0\n"
- luaCode = luaCode .. "end\n"
- else
- -- Single variable
- luaCode = luaCode .. "local " .. varName .. " = 0\n"
- end
- else
- -- Direct translation for other tokens
- luaCode = luaCode .. token.value .. " "
- i = i + 1
- end
- end
- return luaCode
- end
- -- Example usage:
- local pawnCode = [[
- #define MAX_PLAYERS 500
- enum pInfo {
- PlayerName[25],
- Kills,
- Level,
- Points
- }
- new PlayerInfo[MAX_PLAYERS][pInfo];
- public OnPlayerConnect(playerid)
- {
- PlayerInfo[playerid][Kills] = 0;
- PlayerInfo[playerid][Level] = 1;
- return 1;
- }
- ]]
- local luaCode = Pawn.transpileToLua(pawnCode)
- print("Transpiled Lua code:")
- print(luaCode)
Advertisement