sporniket / ideas

My backlog of ideas, organized as a bunch of issues
0 stars 0 forks source link

Model and API to manage variables in scripting languages #19

Open sporniket opened 1 year ago

sporniket commented 1 year ago

Abstract

Studying some scripting languages like Espruino, Micropython,..., design my own model and API for my own scripting language.

In a javascript-like toy scripting language, it would gives something like :

a = 10
console.log(a) // Output: 10

a = "Hello"
console.log(a) // Output: Hello

a = true
console.log(a) // Output: true

a = { 
  order_id: 1, 
  amount: 10.35, 
  currency: "EUR", 
  shipping_address: {
    lines:[
      "1 baker street","for M. Bar"
    ], 
    zipcode:"92340", 
    city:"New York"
  } 
}
console.log(a) // Output: { order_id: 1, amount: 10.35, currency: "EUR", shipping_address: {lines:["1 baker street","for M. Bar"], zipcode:"92340", city:"New York"} }
sporniket commented 1 year ago

Variable representation

Inspired by Espruino variable storage principles, one variable will occupy one or more blocks of 16 bytes.

The set of features : a wish-list

The blocks

The variables

Logic model :

const {
  data, // 8 bytes
  navigation : {
    parent, previous, next // ids of blocks of same level = 6 bytes
  },
  children : { 
    first, last // ids of children blocks = 4 bytes
  },
  flags : {
    integral, // boolean, meaningfull only when the type is number
    type, // unsigned integer (predefined types : 0 = number, 1 = names, 2 = strings, ...)
    //...
  } // MUST hold into 2 bytes
} = jsvar  // MUST hold into 16 bytes

Samples

An integer named item_count

[ //...
//current index for the variable : i
{
  data: {
    name: {
      length:10, // uint16_t
      first:i+1, 
      last:i+2 
    }, // 6 bytes
    value: {
      type : 0, // uint16_t
      first : i+3,
      last: i+3
    }
  },
  navigation : {
    parent : p //whatever, 
    previous : i-3 // if the previous variable is a short named, integer value too, 
    next : 0 // this is the latest variable declared
  },
  flags : {
    type : TYPE__VARIABLE_DEFINITION
  } // MUST hold into 2 bytes
}, 
// current index for the name, first block : i+1
{
  data: {
    name: "item_cou", //8 bytes at most
  },
  navigation : {
    parent : i //the variable definition block, 
    previous : 0 // first block in the list
    next : i+2 // next block to complete the name
  },
  flags : {
    type : TYPE__NAME_PART
  } // MUST hold into 2 bytes
}, 
// current index for the name, second block : i+2
{
  data: {
    name: "nt\u0000\u0000\u0000\u0000\u0000\u0000", //8 bytes at most, padded with 0
  },
  navigation : {
    parent : i //the variable definition block, 
    previous : i+1 // previous block in the list
    next : 0 // no more blocks for the name
  },
  flags : {
    type : TYPE__KEY_NAME_PART
  } // MUST hold into 2 bytes
}, 
// current index for the value : i+3
{
  data : {
    integral, decimal // 2×uint32_t
  }, 
  navigation : {
    parent : i, //the block that "owns" the value
    previous:0, next:0 // single child bloc
  },
  flags : {
    integral : true, //by default, false
    type : TYPE__NUMBER_VALUE, 
    //...
  } // MUST hold into 2 bytes
}
]