LivinGrimoire holyC port

fukurou

the supreme coder
ADMIN
pt1/4
Code:
// LivinGrimoire.HC
// HolyC port of LivinGrimoire.py
// Runs on TempleOS
// OOP replaced with structs + function pointers (composition)
// Caps: MAX_SKILLS=16, MAX_SENTENCES=32, MAX_ALG_PARTS=16, NEURON_QUEUE=4

#define MAX_SKILLS      16
#define MAX_SENTENCES   32
#define MAX_ALG_PARTS   16
#define NEURON_QUEUE    4
#define DEFCON_LEVELS   5

// ─────────────────────────────────────────────
// AbsDictionaryDB
// ─────────────────────────────────────────────
class AbsDictionaryDB
{
  U0 (*Save)(AbsDictionaryDB *self, U8 *key, U8 *value);
  U8 *(*Load)(AbsDictionaryDB *self, U8 *key);
};

U0 AbsDictionaryDB_Save_Default(AbsDictionaryDB *self, U8 *key, U8 *value)
{
  // override in subcomposition
}

U8 *AbsDictionaryDB_Load_Default(AbsDictionaryDB *self, U8 *key)
{
  return "null";
}

U0 AbsDictionaryDB_Init(AbsDictionaryDB *self)
{
  self->Save = &AbsDictionaryDB_Save_Default;
  self->Load = &AbsDictionaryDB_Load_Default;
}

// ─────────────────────────────────────────────
// AlgPart
// ─────────────────────────────────────────────
class AlgPart
{
  Bool algKillSwitch;
  U8   customName[64];
  U8  *(*Action)(AlgPart *self, U8 *ear, U8 *skin, U8 *eye);
  Bool (*Completed)(AlgPart *self);
};

U8 *AlgPart_Action_Default(AlgPart *self, U8 *ear, U8 *skin, U8 *eye)
{
  return "";
}

Bool AlgPart_Completed_Default(AlgPart *self)
{
  return TRUE;
}

U0 AlgPart_Init(AlgPart *self, U8 *name)
{
  self->algKillSwitch = FALSE;
  StrCpy(self->customName, name);
  self->Action    = &AlgPart_Action_Default;
  self->Completed = &AlgPart_Completed_Default;
}

U0 AlgPart_SetName(AlgPart *self, U8 *name)
{
  StrCpy(self->customName, name);
}

U8 *AlgPart_MyName(AlgPart *self)
{
  return self->customName;
}

// ─────────────────────────────────────────────
// APVerbatim  (composes AlgPart)
// ─────────────────────────────────────────────
class APVerbatim
{
  AlgPart base;
  U8     *sentences[MAX_SENTENCES];
  I64     count;
  I64     head;  // queue head index
};

U8 *APVerbatim_Action(AlgPart *base, U8 *ear, U8 *skin, U8 *eye)
{
  APVerbatim *self = (APVerbatim *)base;
  if (self->head >= self->count)
    return "";
  U8 *s = self->sentences[self->head];
  self->head++;
  return s;
}

Bool APVerbatim_Completed(AlgPart *base)
{
  APVerbatim *self = (APVerbatim *)base;
  return self->head >= self->count;
}

U0 APVerbatim_Init(APVerbatim *self)
{
  AlgPart_Init(&self->base, "APVerbatim");
  self->base.Action    = &APVerbatim_Action;
  self->base.Completed = &APVerbatim_Completed;
  self->count = 0;
  self->head  = 0;
}

U0 APVerbatim_Add(APVerbatim *self, U8 *sentence)
{
  if (self->count < MAX_SENTENCES)
  {
    self->sentences[self->count] = sentence;
    self->count++;
  }
}

// ─────────────────────────────────────────────
// Algorithm
// ─────────────────────────────────────────────
class Algorithm
{
  AlgPart *parts[MAX_ALG_PARTS];
  I64      size;
};

U0 Algorithm_Init(Algorithm *self)
{
  self->size = 0;
  I64 i;
  for (i = 0; i < MAX_ALG_PARTS; i++)
    self->parts[i] = NULL;
}

U0 Algorithm_AddPart(Algorithm *self, AlgPart *part)
{
  if (self->size < MAX_ALG_PARTS)
  {
    self->parts[self->size] = part;
    self->size++;
  }
}

I64 Algorithm_GetSize(Algorithm *self)
{
  return self->size;
}

// ─────────────────────────────────────────────
// Kokoro
// ─────────────────────────────────────────────
class Kokoro
{
  U8            emot[128];
  AbsDictionaryDB *grimoireMemento;
  // toHeart omitted: no hash map in TempleOS stdlib;
  // extend with a flat key/val array if needed
};

U0 Kokoro_Init(Kokoro *self, AbsDictionaryDB *db)
{
  self->emot[0]        = 0;
  self->grimoireMemento = db;
}

U8 *Kokoro_GetEmot(Kokoro *self)
{
  return self->emot;
}

U0 Kokoro_SetEmot(Kokoro *self, U8 *emot)
{
  StrCpy(self->emot, emot);
}

// ─────────────────────────────────────────────
// Neuron
// ─────────────────────────────────────────────
class Neuron
{
  // defcons[1..5], each a small queue of Algorithm pointers
  Algorithm *defcons[DEFCON_LEVELS + 1][NEURON_QUEUE];
  I64        defcon_count[DEFCON_LEVELS + 1];
};

U0 Neuron_Init(Neuron *self)
{
 

fukurou

the supreme coder
ADMIN
pt2/4
Code:
  I64 i, j;
  for (i = 0; i <= DEFCON_LEVELS; i++)
  {
    self->defcon_count[i] = 0;
    for (j = 0; j < NEURON_QUEUE; j++)
      self->defcons[i][j] = NULL;
  }
}

U0 Neuron_InsertAlg(Neuron *self, I64 priority, Algorithm *alg)
{
  if (priority < 1 || priority > 5) return;
  if (self->defcon_count[priority] >= NEURON_QUEUE) return;
  self->defcons[priority][self->defcon_count[priority]] = alg;
  self->defcon_count[priority]++;
}

Algorithm *Neuron_GetAlg(Neuron *self, I64 defcon)
{
  if (self->defcon_count[defcon] == 0) return NULL;
  Algorithm *temp = self->defcons[defcon][0];
  // shift queue left
  I64 i;
  for (i = 0; i < self->defcon_count[defcon] - 1; i++)
    self->defcons[defcon][i] = self->defcons[defcon][i + 1];
  self->defcon_count[defcon]--;
  return temp;
}

// ─────────────────────────────────────────────
// Skill
// ─────────────────────────────────────────────
class Skill
{
  Kokoro    *kokoro;
  Algorithm *outAlg;
  I64        outAlgPriority;
  I64        skillType;   // 1:regular, 2:continuous
  I64        skillLobe;   // 1:logical 2:hardware 3:ear 4:skin 5:eye
  U8         skillName[64];

  // virtual methods via function pointers
  U0  (*Input)(Skill *self, U8 *ear, U8 *skin, U8 *eye);
  U0  (*Manifest)(Skill *self);
  U0  (*Ghost)(Skill *self);
  U8 *(*SkillNotes)(Skill *self, U8 *param);
};

U0 Skill_Input_Default(Skill *self, U8 *ear, U8 *skin, U8 *eye)   { }
U0 Skill_Manifest_Default(Skill *self)                              { }
U0 Skill_Ghost_Default(Skill *self)                                 { }
U8 *Skill_SkillNotes_Default(Skill *self, U8 *param) { return "notes unknown"; }

U0 Skill_Init(Skill *self, U8 *name)
{
  self->kokoro         = NULL;
  self->outAlg         = NULL;
  self->outAlgPriority = -1;
  self->skillType      = 1;
  self->skillLobe      = 1;
  StrCpy(self->skillName, name);
  self->Input      = &Skill_Input_Default;
  self->Manifest   = &Skill_Manifest_Default;
  self->Ghost      = &Skill_Ghost_Default;
  self->SkillNotes = &Skill_SkillNotes_Default;
}

