I've come up with a partial token grammar for the language as you've described it, in
EBNF notation, though some of it will need to be expanded upon or changed as the language design progresses. This should give you a leg up on defining the lexical analyzer when the time comes to implement it.
Code:
token ::= <keyword> | <number> | <char> | <string> | <identifier> |
<assignment-op> | <arithmetic-op> | <bitwise-op> | <logical-op> |
<paren> | <colon> | <right-arrow> | <angle-bracket> | <brace> |
<comma> | <period>
keyword ::= <base-type> | "if" | "elif" | "else" |
"loop" | "while" | "once" | "for" |
"fn" | "let" | "mut" | "return" | "object" |
"import" | "as" | "alias" |
"and" | "or" | "not"
base-type ::= "i8"| "i16" | "i32" | "i64" |"f32" | "f64" |
"bool" | "char" | "string" | "ptr" | "Array" | "Vector"
identifer ::= <alpha><alphanum>*
alpha ::= "A" | "a" |"B" | "b" | "C" | "c" ... | Z" | "z"
alphanum ::= <alpha> | <digit>
bit ::= "0" | "1"
octal-digit ::= <bit> | "2" | "3" | "4" | "5" | "6" | "7"
digit ::= <octal-digit> | "8" | "9"
hex-digit ::= <digit> | "A" | "a" |"B" | "b" | "C" | "c" | "D" | "d" | "E" | "e" | "F" | "f"
number ::= <integer> | <float>
integer ::= <digit>+ | "0b" <bit> | "0" <octal-digit> | "0x" <hex-digit>
float ::= <integer> <period> <integer> {("E"|"e") <integer>}
char ::= <quote> {<printable-character>} <quote>
string ::= <double-quote> {(<printable-character> | '\"')}* <double-quote>
assignment-op ::= "="
arithmetic-op ::= "+" | "-" | "*" | "/"
bitwise-op ::= "<<" | ">>" | "&" | "|"
logical-op ::= "==" | "<" | ">" | "<=" | ">="
paren ::= <lparen> | <rparen>
lparen ::= "("
rparen ::= ")"
angle-bracket ::= <langle> | <rangle>
lparen ::= "<"
rparen ::= ">"
brace ::= <lbrace> | <rbrace>
lbrace ::= "{"
rbrace ::= "}"
colon ::= ":"
right-arrow ::= "->"
comma ::= ","
period ::= "."
quote ::= "'"
double-quote ::= '"'