Skip to content

Commit

Permalink
Implements STR, def STR comamnds
Browse files Browse the repository at this point in the history
  • Loading branch information
kujirahand committed Oct 18, 2022
1 parent 840e881 commit 6792577
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 15 deletions.
42 changes: 39 additions & 3 deletions src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,19 @@ fn read_upper_command(cur: &mut TokenCursor, song: &mut Song) -> Token {
cur.prev(); // back 1char
let cmd = cur.get_word();

// check variables
let sval: SValue = match song.variables.get(&cmd) {
None => SValue::None,
Some(sval) => sval.clone(),
};
match sval {
SValue::Str(src, line_no) => {
let tokens = lex(song, &src, line_no);
return Token::new_tokens(TokenType::Tokens, line_no, tokens);
},
_ => {},
}

// <UPPER_COMMANDS>
// Track & Channel
if cmd == "TR" || cmd == "TRACK" || cmd == "Track" { // @ トラック変更 TR=番号 範囲:1-
Expand All @@ -88,8 +101,9 @@ fn read_upper_command(cur: &mut TokenCursor, song: &mut Song) -> Token {
if cmd == "DIV" || cmd == "Div" { return read_command_div(cur, song) } // @ 連符 (例 DIV{ceg} )
if cmd == "SUB" || cmd == "Sub" { return read_command_sub(cur, song) } // @ タイムポインタを戻す (例 SUB{ceg} egb)

if cmd == "INT" || cmd == "Int" { return read_def_int(cur, song); } // @ 変数を定義 (例 INT TestValue=30)
if cmd == "KF" || cmd == "KeyFlag" { return read_key_flag(cur, song); } // @ 臨時記号を設定 - KeyFlag=(a,b,c,d,e,f,g) KeyFlag[=][+|-](note)
if cmd == "INT" || cmd == "Int" { return read_def_int(cur, song); } // @ 変数を定義 (例 INT TestValue=30)
if cmd == "STR" || cmd == "Str" { return read_def_str(cur, song); } // @ 文字列変数を定義 (例 STR A={cde})

// controll change
if cmd == "M" || cmd == "Modulation" { return read_command_cc(cur, 1, song); } // @ モジュレーション 範囲: 0-127
Expand Down Expand Up @@ -147,7 +161,7 @@ fn read_upper_command(cur: &mut TokenCursor, song: &mut Song) -> Token {
}
// </UPPER_COMMANDS>
song.logs.push(format!("[ERROR]({}) Unknown command: {}", cur.line, cmd));
return Token::new_unknown(&cmd);
return Token::new_empty(&cmd);
}

fn read_arg_value(cur: &mut TokenCursor, song: &mut Song) -> SValue {
Expand Down Expand Up @@ -332,7 +346,7 @@ fn read_def_int(cur: &mut TokenCursor, song: &mut Song) -> Token {
let var_name = cur.get_word();
if var_name == "" {
song.logs.push(format!("[ERROR]({}): INT command should use Upper case like \"Test\".", cur.line));
return Token::new_unknown("Failed to def INT");
return Token::new_empty("Failed to def INT");
}
cur.skip_space();
if cur.eq_char('=') { cur.next(); }
Expand All @@ -344,6 +358,28 @@ fn read_def_int(cur: &mut TokenCursor, song: &mut Song) -> Token {
tok
}

fn read_def_str(cur: &mut TokenCursor, song: &mut Song) -> Token {
cur.skip_space();
let var_name = cur.get_word();
if var_name == "" {
song.logs.push(format!("[ERROR]({}): STR command should use Upper case like \"Test\"", cur.line));
return Token::new_empty("Failed to def STR");
}
cur.skip_space();
if cur.eq_char('=') { cur.next(); }
cur.skip_space();
if !cur.eq_char('{') {
song.logs.push(format!("[ERROR]({}): STR command should set string", cur.line));
return Token::new_empty("Failed to def STR");
}
let line_no = cur.line;
let data_str = cur.get_token_nest('{', '}');
let var_value = SValue::from_str_and_tag(&data_str, line_no);
let tok = Token::new_empty("STR");
song.variables.insert(var_name, var_value);
tok
}

fn read_command_sub(cur: &mut TokenCursor, song: &mut Song) -> Token {
cur.skip_space();
let block = cur.get_token_nest('{', '}');
Expand Down
11 changes: 8 additions & 3 deletions src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub fn exec(song: &mut Song, tokens: &Vec<Token>) -> bool {
println!("{:3}:exec:{:?}", pos, t);
}
match t.ttype {
TokenType::Unknown => {
TokenType::Empty => {
// unknown
},
TokenType::Error => {
Expand Down Expand Up @@ -186,12 +186,17 @@ pub fn exec(song: &mut Song, tokens: &Vec<Token>) -> bool {
},
TokenType::Div => exec_div(song, t),
TokenType::Sub => exec_sub(song, t),
TokenType::KeyFlag => song.key_flag = t.data[0].to_int_array(),
TokenType::DefInt => {
let var_key = t.data[0].to_s().clone();
let var_val = var_extract(&t.data[1], song);
song.variables.insert(var_key, var_val);
},
TokenType::KeyFlag => song.key_flag = t.data[0].to_int_array(),
TokenType::DefStr => {
let var_key = t.data[0].to_s().clone();
let var_val = var_extract(&t.data[1], song);
song.variables.insert(var_key, var_val);
},
}
pos += 1;
}
Expand All @@ -200,7 +205,7 @@ pub fn exec(song: &mut Song, tokens: &Vec<Token>) -> bool {

fn var_extract(val: &SValue, song: &mut Song) -> SValue {
match val {
SValue::Str(s) => {
SValue::Str(s, _) => {
if s.starts_with('=') && s.len() >= 2 {
let key = &s[1..];
match song.variables.get(key) {
Expand Down
21 changes: 16 additions & 5 deletions src/svalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#[derive(Debug,Clone)]
pub enum SValue {
Int(isize),
Str(String),
Str(String, isize),
Array(Vec<SValue>),
None,
}
Expand All @@ -23,27 +23,38 @@ impl SValue {
Self::Int(v)
}
pub fn from_s(s: String) -> Self {
Self::Str(s)
Self::Str(s, 0)
}
pub fn from_str(s: &str) -> Self {
Self::Str(String::from(s))
Self::Str(String::from(s), 0)
}
pub fn from_str_and_tag(s: &str, tag: isize) -> Self {
Self::Str(String::from(s), tag)
}
pub fn to_i(&self) -> isize {
match self {
Self::Int(i) => *i,
Self::Str(s) => s.parse().unwrap_or(0),
Self::Str(s, _) => s.parse().unwrap_or(0),
Self::None => 0,
_ => 0,
}
}
pub fn to_s(&self) -> String {
match self {
Self::Int(i) => i.to_string(),
Self::Str(s) => s.clone(),
Self::Str(s, _) => s.clone(),
Self::None => String::new(),
_ => String::new(),
}
}
pub fn get_str_and_tag(&self) -> (String, isize) {
match self {
Self::Int(i) => (i.to_string(), 0),
Self::Str(s, no) => { (s.clone(), *no) },
Self::None => (String::new(), 0),
_ => (String::new(), 0),
}
}
pub fn to_int_array(&self) -> Vec<isize> {
match self {
Self::Array(a) => {
Expand Down
12 changes: 8 additions & 4 deletions src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::svalue::SValue;
#[derive(Debug)]
pub enum TokenType {
Error,
Unknown,
Empty,
Note,
NoteN,
Rest,
Expand Down Expand Up @@ -33,8 +33,9 @@ pub enum TokenType {
Tokens, // should run children toknes
Div,
Sub,
DefInt,
KeyFlag,
DefInt,
DefStr,
}

#[allow(dead_code)]
Expand All @@ -53,8 +54,11 @@ impl Token {
pub fn new_value(ttype: TokenType, value: isize) -> Self {
Self { ttype, value, data: vec![], children: None }
}
pub fn new_unknown(cmd: &str) -> Self {
Self::new(TokenType::Unknown, 0, vec![SValue::from_s(cmd.to_string())])
pub fn new_tokens(ttype: TokenType, value: isize, tokens: Vec<Token>) -> Self {
Self { ttype, value, data: vec![], children: Some(tokens) }
}
pub fn new_empty(cmd: &str) -> Self {
Self::new(TokenType::Empty, 0, vec![SValue::from_s(cmd.to_string())])
}
pub fn new_sysex(a: Vec<isize>) -> Self {
let mut sa: Vec<SValue> = vec![];
Expand Down

0 comments on commit 6792577

Please sign in to comment.