1use crate::nvalue::NValue;
4
5#[derive(Debug,Clone,PartialEq,Copy)]
7pub enum TokenKind {
8 None,
9 Comment,
10 Comma,
11 Eol,
12 Int,
13 Number,
14 String,
15 Word,
16 Flag,
17 Eq,
18 NotEq,
19 Gt,
20 GtEq,
21 Lt,
22 LtEq,
23 Not,
24 ParenL,
25 ParenR,
26 BracketL,
27 BracketR,
28 CurBracketL,
29 CurBracketR,
30 BlockBegin,
31 BlockEnd,
32 If,
33 Else,
34 Kai,
35 Plus,
36 Minus,
37 Mul,
38 Div,
39 Mod,
40 Pow,
41 PlusStr,
42 And,
43 Or,
44 True,
45 False,
46 Break,
47 Continue,
48 For,
49 DefFunc,
50 Return,
51 DefVar,
52 Dainyu,
53}
54
55#[derive(Debug,Clone,Copy,PartialEq)]
57pub struct TokenPos {
58 pub start: i32,
59 pub end: i32,
60 pub fileno: i32,
61 pub row: i32, pub col: i32, }
64
65impl TokenPos {
66 pub fn new(start: i32, end: i32, fileno: i32) -> Self {
67 Self { start, end, fileno, row: 0, col: 0 }
68 }
69 pub fn to_string_se(&self) -> String {
70 format!("({},{})", self.start, self.end)
71 }
72}
73
74#[derive(Debug,Clone)]
76pub struct Token {
77 pub kind: TokenKind,
78 pub value: NValue,
79 pub josi: Option<String>,
80 pub pos: TokenPos,
81}
82
83impl Token {
84 pub fn new(kind: TokenKind, value:NValue, josi: Option<String>, pos: TokenPos) -> Self {
86 Self { kind, value, josi, pos }
87 }
88 pub fn new_empty() -> Self {
90 Self::new(TokenKind::None, NValue::Empty, None, TokenPos::new(0, 0, 0))
91 }
92 pub fn new_comment(comment: &str, pos: TokenPos) -> Self {
94 Self::new(TokenKind::Comment, NValue::from_str(comment), None, pos)
95 }
96 pub fn new_char(kind: TokenKind, label: char, pos: TokenPos) -> Self {
98 Self {
99 kind,
100 value: NValue::from_char(label),
101 josi: None,
102 pos,
103 }
104 }
105 pub fn new_str(kind: TokenKind, label: &str, pos: TokenPos) -> Self {
107 Self {
108 kind,
109 value: NValue::from_str(label),
110 josi: None,
111 pos,
112 }
113 }
114 pub fn as_char(&self) -> char {
115 match &self.value {
116 NValue::String(c) => if c.len() > 0 { c.chars().nth(0).unwrap_or('\0') } else { '\0' },
117 _ => '\0',
118 }
119 }
120 pub fn as_label(&self) -> String {
121 self.value.to_string()
122 }
123}
124
125impl std::fmt::Display for Token {
126 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
127 let get_value = |t: &Token| -> String {
129 match &t.josi {
130 Some(j) => { format!("{}/{}", t.value.to_string(), j) },
131 None => { format!("{}", t.value.to_string()) },
132 }
133 };
134 let t = &self;
135 let s: String = match self.kind {
136 TokenKind::None => format!("None"),
137 TokenKind::Comment => format!("Comment:{}", get_value(t)),
138 TokenKind::Comma => format!(","),
139 TokenKind::Eol => format!("Eol"),
140 TokenKind::Int => format!("Int:{}", get_value(t)),
141 TokenKind::Number => format!("Number:{}", get_value(t)),
142 TokenKind::String => format!("String:{}", get_value(t)),
143 TokenKind::Word => format!("Word:{}", get_value(t)),
144 TokenKind::Flag => format!("Flag:{}", get_value(t)),
145 TokenKind::ParenL => String::from("("),
146 TokenKind::ParenR => String::from(")"),
147 TokenKind::Eq => format!("="),
148 TokenKind::NotEq => format!("≠"),
149 TokenKind::Plus => format!("+"),
150 TokenKind::Minus => format!("-"),
151 TokenKind::Mul => format!("*"),
152 TokenKind::Div => format!("/"),
153 TokenKind::Mod => format!("%"),
154 TokenKind::Pow => format!("^"),
155 TokenKind::Gt => format!(">"),
156 TokenKind::GtEq => format!("≧"),
157 TokenKind::Lt => format!("<"),
158 TokenKind::LtEq => format!("≦"),
159 TokenKind::Not => format!("!"),
160 TokenKind::If => format!("もし"),
161 TokenKind::Else => format!("違えば"),
162 TokenKind::Kai => format!("Kai"),
163 TokenKind::BlockBegin => format!("ここから"),
164 TokenKind::BlockEnd => format!("ここまで"),
165 TokenKind::BracketL => String::from("["),
166 TokenKind::BracketR => String::from("]"),
167 TokenKind::CurBracketL => String::from("{"),
168 TokenKind::CurBracketR => String::from("}"),
169 TokenKind::True => String::from("真"),
170 TokenKind::False => String::from("偽"),
171 TokenKind::And => String::from("&&"),
172 TokenKind::Or => String::from("||"),
173 TokenKind::PlusStr => String::from("&"),
174 TokenKind::Break => String::from("抜"),
175 TokenKind::Continue => String::from("続"),
176 TokenKind::For => String::from("繰返"),
177 TokenKind::DefFunc => String::from("●関数"),
178 TokenKind::Return => String::from("戻"),
179 TokenKind::DefVar => String::from("変数"),
180 TokenKind::Dainyu => String::from("代入"),
181 };
183 write!(f, "{}", s)
184 }
185}
186
187#[allow(dead_code)]
188pub fn tokens_string(vt: &[Token]) -> String {
189 let mut res = String::new();
190 for tok in vt.iter() {
191 let s = format!("[{}]", tok);
192 res.push_str(&s);
193 }
194 format!("{}", res)
195}
196
197#[allow(dead_code)]
198pub fn tokens_string_pos(vt: &[Token]) -> String {
199 let mut res = String::new();
200 for tok in vt.iter() {
201 let s = format!("[{}]{}", tok, tok.pos.to_string_se());
202 res.push_str(&s);
203 }
204 format!("{}", res)
205}
206
207#[allow(dead_code)]
208pub fn tokens_string_lineno(vt: &[Token]) -> String {
209 let mut res = String::new();
210 for tok in vt.iter() {
211 let s = format!("[{}]({})", tok, tok.pos.row);
212 res.push_str(&s);
213 }
214 format!("{}", res)
215}