U0 Skill_Output(Skill *self, Neuron *neuron)
{
  if (self->outAlg != NULL)
  {
    Neuron_InsertAlg(neuron, self->outAlgPriority, self->outAlg);
    self->outAlgPriority = -1;
    self->outAlg         = NULL;
  }
}

Bool Skill_PendingAlgorithm(Skill *self)
{
  return self->outAlg != NULL;
}

// helper: build a single-APVerbatim algorithm and assign it
// caller provides pre-allocated APVerbatim and Algorithm
U0 Skill_SetVerbatimAlg(Skill *self, I64 priority,
                         APVerbatim *apv, Algorithm *alg,
                         U8 **sentences, I64 count)
{
  APVerbatim_Init(apv);
  I64 i;
  for (i = 0; i < count; i++)
    APVerbatim_Add(apv, sentences[i]);
  Algorithm_Init(alg);
  Algorithm_AddPart(alg, &apv->base);
  self->outAlg         = alg;
  self->outAlgPriority = priority;
}

U0 Skill_SetSimpleAlg(Skill *self,
                       APVerbatim *apv, Algorithm *alg,
                       U8 **sentences, I64 count)
{
  Skill_SetVerbatimAlg(self, 4, apv, alg, sentences, count);
}

// ─────────────────────────────────────────────
// DiHelloWorld  (composes Skill)
// ─────────────────────────────────────────────
class DiHelloWorld
{
  Skill    base;
  APVerbatim apv;
  Algorithm  alg;
};

U0 DiHelloWorld_Input(Skill *base, U8 *ear, U8 *skin, U8 *eye)
{
  DiHelloWorld *self = (DiHelloWorld *)base;
  if (!StrCmp(ear, "hello"))
  {
    U8 *sentences[1];
    sentences[0] = "hello world";
    Skill_SetVerbatimAlg(&self->base, 4, &self->apv, &self->alg, sentences, 1);
  }
}

U8 *DiHelloWorld_SkillNotes(Skill *base, U8 *param)
{
  if (!StrCmp(param, "notes"))    return "plain hello world skill";
  if (!StrCmp(param, "triggers")) return "say hello";
  return "note unavailable";
}

U0 DiHelloWorld_Init(DiHelloWorld *self)
{
  Skill_Init(&self->base, "DiHelloWorld");
  self->base.Input      = &DiHelloWorld_Input;
  self->base.SkillNotes = &DiHelloWorld_SkillNotes;
}

// ─────────────────────────────────────────────
// Cerebellum
// ─────────────────────────────────────────────
class Cerebellum
{
  I64       fin;
  I64       at;
  Bool      incrementAt;
  Algorithm *alg;
  Bool      isActive;
  U8        emot[128];
};

U0 Cerebellum_Init(Cerebellum *self)
{
  self->fin         = 0;
  self->at          = 0;
  self->incrementAt = FALSE;
  self->alg         = NULL;
  self->isActive    = FALSE;
  self->emot[0]     = 0;
}

U0 Cerebellum_SetAlgorithm(Cerebellum *self, Algorithm *alg)
{
  if (!self->isActive && alg != NULL && alg->size > 0)
  {
    self->alg         = alg;
    self->at          = 0;
    self->fin         = alg->size;
    self->isActive    = TRUE;
    StrCpy(self->emot, AlgPart_MyName(alg->parts[0]));
  }
}

U0 Cerebellum_AdvanceInAlg(Cerebellum *self)
{
  if (self->incrementAt)
  {
    self->incrementAt = FALSE;
    self->at++;
    if (self->at == self->fin)
      self->isActive = FALSE;
  }
}

U8 *Cerebellum_Act(Cerebellum *self, U8 *ear, U8 *skin, U8 *eye)
{
  if (!self->isActive) return "";
  if (self->at < self->fin)
  {
 

fukurou

the supreme coder
ADMIN
pt3/4
Code:
    AlgPart *part = self->alg->parts[self->at];
    U8 *result    = part->Action(part, ear, skin, eye);
    StrCpy(self->emot, AlgPart_MyName(part));
    if (part->Completed(part))
      self->incrementAt = TRUE;
    return result;
  }
  return "";
}

