Scripting Languages

April 19, 2026 · View on GitHub

Python, Ruby, PHP, Lua, R, and Bash support in Sitting Duck.

Language Nuances

Extraction Quality Summary

LanguageFunctionsClassesCallsVariablesBody DetectionOverall
Python⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐Good
Ruby⭐⭐⭐⭐⭐⭐⭐⭐⭐Good
PHP⭐⭐⭐⭐⭐⭐⭐⭐⭐Good
Lua⭐⭐⭐Needs Work
R⭐⭐⭐⭐⭐⭐Basic
Bash⭐⭐N/A⭐⭐⭐⭐⭐Basic

Implementation Notes

  • Python Classes: Excellent class extraction including inheritance detection and abstract class identification (ABC subclasses).
  • Ruby Bodies: Uses body_statement for method bodies - correctly detects all method implementations.
  • PHP Keywords: The function keyword is marked as IS_SYNTAX_ONLY to avoid counting it as a function definition.
  • R Lambdas: Lambda expressions use braced_expression bodies with ~84% detection accuracy.

Known Limitations

  • Python Type Hints: Type hints are parsed but not fully extracted into signature_type.
  • Ruby Blocks: Block parameters (do |x|) are parsed but parameter extraction is limited.
  • PHP Closures: Anonymous functions (function() use ($var)) are detected but captured variables not extracted.
  • Lua Parameters: Function parameters show as empty array [] - needs native extractor implementation.
  • R Functions: Dynamic typing means no type information available; variable extraction is minimal.
  • Bash: No class support (N/A); function and variable extraction is basic.

Body Detection Details

LanguageBody TypeAccuracyNotes
Pythonblock⭐⭐⭐Indentation-based blocks work correctly
Rubybody_statement⭐⭐⭐Fixed in recent update
PHPcompound_statement⭐⭐⭐function keyword properly excluded
Luablock⭐⭐⭐Works correctly
Rbraced_expression⭐⭐~84% accuracy for lambdas
Bashcompound_statement⭐⭐⭐Works correctly

Python

Extensions: .py Identifier: 'python'

Common Node Types

TypeSemantic TypeDescription
function_definitionDEFINITION_FUNCTIONFunctions
async_function_definitionDEFINITION_FUNCTIONAsync functions
class_definitionDEFINITION_CLASSClasses
decorated_definitionMETADATA_ANNOTATIONDecorated items
import_statementEXTERNAL_IMPORTImports
import_from_statementEXTERNAL_IMPORTFrom imports

Examples

-- Find all functions
SELECT name, start_line
FROM read_ast('**/*.py')
WHERE type = 'function_definition';

-- Find decorated functions
SELECT name, peek
FROM read_ast('**/*.py')
WHERE type = 'function_definition'
  AND parent_id IN (SELECT node_id FROM read_ast('**/*.py') WHERE type = 'decorated_definition');

-- Find class methods
SELECT c.name as class_name, f.name as method_name
FROM read_ast('test/data/python/sample_app.py') c
JOIN read_ast('test/data/python/sample_app.py') f ON f.parent_id = c.node_id
WHERE c.type = 'class_definition'
  AND f.type = 'function_definition';

Ruby

Extensions: .rb Identifier: 'ruby'

Common Node Types

TypeSemantic TypeDescription
methodDEFINITION_FUNCTIONMethods
classDEFINITION_CLASSClasses
moduleDEFINITION_MODULEModules
callCOMPUTATION_CALLMethod calls

Examples

-- Find methods
SELECT name, start_line
FROM read_ast('**/*.rb')
WHERE type = 'method';

-- Find classes
SELECT name
FROM read_ast('**/*.rb')
WHERE type = 'class';

-- Find modules
SELECT name
FROM read_ast('**/*.rb')
WHERE type = 'module';

PHP

Extensions: .php Identifier: 'php'

Common Node Types

TypeSemantic TypeDescription
function_definitionDEFINITION_FUNCTIONFunctions
method_declarationDEFINITION_FUNCTIONMethods
class_declarationDEFINITION_CLASSClasses
interface_declarationDEFINITION_CLASSInterfaces
namespace_definitionDEFINITION_MODULENamespaces

Examples

-- Find classes
SELECT name, start_line
FROM read_ast('**/*.php')
WHERE type = 'class_declaration';

-- Find methods
SELECT name
FROM read_ast('**/*.php')
WHERE type = 'method_declaration';

-- Find namespaces
SELECT peek
FROM read_ast('**/*.php')
WHERE type = 'namespace_definition';

Lua

Extensions: .lua Identifier: 'lua'

Common Node Types

TypeSemantic TypeDescription
function_declarationDEFINITION_FUNCTIONFunctions
local_functionDEFINITION_FUNCTIONLocal functions
variable_declarationDEFINITION_VARIABLEVariables
function_callCOMPUTATION_CALLCalls

Examples

-- Find functions
SELECT name, start_line
FROM read_ast('**/*.lua')
WHERE type IN ('function_declaration', 'local_function');

-- Find local variables
SELECT name
FROM read_ast('**/*.lua')
WHERE type = 'variable_declaration';

R

Extensions: .r, .R Identifier: 'r'

Common Node Types

TypeSemantic TypeDescription
function_definitionDEFINITION_FUNCTIONFunctions
left_assignmentDEFINITION_VARIABLEAssignments
callCOMPUTATION_CALLFunction calls

Examples

-- Find function definitions
SELECT name, start_line
FROM read_ast('**/*.R')
WHERE type = 'function_definition';

-- Find variable assignments
SELECT peek
FROM read_ast('analysis.R')
WHERE type = 'left_assignment';

Bash

Extensions: .sh, .bash Identifier: 'bash'

Common Node Types

TypeSemantic TypeDescription
function_definitionDEFINITION_FUNCTIONFunctions
variable_assignmentDEFINITION_VARIABLEAssignments
commandCOMPUTATION_CALLCommands
if_statementFLOW_CONDITIONALIf statements
for_statementFLOW_LOOPFor loops

Examples

-- Find functions
SELECT name, start_line
FROM read_ast('**/*.sh')
WHERE type = 'function_definition';

-- Find variable assignments
SELECT peek
FROM read_ast('script.sh')
WHERE type = 'variable_assignment';

-- Find commands
SELECT peek
FROM read_ast('script.sh')
WHERE type = 'command';

Cross-Scripting Analysis

-- Compare scripting language patterns
SELECT
    language,
    COUNT(CASE WHEN semantic_type = 'DEFINITION_FUNCTION' THEN 1 END) as functions,
    COUNT(CASE WHEN semantic_type = 'DEFINITION_VARIABLE' THEN 1 END) as variables,
    COUNT(*) as total_nodes
FROM read_ast(['**/*.py', '**/*.rb', '**/*.php', '**/*.lua'], ignore_errors := true)
GROUP BY language
ORDER BY total_nodes DESC;