Загрузка...

How to organize the toy memory of your language?

Thread in C# created by Host1 Mar 23, 2024. 194 views

  1. Host1
    Host1 Topic starter Mar 23, 2024 Лучше бы раньше, но раньше уже закончилось 64 Aug 8, 2017
    Делаю свой домашний проект - виртуальную машину наподобие jvm. Есть текстовый файл с опкодами по типу:
    Code
    store 200 0 i //кладет в ячейку памяти 0 значение 200 и помечает ячейку как integer
    store string 1 s //кладет в ячейку памяти 1 значение string и помечает ячейку как string
    store a 2 c //кладет в ячейку памяти 2 значение c и помечает ячейку как char
    store 300 3 i //кладет в ячейку памяти 3 значение 300 и помечает ячейку как integer
    load 0 //загружает из ячейки памяти 0 значение в стек, тип стека задается типом первого загружаемого значение, в данном случае int
    load 3 //загружает из ячейки памяти 3 значение в стек
    add //складывает значения в стеке
    store 4 //результат который остался от сложения берет из стека и кладет в ячейку 4
    И я столкнулся с проблемой как хранить эти ячейки памяти.
    Если создавать ячейки через дженерики < T >, то такие ячейки будут разными и хранить их в одном массиве не получится. Если бы так работало, то можно было бы получать доступ к ячейке просто по индексу и вызывать в ней метод get который возвращал тот тип данных который хранит ячейка.

    Потом я подумал хранить ячейки в массиве object, но это плохая идея так как все равно придется приводить к типу ячейки, приведение типов не безопасно. Да и конвертация в object и обратно занимает время просто так, неэффективно.

    Далее я подумал сделать ячейку универсальной и дать ей поля всех нужных типов данных: int float char string bool, но тогда получается когда в ячейку помещается значение оно хранится в одном из 5 полей, остальные 4 поля пустые и неинициализированные, что не есть хорошо.

    Еще была идея создать 5 массивов, каждый для своего типа ячеек, например массив MemArrInt[] хранит ячейки MemCellInt которые имеют поле int для хранения данных, но мне эта идея показалась неправильной и костыльной и что будто есть нормальный путь сделать задуманное.

    Если тут есть хорошо разбирающиеся в C# и в целом архитектуре языков программирования, подскажите пожалуйста идею как это все можно было бы реализовать по вашему. Или если вы знаете источники где это хорошо описано прошу поделиться. Заранее спасибо. Если есть какие либо идеи или предложения и вам удобнее показать/рассказать это в тг, то пожалуйста, буду ждать вас там.
     
    1. View previous comments (7)
    2. vtlstolyarov
      Host1,
      в самом простом варианте типом данных может быть число - для твоей простейшей виртуальной машины будет достаточно 1 байта - этого тебе хватит зтобы определить 256 типов данных, например:

      CSHARP
      struct TypeDescriptor
      {
      public string Name { get; init }
      public byte Size { get; init }
      }

      public static TypeDescriptor[] TypeDescriptors = new TypeDescriptor[]
      {
      new() { Name = "NULL", Size = 0 }, // не занимает места в памяти так как не несёт никакой другой инфомации ктоме того что это NULL
      new() { Name = "Int8", Size = 1 }, // 1 октет памяти хранит 8-бит информации, биты надо интерпретировать как 8-битное число со знаком
      new() { Name = "UInt8", Size = 1 }, // 1 октет памяти хранит 8-бит информации, биты надо интерпретировать как 8-битное число без знака
      new() { Name = "Int16", Size = 2 }, // 2 октета памяти хранят 16-бит информации, биты надо интерпретировать как 16-битное число со знаком
      new() { Name = "UInt16", Size = 2 }, // 2 октета памяти хранят 16-бит информации, биты надо интерпретировать как 16-битное число без знака
      new() { Name = "char", Size = 1 }, // 1 октет памяти хранит 8-бит информации, биты надо интерпретировать как код символа в таблице ASCII
      new() { Name = "pointer", Size = 2 }, // 2 октета памяти хранят 16-бит информации, биты надо интерпретировать как 16-битное число без знака которое означает индекс ячейки памяти (это при условии что тебе хватит 16-разрядной шины адреса - 2^16=64KB памяти, ели не хватит - делай размера 4 - будет 32-разрядная шина, ее хватит на 4ГБ)
      new() { Name = "string", Size = 4 }, // 4 октета памяти хранят 32-бита информации, первые 16 бит надо интерпретировать как pointer на участок памяти хранящий размер строки, вторые 16 бит - как pointer на начало участка памяти хранящего столько char'ов сколько было указано в размере строки
      // и так далее описываешь все типы данных которые хочешь поддерживать
      }
    3. Host1 Topic starter
      vtlstolyarov, Спасибо большое, это очень подробное и интересное объяснение. Теперь все стало намного понятнее, пойду пробовать реализовывать эту идею. Если столкнусь с чем-то что не сможет объяснить интернет или gpt, не против если я обращусь к вам здесь или в другой теме?
    4. vtlstolyarov
      Host1, Обращайся :)
    5. View the next comments (9)
Top
Loading...