U0 Cerebellum_DeactivateAlg(Cerebellum *self)
{
  if (self->isActive)
  {
    AlgPart *part = self->alg->parts[self->at];
    if (part->algKillSwitch)
      self->isActive = FALSE;
  }
}

// ─────────────────────────────────────────────
// Fusion
// ─────────────────────────────────────────────
class Fusion
{
  Cerebellum ceraArr[DEFCON_LEVELS];
  U8         emot[128];
  U8         result[512];
};

U0 Fusion_Init(Fusion *self)
{
  I64 i;
  for (i = 0; i < DEFCON_LEVELS; i++)
    Cerebellum_Init(&self->ceraArr[i]);
  self->emot[0]   = 0;
  self->result[0] = 0;
}

U0 Fusion_LoadAlgs(Fusion *self, Neuron *neuron)
{
  I64 i;
  for (i = 0; i < DEFCON_LEVELS; i++)
  {
    if (!self->ceraArr[i].isActive)
    {
      Algorithm *temp = Neuron_GetAlg(neuron, i + 1);
      if (temp != NULL)
        Cerebellum_SetAlgorithm(&self->ceraArr[i], temp);
    }
  }
}

U8 *Fusion_RunAlgs(Fusion *self, U8 *ear, U8 *skin, U8 *eye)
{
  self->result[0] = 0;
  I64 i;
  for (i = 0; i < DEFCON_LEVELS; i++)
  {
    if (!self->ceraArr[i].isActive) continue;
    U8 *r = Cerebellum_Act(&self->ceraArr[i], ear, skin, eye);
    StrCpy(self->result, r);
    Cerebellum_AdvanceInAlg(&self->ceraArr[i]);
    StrCpy(self->emot, self->ceraArr[i].emot);
    Cerebellum_DeactivateAlg(&self->ceraArr[i]);
    return self->result;
  }
  self->emot[0] = 0;
  return self->result;
}

// ─────────────────────────────────────────────
// Lobe
// ─────────────────────────────────────────────
class Lobe
{
  Skill   *dClasses[MAX_SKILLS];    // regular skills
  I64      dCount;
  Skill   *ctsSkills[MAX_SKILLS];   // continuous skills
  I64      ctsCount;
  Fusion   fusion;
  Neuron   neuron;
  Kokoro   kokoro;
  Bool     isThinking;
  Bool     algTriggered;
};

U0 Lobe_Init(Lobe *self, AbsDictionaryDB *db)
{
  self->dCount      = 0;
  self->ctsCount    = 0;
  self->isThinking  = FALSE;
  self->algTriggered = FALSE;
  Fusion_Init(&self->fusion);
  Neuron_Init(&self->neuron);
  Kokoro_Init(&self->kokoro, db);
  I64 i;
  for (i = 0; i < MAX_SKILLS; i++)
  {
    self->dClasses[i]  = NULL;
    self->ctsSkills[i] = NULL;
  }
}

U0 Lobe_AddRegularSkill(Lobe *self, Skill *skill)
{
  if (self->isThinking) return;
  if (self->dCount >= MAX_SKILLS) return;
  skill->skillType = 1;
  skill->kokoro    = &self->kokoro;
  self->dClasses[self->dCount++] = skill;
  skill->Manifest(skill);
}

U0 Lobe_AddContinuousSkill(Lobe *self, Skill *skill)
{
  if (self->isThinking) return;
  if (self->ctsCount >= MAX_SKILLS) return;
  skill->skillType = 2;
  skill->kokoro    = &self->kokoro;
  self->ctsSkills[self->ctsCount++] = skill;
  skill->Manifest(skill);
}

U0 Lobe_AddSkill(Lobe *self, Skill *skill)
{
  if (skill->skillType == 1)
    Lobe_AddRegularSkill(self, skill);
  else
    Lobe_AddContinuousSkill(self, skill);
}

U0 Lobe_RemoveRegularSkill(Lobe *self, Skill *skill)
{
  if (self->isThinking) return;
  I64 i;
  for (i = 0; i < self->dCount; i++)
  {
    if (self->dClasses[i] == skill)
    {
      skill->Ghost(skill);
      // shift left
      I64 j;
      for (j = i; j < self->dCount - 1; j++)
        self->dClasses[j] = self->dClasses[j + 1];
      self->dClasses[--self->dCount] = NULL;
      return;
    }
  }
}

