runtime type checking
This commit is contained in:
parent
e2ddf94a00
commit
5243e46dce
5 changed files with 217 additions and 42 deletions
|
|
@ -3,7 +3,7 @@ use crate::value::Value;
|
||||||
use crate::vm::{
|
use crate::vm::{
|
||||||
OP_ADD, OP_BITAND, OP_BITOR, OP_BITXOR, OP_CONSTANT, OP_DIVIDE, OP_FALSE, OP_MULTIPLY,
|
OP_ADD, OP_BITAND, OP_BITOR, OP_BITXOR, OP_CONSTANT, OP_DIVIDE, OP_FALSE, OP_MULTIPLY,
|
||||||
OP_NEGATE, OP_RETURN, OP_SUBTRACT, OP_TRUE, OP_NOT, OP_SHL, OP_SHR, OP_LESS, OP_LESS_EQUAL,
|
OP_NEGATE, OP_RETURN, OP_SUBTRACT, OP_TRUE, OP_NOT, OP_SHL, OP_SHR, OP_LESS, OP_LESS_EQUAL,
|
||||||
OP_GREATER, OP_GREATER_EQUAL, OP_EQUAL, OP_PRINT, OP_POP, OP_DEFINE, OP_GET,OP_DEF_STRING
|
OP_GREATER, OP_GREATER_EQUAL, OP_EQUAL, OP_PRINT, OP_POP, OP_DEFINE, OP_GET,OP_DEF_STRING, OP_DEF_BOOL
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Chunk {
|
pub struct Chunk {
|
||||||
|
|
@ -75,6 +75,7 @@ impl Chunk {
|
||||||
OP_POP => self.simple_inst("POP", offset),
|
OP_POP => self.simple_inst("POP", offset),
|
||||||
OP_DEFINE => self.constant_inst("DEF", offset),
|
OP_DEFINE => self.constant_inst("DEF", offset),
|
||||||
OP_DEF_STRING => self.constant_inst("DEFSTR", offset),
|
OP_DEF_STRING => self.constant_inst("DEFSTR", offset),
|
||||||
|
OP_DEF_BOOL => self.constant_inst("DEFBOOL", offset),
|
||||||
OP_GET => self.constant_inst("GET", offset),
|
OP_GET => self.constant_inst("GET", offset),
|
||||||
_ => {
|
_ => {
|
||||||
println!("Unknown instruction {}", instruction);
|
println!("Unknown instruction {}", instruction);
|
||||||
|
|
@ -90,12 +91,12 @@ impl Chunk {
|
||||||
|
|
||||||
fn constant_inst(&self, name: &str, offset: usize) -> usize {
|
fn constant_inst(&self, name: &str, offset: usize) -> usize {
|
||||||
let constant = self.code[offset + 1];
|
let constant = self.code[offset + 1];
|
||||||
print!("{} {} ", name, constant);
|
print!("{} {}:", name, constant);
|
||||||
self.print_value(&self.constants[constant as usize]);
|
self.print_value(&self.constants[constant as usize]);
|
||||||
offset + 2
|
offset + 2
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_value(&self, value: &Value) {
|
fn print_value(&self, value: &Value) {
|
||||||
println!("{:?}", value);
|
println!("{}", value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,10 @@ use crate::tokens::{Token, TokenType};
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
use crate::vm::{
|
use crate::vm::{
|
||||||
OP_ADD, OP_BITAND, OP_BITOR, OP_BITXOR, OP_CONSTANT, OP_DEF_BOOL, OP_DEF_CHAR, OP_DEF_DATE,
|
OP_ADD, OP_BITAND, OP_BITOR, OP_BITXOR, OP_CONSTANT, OP_DEF_BOOL, OP_DEF_CHAR, OP_DEF_DATE,
|
||||||
OP_DEF_I32, OP_DEF_I64, OP_DEF_LIST, OP_DEF_MAP, OP_DEF_OBJ, OP_DEF_STRING, OP_DEFINE,
|
OP_DEF_F64, OP_DEF_I32, OP_DEF_I64, OP_DEF_LIST, OP_DEF_MAP, OP_DEF_STRUCT, OP_DEF_STRING,
|
||||||
OP_DIVIDE, OP_EQUAL, OP_FALSE, OP_GET, OP_GREATER, OP_GREATER_EQUAL, OP_LESS, OP_LESS_EQUAL,
|
OP_DEFINE, OP_DIVIDE, OP_EQUAL, OP_FALSE, OP_GET, OP_GREATER, OP_GREATER_EQUAL, OP_LESS,
|
||||||
OP_MULTIPLY, OP_NEGATE, OP_NOT, OP_POP, OP_PRINT, OP_RETURN, OP_SHL, OP_SHR, OP_SUBTRACT,
|
OP_LESS_EQUAL, OP_MULTIPLY, OP_NEGATE, OP_NOT, OP_POP, OP_PRINT, OP_RETURN, OP_SHL, OP_SHR,
|
||||||
OP_TRUE,
|
OP_SUBTRACT, OP_TRUE,
|
||||||
};
|
};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
@ -70,7 +70,7 @@ impl<'a> Compiler<'a> {
|
||||||
|
|
||||||
fn let_declaration(&mut self) -> anyhow::Result<()> {
|
fn let_declaration(&mut self) -> anyhow::Result<()> {
|
||||||
let index = self.parse_variable("Expect variable name")?;
|
let index = self.parse_variable("Expect variable name")?;
|
||||||
let mut var_type = None;
|
let mut declared_type = None;
|
||||||
if self.check(TokenType::Colon) {
|
if self.check(TokenType::Colon) {
|
||||||
self.consume(TokenType::Colon, "must not happen")?;
|
self.consume(TokenType::Colon, "must not happen")?;
|
||||||
match self.current_token.token_type {
|
match self.current_token.token_type {
|
||||||
|
|
@ -83,15 +83,16 @@ impl<'a> Compiler<'a> {
|
||||||
| TokenType::Char
|
| TokenType::Char
|
||||||
| TokenType::Bool
|
| TokenType::Bool
|
||||||
| TokenType::ListType
|
| TokenType::ListType
|
||||||
| TokenType::MapType => var_type = Some(self.current_token.token_type),
|
| TokenType::MapType => declared_type = Some(self.current_token.token_type),
|
||||||
_ => return Err(anyhow!("Invalid type {:?}", self.current_token.token_type)),
|
_ => return Err(anyhow!("Invalid type {:?}", self.current_token.token_type)),
|
||||||
}
|
}
|
||||||
self.advance()?;
|
self.advance()?;
|
||||||
}
|
}
|
||||||
if self.match_token(TokenType::Equal) {
|
if self.match_token(TokenType::Equal) {
|
||||||
self.expression(var_type)?;
|
self.expression(declared_type)?;
|
||||||
|
let derived_type = Some(&self.previous_token.token_type);
|
||||||
self.consume(TokenType::Eol, "Expect end of line")?;
|
self.consume(TokenType::Eol, "Expect end of line")?;
|
||||||
self.define_variable(var_type, index)?;
|
self.define_variable(declared_type, derived_type, index)?;
|
||||||
} else {
|
} else {
|
||||||
return Err(anyhow!(
|
return Err(anyhow!(
|
||||||
"You cannot declare a variable without initializing it."
|
"You cannot declare a variable without initializing it."
|
||||||
|
|
@ -111,7 +112,12 @@ impl<'a> Compiler<'a> {
|
||||||
Ok(index)
|
Ok(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn define_variable(&mut self, var_type: Option<TokenType>, index: usize) -> anyhow::Result<()> {
|
fn define_variable(
|
||||||
|
&mut self,
|
||||||
|
var_type: Option<TokenType>,
|
||||||
|
derived_type: Option<&TokenType>,
|
||||||
|
index: usize,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
let def_op = match var_type {
|
let def_op = match var_type {
|
||||||
Some(TokenType::I32) => OP_DEF_I32,
|
Some(TokenType::I32) => OP_DEF_I32,
|
||||||
Some(TokenType::I64) => OP_DEF_I64,
|
Some(TokenType::I64) => OP_DEF_I64,
|
||||||
|
|
@ -123,8 +129,17 @@ impl<'a> Compiler<'a> {
|
||||||
Some(TokenType::Bool) => OP_DEF_BOOL,
|
Some(TokenType::Bool) => OP_DEF_BOOL,
|
||||||
Some(TokenType::ListType) => OP_DEF_LIST,
|
Some(TokenType::ListType) => OP_DEF_LIST,
|
||||||
Some(TokenType::MapType) => OP_DEF_MAP,
|
Some(TokenType::MapType) => OP_DEF_MAP,
|
||||||
Some(TokenType::Object) => OP_DEF_OBJ,
|
Some(TokenType::Object) => OP_DEF_STRUCT,
|
||||||
|
_ => match derived_type {
|
||||||
|
Some(TokenType::Text) => OP_DEF_STRING,
|
||||||
|
Some(TokenType::Bool) => OP_DEF_BOOL,
|
||||||
|
Some(TokenType::Char) => OP_DEF_CHAR,
|
||||||
|
Some(TokenType::F64) => OP_DEF_F64,
|
||||||
|
Some(TokenType::I64) => OP_DEF_I64,
|
||||||
|
Some(TokenType::ListType) => OP_DEF_LIST,
|
||||||
|
Some(TokenType::MapType) => OP_DEF_MAP,
|
||||||
_ => OP_DEFINE,
|
_ => OP_DEFINE,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
self.emit_bytes(def_op, index as u16);
|
self.emit_bytes(def_op, index as u16);
|
||||||
|
|
@ -275,17 +290,24 @@ fn number(s: &mut Compiler, expected_type: Option<TokenType>) -> anyhow::Result<
|
||||||
TokenType::F32 => Value::U32(number.parse()?),
|
TokenType::F32 => Value::U32(number.parse()?),
|
||||||
TokenType::F64 => Value::U64(number.parse()?),
|
TokenType::F64 => Value::U64(number.parse()?),
|
||||||
|
|
||||||
_ => {return Err(anyhow!("Invalid type: expected {} value, got {}({})", expected_type, &s.previous_token.token_type, number));}
|
_ => {
|
||||||
|
return Err(anyhow!(
|
||||||
|
"Invalid type: expected {} value, got {}({})",
|
||||||
|
expected_type,
|
||||||
|
&s.previous_token.token_type,
|
||||||
|
number
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let TokenType::Number = s.previous_token.token_type {
|
if let TokenType::Number = s.previous_token.token_type {
|
||||||
if number.contains('.'){
|
if number.contains('.') {
|
||||||
Value::F64(number.parse()?)
|
Value::F64(number.parse()?)
|
||||||
} else {
|
} else {
|
||||||
Value::I64(number.parse()?)
|
Value::I64(number.parse()?)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(anyhow!("I did not think this would happen"))
|
return Err(anyhow!("I did not think this would happen"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
s.emit_constant(value);
|
s.emit_constant(value);
|
||||||
|
|
@ -293,21 +315,31 @@ fn number(s: &mut Compiler, expected_type: Option<TokenType>) -> anyhow::Result<
|
||||||
}
|
}
|
||||||
|
|
||||||
fn literal(s: &mut Compiler, expected_type: Option<TokenType>) -> anyhow::Result<()> {
|
fn literal(s: &mut Compiler, expected_type: Option<TokenType>) -> anyhow::Result<()> {
|
||||||
|
let actual_type = &s.previous_token.token_type;
|
||||||
if let Some(expected_type) = expected_type {
|
if let Some(expected_type) = expected_type {
|
||||||
if discriminant(&expected_type) != discriminant(&s.previous_token.token_type) {
|
match (actual_type, expected_type) {
|
||||||
|
(TokenType::False, TokenType::Bool) => s.emit_constant(Value::Bool(false)),
|
||||||
|
(TokenType::True, TokenType::Bool) => s.emit_constant(Value::Bool(true)),
|
||||||
|
(TokenType::Text, TokenType::String) => {
|
||||||
|
s.emit_constant(Value::String(s.previous_token.lexeme.clone()))
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
return Err(anyhow!(
|
return Err(anyhow!(
|
||||||
"Cannot assign {:?} to {:?}",
|
"Invalid type: expected {} value, got {}({})",
|
||||||
s.previous_token.token_type,
|
expected_type,
|
||||||
expected_type
|
&s.previous_token.token_type,
|
||||||
|
s.previous_token.lexeme
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match s.previous_token.token_type {
|
} else {
|
||||||
|
match actual_type {
|
||||||
TokenType::False => s.emit_constant(Value::Bool(false)),
|
TokenType::False => s.emit_constant(Value::Bool(false)),
|
||||||
TokenType::True => s.emit_constant(Value::Bool(true)),
|
TokenType::True => s.emit_constant(Value::Bool(true)),
|
||||||
TokenType::Text => s.emit_constant(Value::String(s.previous_token.lexeme.clone())),
|
TokenType::Text => s.emit_constant(Value::String(s.previous_token.lexeme.clone())),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -483,7 +515,7 @@ const PREC_UNARY: usize = 12;
|
||||||
const PREC_CALL: usize = 13;
|
const PREC_CALL: usize = 13;
|
||||||
const PREC_PRIMARY: usize = 14;
|
const PREC_PRIMARY: usize = 14;
|
||||||
|
|
||||||
enum ValueType{
|
enum ValueType {
|
||||||
DateType,
|
DateType,
|
||||||
BoolType,
|
BoolType,
|
||||||
CharType,
|
CharType,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ fn main() -> anyhow::Result<()> {
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
|
|
||||||
let chunk = crudlang::compiler::compile(
|
let chunk = crudlang::compiler::compile(
|
||||||
r#"let a:bool = 42"#,
|
r#"let a: string = "koe""#,
|
||||||
);
|
);
|
||||||
match chunk {
|
match chunk {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
|
||||||
33
src/value.rs
33
src/value.rs
|
|
@ -6,6 +6,35 @@ use std::fmt::{write, Display, Formatter};
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Not, Shl, Shr, Sub};
|
use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Not, Shl, Shr, Sub};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct StructDefinition {
|
||||||
|
fields: Vec<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Instance {
|
||||||
|
definition: StructDefinition,
|
||||||
|
fields: Vec<Value>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Instance {
|
||||||
|
pub fn new(definition: StructDefinition) -> Self {
|
||||||
|
Self {
|
||||||
|
definition,
|
||||||
|
fields: Vec::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for Instance {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
for (i, field) in self.definition.fields.iter().enumerate() {
|
||||||
|
write!(f, "{}: {}", field, self.fields[i])?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Value {
|
pub enum Value {
|
||||||
U32(u32),
|
U32(u32),
|
||||||
|
|
@ -19,9 +48,9 @@ pub enum Value {
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
Date(DateTime<Utc>),
|
Date(DateTime<Utc>),
|
||||||
Enum,
|
Enum,
|
||||||
Struct,
|
|
||||||
List(Vec<Value>),
|
List(Vec<Value>),
|
||||||
Map(HashMap<Value, Value>),
|
Map(HashMap<Value, Value>),
|
||||||
|
Struct(Instance),
|
||||||
Error(String),
|
Error(String),
|
||||||
Void
|
Void
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +140,7 @@ impl Display for Value {
|
||||||
&Value::Char(v) => write!(f, "{}", v),
|
&Value::Char(v) => write!(f, "{}", v),
|
||||||
&Value::Date(v) => write!(f, "{}", v),
|
&Value::Date(v) => write!(f, "{}", v),
|
||||||
&Value::Enum => write!(f, "enum"),
|
&Value::Enum => write!(f, "enum"),
|
||||||
&Value::Struct => write!(f, "struct"),
|
&Value::Struct(v) => write!(f, "{}", v),
|
||||||
&Value::List(v) => write!(f, "{:?}", v),
|
&Value::List(v) => write!(f, "{:?}", v),
|
||||||
&Value::Map(v) => write!(f, "map"),
|
&Value::Map(v) => write!(f, "map"),
|
||||||
&Value::Error(v) => write!(f, "{}", v),
|
&Value::Error(v) => write!(f, "{}", v),
|
||||||
|
|
|
||||||
129
src/vm.rs
129
src/vm.rs
|
|
@ -84,8 +84,118 @@ impl Vm {
|
||||||
OP_DEF_I32 => {
|
OP_DEF_I32 => {
|
||||||
let name = self.read_constant();
|
let name = self.read_constant();
|
||||||
let value = self.pop();
|
let value = self.pop();
|
||||||
if let Value::I32(v) = value {
|
if let Value::I32(_) = value {
|
||||||
self.local_vars.insert(name, value);
|
self.local_vars.insert(name, value);
|
||||||
|
} else {
|
||||||
|
return Err(anyhow!("Expected i32, got {:?}", value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OP_DEF_I64 => {
|
||||||
|
let name = self.read_constant();
|
||||||
|
let value = self.pop();
|
||||||
|
if let Value::I64(_) = value {
|
||||||
|
self.local_vars.insert(name, value);
|
||||||
|
} else {
|
||||||
|
return Err(anyhow!("Expected i64, got {:?}", value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OP_DEF_U32 => {
|
||||||
|
let name = self.read_constant();
|
||||||
|
let value = self.pop();
|
||||||
|
if let Value::U32(_) = value {
|
||||||
|
self.local_vars.insert(name, value);
|
||||||
|
} else {
|
||||||
|
return Err(anyhow!("Expected u32, got {:?}", value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OP_DEF_U64 => {
|
||||||
|
let name = self.read_constant();
|
||||||
|
let value = self.pop();
|
||||||
|
if let Value::U64(_) = value {
|
||||||
|
self.local_vars.insert(name, value);
|
||||||
|
} else {
|
||||||
|
return Err(anyhow!("Expected u64, got {:?}", value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OP_DEF_F32 => {
|
||||||
|
let name = self.read_constant();
|
||||||
|
let value = self.pop();
|
||||||
|
if let Value::F32(_) = value {
|
||||||
|
self.local_vars.insert(name, value);
|
||||||
|
} else {
|
||||||
|
return Err(anyhow!("Expected f32, got {:?}", value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OP_DEF_F64 => {
|
||||||
|
let name = self.read_constant();
|
||||||
|
let value = self.pop();
|
||||||
|
if let Value::F64(_) = value {
|
||||||
|
self.local_vars.insert(name, value);
|
||||||
|
} else {
|
||||||
|
return Err(anyhow!("Expected f64, got {:?}", value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OP_DEF_STRING => {
|
||||||
|
let name = self.read_constant();
|
||||||
|
let value = self.pop();
|
||||||
|
if let Value::String(_) = &value {
|
||||||
|
self.local_vars.insert(name, value);
|
||||||
|
} else {
|
||||||
|
return Err(anyhow!("Expected string, got {:?}", value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OP_DEF_CHAR => {
|
||||||
|
let name = self.read_constant();
|
||||||
|
let value = self.pop();
|
||||||
|
if let Value::Char(_) = &value {
|
||||||
|
self.local_vars.insert(name, value);
|
||||||
|
} else {
|
||||||
|
return Err(anyhow!("Expected char, got {:?}", value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OP_DEF_BOOL => {
|
||||||
|
let name = self.read_constant();
|
||||||
|
let value = self.pop();
|
||||||
|
if let Value::Bool(_) = &value {
|
||||||
|
self.local_vars.insert(name, value);
|
||||||
|
} else {
|
||||||
|
return Err(anyhow!("Expected bool, got {:?}", value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OP_DEF_DATE => {
|
||||||
|
let name = self.read_constant();
|
||||||
|
let value = self.pop();
|
||||||
|
if let Value::Date(_) = &value {
|
||||||
|
self.local_vars.insert(name, value);
|
||||||
|
} else {
|
||||||
|
return Err(anyhow!("Expected date, got {:?}", value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OP_DEF_LIST => {
|
||||||
|
let name = self.read_constant();
|
||||||
|
let value = self.pop();
|
||||||
|
if let Value::List(_) = &value {
|
||||||
|
self.local_vars.insert(name, value);
|
||||||
|
} else {
|
||||||
|
return Err(anyhow!("Expected list, got {:?}", value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OP_DEF_MAP => {
|
||||||
|
let name = self.read_constant();
|
||||||
|
let value = self.pop();
|
||||||
|
if let Value::Map(_) = &value {
|
||||||
|
self.local_vars.insert(name, value);
|
||||||
|
} else {
|
||||||
|
return Err(anyhow!("Expected map, got {:?}", value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OP_DEF_STRUCT => {
|
||||||
|
let name = self.read_constant();
|
||||||
|
let value = self.pop();
|
||||||
|
if let Value::Struct(_) = &value {
|
||||||
|
self.local_vars.insert(name, value);
|
||||||
|
} else {
|
||||||
|
return Err(anyhow!("Expected object, got {:?}", value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
OP_GET => {
|
OP_GET => {
|
||||||
|
|
@ -170,10 +280,13 @@ pub const OP_GET: u16 = 27;
|
||||||
pub const OP_DEF_I32: u16 = 28;
|
pub const OP_DEF_I32: u16 = 28;
|
||||||
pub const OP_DEF_I64: u16 = 29;
|
pub const OP_DEF_I64: u16 = 29;
|
||||||
pub const OP_DEF_U32: u16 = 30;
|
pub const OP_DEF_U32: u16 = 30;
|
||||||
pub const OP_DEF_DATE: u16 = 31;
|
pub const OP_DEF_U64: u16 = 31;
|
||||||
pub const OP_DEF_STRING: u16 = 32;
|
pub const OP_DEF_DATE: u16 = 32;
|
||||||
pub const OP_DEF_CHAR: u16 = 33;
|
pub const OP_DEF_STRING: u16 = 33;
|
||||||
pub const OP_DEF_BOOL: u16 = 34;
|
pub const OP_DEF_CHAR: u16 = 34;
|
||||||
pub const OP_DEF_LIST: u16 = 35;
|
pub const OP_DEF_BOOL: u16 = 35;
|
||||||
pub const OP_DEF_MAP: u16 = 36;
|
pub const OP_DEF_LIST: u16 = 36;
|
||||||
pub const OP_DEF_OBJ: u16 = 37;
|
pub const OP_DEF_MAP: u16 = 37;
|
||||||
|
pub const OP_DEF_STRUCT: u16 = 38;
|
||||||
|
pub const OP_DEF_F32: u16 = 39;
|
||||||
|
pub const OP_DEF_F64: u16 = 40;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue