@@ -1211,12 +1211,263 @@ void executeScript(const std::string &content)
12111211 }
12121212}
12131213
1214+ // ═══════════════════════════════════════════════════════════
1215+ // ──── Minimal JSON Helpers (for kernel mode) ───────────────
1216+ // ═══════════════════════════════════════════════════════════
1217+
1218+ // Minimal JSON value: string→string map parser (for kernel protocol)
1219+ inline std::unordered_map<std::string, std::string> parse_json_object (const std::string &json)
1220+ {
1221+ std::unordered_map<std::string, std::string> result;
1222+ size_t i = json.find (' {' );
1223+ if (i == std::string::npos)
1224+ return result;
1225+ i++;
1226+
1227+ auto skipWS = [&]()
1228+ { while (i < json.size () && std::isspace (json[i])) i++; };
1229+ auto readString = [&]() -> std::string
1230+ {
1231+ skipWS ();
1232+ if (i >= json.size () || json[i] != ' "' )
1233+ return " " ;
1234+ i++; // skip opening "
1235+ std::string s;
1236+ while (i < json.size () && json[i] != ' "' )
1237+ {
1238+ if (json[i] == ' \\ ' && i + 1 < json.size ())
1239+ {
1240+ i++;
1241+ if (json[i] == ' n' )
1242+ s += ' \n ' ;
1243+ else if (json[i] == ' t' )
1244+ s += ' \t ' ;
1245+ else if (json[i] == ' \\ ' )
1246+ s += ' \\ ' ;
1247+ else if (json[i] == ' "' )
1248+ s += ' "' ;
1249+ else if (json[i] == ' /' )
1250+ s += ' /' ;
1251+ else
1252+ s += json[i];
1253+ }
1254+ else
1255+ s += json[i];
1256+ i++;
1257+ }
1258+ if (i < json.size ())
1259+ i++; // skip closing "
1260+ return s;
1261+ };
1262+
1263+ while (i < json.size ())
1264+ {
1265+ skipWS ();
1266+ if (json[i] == ' }' )
1267+ break ;
1268+ if (json[i] == ' ,' )
1269+ {
1270+ i++;
1271+ continue ;
1272+ }
1273+ std::string key = readString ();
1274+ skipWS ();
1275+ if (i < json.size () && json[i] == ' :' )
1276+ i++;
1277+ skipWS ();
1278+ // Value can be string, number, or null
1279+ if (i < json.size () && json[i] == ' "' )
1280+ {
1281+ result[key] = readString ();
1282+ }
1283+ else
1284+ {
1285+ // Read non-string value as raw text until , or }
1286+ std::string val;
1287+ while (i < json.size () && json[i] != ' ,' && json[i] != ' }' )
1288+ val += json[i++];
1289+ // trim
1290+ while (!val.empty () && std::isspace (val.back ()))
1291+ val.pop_back ();
1292+ result[key] = val;
1293+ }
1294+ }
1295+ return result;
1296+ }
1297+
1298+ inline std::string json_escape (const std::string &s)
1299+ {
1300+ std::string out;
1301+ out.reserve (s.size () + 10 );
1302+ for (char c : s)
1303+ {
1304+ switch (c)
1305+ {
1306+ case ' "' :
1307+ out += " \\\" " ;
1308+ break ;
1309+ case ' \\ ' :
1310+ out += " \\\\ " ;
1311+ break ;
1312+ case ' \n ' :
1313+ out += " \\ n" ;
1314+ break ;
1315+ case ' \r ' :
1316+ out += " \\ r" ;
1317+ break ;
1318+ case ' \t ' :
1319+ out += " \\ t" ;
1320+ break ;
1321+ default :
1322+ out += c;
1323+ }
1324+ }
1325+ return out;
1326+ }
1327+
1328+ inline std::string make_json_response (const std::string &cellId, const std::string &status,
1329+ const std::string &stdoutStr, const std::string &stderrStr,
1330+ const std::string &result, int execCount)
1331+ {
1332+ return " {\" cell_id\" :\" " + json_escape (cellId) + " \" ,"
1333+ " \" status\" :\" " +
1334+ json_escape (status) + " \" ,"
1335+ " \" stdout\" :\" " +
1336+ json_escape (stdoutStr) + " \" ,"
1337+ " \" stderr\" :\" " +
1338+ json_escape (stderrStr) + " \" ,"
1339+ " \" result\" :\" " +
1340+ json_escape (result) + " \" ,"
1341+ " \" execution_count\" :" +
1342+ std::to_string (execCount) + " }" ;
1343+ }
1344+
1345+ // ═══════════════════════════════════════════════════════════
1346+ // ──── Kernel Mode ──────────────────────────────────────────
1347+ // ═══════════════════════════════════════════════════════════
1348+
1349+ void runKernel ()
1350+ {
1351+ Scope globalScope;
1352+ globalScope.define (" PI" , var (3.14159265 ));
1353+ globalScope.define (" e" , var (2.7182818 ));
1354+ int executionCount = 0 ;
1355+
1356+ // Signal ready
1357+ std::cout << " {\" status\" :\" kernel_ready\" ,\" version\" :\" 2.0\" }" << std::endl;
1358+ std::cout.flush ();
1359+
1360+ std::string line;
1361+ while (std::getline (std::cin, line))
1362+ {
1363+ if (line.empty ())
1364+ continue ;
1365+
1366+ auto cmd = parse_json_object (line);
1367+ std::string action = cmd[" action" ];
1368+
1369+ if (action == " shutdown" )
1370+ {
1371+ std::cout << " {\" status\" :\" shutdown_ok\" }" << std::endl;
1372+ std::cout.flush ();
1373+ break ;
1374+ }
1375+
1376+ if (action == " reset" )
1377+ {
1378+ globalScope.clear ();
1379+ globalScope.define (" PI" , var (3.14159265 ));
1380+ globalScope.define (" e" , var (2.7182818 ));
1381+ executionCount = 0 ;
1382+ std::cout << " {\" status\" :\" reset_ok\" }" << std::endl;
1383+ std::cout.flush ();
1384+ continue ;
1385+ }
1386+
1387+ if (action == " execute" )
1388+ {
1389+ std::string cellId = cmd[" cell_id" ];
1390+ std::string code = cmd[" code" ];
1391+ executionCount++;
1392+
1393+ // Capture stdout
1394+ std::ostringstream capturedOut;
1395+ std::streambuf *oldBuf = std::cout.rdbuf (capturedOut.rdbuf ());
1396+
1397+ std::string errorStr;
1398+ std::string resultStr;
1399+
1400+ try
1401+ {
1402+ Tokenizer tokenizer;
1403+ auto tokens = tokenizer.tokenize (code);
1404+ Parser parser (tokens);
1405+ auto program = parser.parseProgram ();
1406+
1407+ for (auto &stmt : program->statements )
1408+ stmt->execute (globalScope);
1409+ }
1410+ catch (ReturnException &e)
1411+ {
1412+ resultStr = format_output (e.value );
1413+ }
1414+ catch (std::exception &e)
1415+ {
1416+ errorStr = e.what ();
1417+ }
1418+
1419+ // Restore stdout
1420+ std::cout.rdbuf (oldBuf);
1421+ std::string stdoutStr = capturedOut.str ();
1422+
1423+ std::string status = errorStr.empty () ? " ok" : " error" ;
1424+ std::cout << make_json_response (cellId, status, stdoutStr, errorStr, resultStr, executionCount) << std::endl;
1425+ std::cout.flush ();
1426+ continue ;
1427+ }
1428+
1429+ if (action == " complete" )
1430+ {
1431+ std::string code = cmd[" code" ];
1432+ // Simple completion: list scope variables and builtins that match prefix
1433+ std::vector<std::string> matches;
1434+ for (auto &[name, _] : globalScope.getAll ())
1435+ {
1436+ if (name.find (code) == 0 )
1437+ matches.push_back (name);
1438+ }
1439+ // Return as JSON array
1440+ std::string out = " {\" status\" :\" ok\" ,\" completions\" :[" ;
1441+ for (size_t i = 0 ; i < matches.size (); i++)
1442+ {
1443+ if (i > 0 )
1444+ out += " ," ;
1445+ out += " \" " + json_escape (matches[i]) + " \" " ;
1446+ }
1447+ out += " ]}" ;
1448+ std::cout << out << std::endl;
1449+ std::cout.flush ();
1450+ continue ;
1451+ }
1452+
1453+ // Unknown action
1454+ std::cout << " {\" status\" :\" error\" ,\" stderr\" :\" Unknown action: " + json_escape (action) + " \" }" << std::endl;
1455+ std::cout.flush ();
1456+ }
1457+ }
1458+
12141459// ═══════════════════════════════════════════════════════════
12151460// ──── Main ─────────────────────────────────────────────────
12161461// ═══════════════════════════════════════════════════════════
12171462
12181463int main (int argc, char *argv[])
12191464{
1465+ if (argc > 1 && std::string (argv[1 ]) == " --kernel" )
1466+ {
1467+ runKernel ();
1468+ return 0 ;
1469+ }
1470+
12201471 if (argc > 1 && std::string (argv[1 ]) == " --test" )
12211472 {
12221473 std::string source =
0 commit comments