U0 Lobe_RemoveContinuousSkill(Lobe *self, Skill *skill)
{
  if (self->isThinking) return;
  I64 i;
  for (i = 0; i < self->ctsCount; i++)
  {
    if (self->ctsSkills[i] == skill)
    {
      skill->Ghost(skill);
      I64 j;
      for (j = i; j < self->ctsCount - 1; j++)
        self->ctsSkills[j] = self->ctsSkills[j + 1];
      self->ctsSkills[--self->ctsCount] = NULL;
      return;
    }
  }
}

U0 Lobe_RemoveSkill(Lobe *self, Skill *skill)
{
  if (skill->skillType == 1)
    Lobe_RemoveRegularSkill(self, skill);
  else
    Lobe_RemoveContinuousSkill(self, skill);
}

U0 Lobe_ClearRegularSkills(Lobe *self)
{
  if (self->isThinking) return;
  I64 i;
  for (i = 0; i < self->dCount; i++)
    self->dClasses[i]->Ghost(self->dClasses[i]);
  self->dCount = 0;
}

U0 Lobe_ClearContinuousSkills(Lobe *self)
{
  if (self->isThinking) return;
  I64 i;
  for (i = 0; i < self->ctsCount; i++)
 

fukurou

the supreme coder
ADMIN
pt4/4
Code:
    self->ctsSkills[i]->Ghost(self->ctsSkills[i]);
  self->ctsCount = 0;
}

U0 Lobe_InOut(Lobe *self, Skill *skill, U8 *ear, U8 *skin, U8 *eye)
{
  skill->Input(skill, ear, skin, eye);
  if (Skill_PendingAlgorithm(skill))
    self->algTriggered = TRUE;
  Skill_Output(skill, &self->neuron);
}

U8 *Lobe_Think(Lobe *self, U8 *ear, U8 *skin, U8 *eye)
{
  self->algTriggered = FALSE;
  self->isThinking   = TRUE;
  I64 i;
  for (i = 0; i < self->dCount; i++)
    Lobe_InOut(self, self->dClasses[i], ear, skin, eye);
  for (i = 0; i < self->ctsCount; i++)
  {
    if (self->algTriggered) break;
    Lobe_InOut(self, self->ctsSkills[i], ear, skin, eye);
  }
  self->isThinking = FALSE;
  Fusion_LoadAlgs(&self->fusion, &self->neuron);
  return Fusion_RunAlgs(&self->fusion, ear, skin, eye);
}

Kokoro *Lobe_GetKokoro(Lobe *self)
{
  return &self->kokoro;
}

U0 Lobe_SetKokoro(Lobe *self, Kokoro *kokoro)
{
  MemCpy(&self->kokoro, kokoro, sizeof(Kokoro));
}

// ─────────────────────────────────────────────
// Brain
// ─────────────────────────────────────────────
class Brain
{
  U8   emotion[128];
  U8   logicLobeOutput[512];
  Lobe logicLobe;
  Lobe hardwareLobe;
  Lobe ear;
  Lobe skin;
  Lobe eye;
  AbsDictionaryDB defaultDb;
};

U0 Brain_ImprintSoul(Kokoro *kokoro, Lobe **lobes, I64 count)
{
  I64 i;
  for (i = 0; i < count; i++)
    Lobe_SetKokoro(lobes[i], kokoro);
}

U0 Brain_Init(Brain *self)
{
  self->emotion[0]        = 0;
  self->logicLobeOutput[0] = 0;
  AbsDictionaryDB_Init(&self->defaultDb);
  Lobe_Init(&self->logicLobe,   &self->defaultDb);
  Lobe_Init(&self->hardwareLobe, &self->defaultDb);
  Lobe_Init(&self->ear,          &self->defaultDb);
  Lobe_Init(&self->skin,         &self->defaultDb);
  Lobe_Init(&self->eye,          &self->defaultDb);
  Lobe *lobes[4];
  lobes[0] = &self->hardwareLobe;
  lobes[1] = &self->ear;
  lobes[2] = &self->skin;
  lobes[3] = &self->eye;
  Brain_ImprintSoul(Lobe_GetKokoro(&self->logicLobe), lobes, 4);
}

U0 Brain_DoIt(Brain *self, U8 *ear, U8 *skin, U8 *eye)
{
  U8 *out = Lobe_Think(&self->logicLobe, ear, skin, eye);
  StrCpy(self->logicLobeOutput, out);
  StrCpy(self->emotion, self->logicLobe.fusion.emot);
  Lobe_Think(&self->hardwareLobe, self->logicLobeOutput, skin, eye);
}

U0 Brain_AddSkill(Brain *self, Skill *skill)
{
  switch (skill->skillLobe)
  {
    case 1: Lobe_AddSkill(&self->logicLobe,    skill); break;
    case 2: Lobe_AddSkill(&self->hardwareLobe, skill); break;
    case 3: Lobe_AddSkill(&self->ear,          skill); break;
    case 4: Lobe_AddSkill(&self->skin,         skill); break;
    case 5: Lobe_AddSkill(&self->eye,          skill); break;
  }
}

U0 Brain_RemoveSkill(Brain *self, Skill *skill)
{
  switch (skill->skillLobe)
  {
    case 1: Lobe_RemoveSkill(&self->logicLobe,    skill); break;
    case 2: Lobe_RemoveSkill(&self->hardwareLobe, skill); break;
    case 3: Lobe_RemoveSkill(&self->ear,          skill); break;
    case 4: Lobe_RemoveSkill(&self->skin,         skill); break;
    case 5: Lobe_RemoveSkill(&self->eye,          skill); break;
  }
}

U0 Brain_Think(Brain *self)
{
  U8 *earOut  = Lobe_Think(&self->ear,  "", "", "");
  U8 *skinOut = Lobe_Think(&self->skin, "", "", "");
  U8 *eyeOut  = Lobe_Think(&self->eye,  "", "", "");
  Brain_DoIt(self, earOut, skinOut, eyeOut);
}

U0 Brain_ThinkDefault(Brain *self, U8 *keyIn)
{
  if (StrLen(keyIn) > 0)
    Brain_DoIt(self, keyIn, "", "");
  else
    Brain_Think(self);
}

// ─────────────────────────────────────────────
// DiSysOut  (composes Skill)
// ─────────────────────────────────────────────
class DiSysOut
{
  Skill base;
};

U0 DiSysOut_Input(Skill *base, U8 *ear, U8 *skin, U8 *eye)
{
  if (StrLen(ear) > 0)
  {
    // check no '#' in ear
    U8 *p = ear;
    Bool hasHash = FALSE;
    while (*p)
    {
      if (*p == '#') { hasHash = TRUE; break; }
      p++;
    }
    if (!hasHash)
      "%s\n", ear;
  }
}

U8 *DiSysOut_SkillNotes(Skill *base, U8 *param)
{
  if (!StrCmp(param, "notes"))    return "prints to console";
  if (!StrCmp(param, "triggers")) return "automatic for any input";
  return "note unavailable";
}

U0 DiSysOut_Init(DiSysOut *self)
{
  Skill_Init(&self->base, "DiSysOut");
  self->base.skillType = 2;  // continuous
  self->base.skillLobe = 2;  // hardware lobe
  self->base.Input      = &DiSysOut_Input;
  self->base.SkillNotes = &DiSysOut_SkillNotes;
}

// ─────────────────────────────────────────────
// Usage example
// ─────────────────────────────────────────────
U0 Main()
{
  Brain        brain;
  DiHelloWorld hello;
  DiSysOut     sysout;

  Brain_Init(&brain);
  DiHelloWorld_Init(&hello);
  DiSysOut_Init(&sysout);

  Brain_AddSkill(&brain, &hello.base);
  Brain_AddSkill(&brain, &sysout.base);

  Brain_ThinkDefault(&brain, "hello");
  Brain_ThinkDefault(&brain, "hello");  // second tick outputs the string
}

Main;
 
Top