Added string support

This commit is contained in:
2023-04-05 02:32:21 -04:00
parent 0a98c96440
commit 462eaea782
2 changed files with 84 additions and 4 deletions

View File

@@ -26,7 +26,7 @@ power : call (POW factor)*
call : atom (LPAREN (expr (COMMA expr)*)? RPAREN)?
atom : INT|FLOAT|IDENTIFIER
atom : INT|FLOAT|STRING|IDENTIFIER
: LPAREN expr RPAREN
: for-expr
: while-expr

View File

@@ -109,6 +109,7 @@ class Position:
# Token types
TT_INT = "INT"
TT_FLOAT = "FLOAT"
TT_STRING = "STRING"
TT_IDENTIFIER = "IDENTIFIER"
TT_KEYWORD = "KEYWORD"
TT_PLUS = "PLUS"
@@ -195,6 +196,8 @@ class Lexer:
tokens.append(self.make_number())
elif self.current_char in LETTERS:
tokens.append(self.make_identifier())
elif self.current_char == '"':
tokens.append(self.make_string())
elif self.current_char == '+':
tokens.append(Token(TT_PLUS, pos_start=self.pos))
self.advance()
@@ -261,6 +264,34 @@ class Lexer:
else:
return Token(TT_FLOAT, float(num_str), pos_start, self.pos)
def make_string(self):
string_ = ''
pos_start = self.pos.copy()
escape_character = False
self.advance()
escape_characters = {
'n': '\n',
't': '\t',
'r': '\r',
'b': '\b',
'f': '\f'
}
while self.current_char is not None and (self.current_char != '"' or escape_character):
if escape_character:
string_ += escape_characters.get(self.current_char, self.current_char)
else:
if self.current_char == '\\':
escape_character = True
else:
string_ += self.current_char
self.advance()
escape_character = False
self.advance()
return Token(TT_STRING, string_, pos_start, self.pos)
def make_dash_operators(self):
token_type = TT_MINUS
pos_start = self.pos.copy()
@@ -341,6 +372,16 @@ class NumberNode:
return f"{self.token}"
class StringNode:
def __init__(self, token):
self.token = token
self.pos_start = self.token.pos_start
self.pos_end = self.token.pos_end
def __repr__(self):
return f'{self.token}'
class VarAccessNode:
def __init__(self, var_name_token):
self.var_name_token = var_name_token
@@ -563,6 +604,10 @@ class Parser:
result.register_advancement()
self.advance()
return result.success(NumberNode(token))
elif token.type == TT_STRING:
result.register_advancement()
self.advance()
return result.success(StringNode(token))
elif token.type == TT_IDENTIFIER:
result.register_advancement()
self.advance()
@@ -1183,6 +1228,36 @@ class Number(Type):
return str(self.value)
class String(Type):
def __init__(self, value):
super().__init__()
self.value = value
def added_to(self, other):
if isinstance(other, String):
return String(self.value + other.value).set_context(self.context), None
else:
return None, Type.illegal_operation(self, other)
def multiplied_by(self, other):
if isinstance(other, Number):
return String(self.value * other.value).set_context(self.context), None
else:
return None, Type.illegal_operation(self, other)
def is_true(self):
return len(self.value) > 0
def copy(self):
copy = String(self.value)
copy.set_pos(self.pos_start, self.pos_end)
copy.set_context(self.context)
return copy
def __repr__(self):
return f'"{self.value}"'
class Function(Type):
def __init__(self, name, body_node, arg_names):
super().__init__()
@@ -1233,6 +1308,7 @@ class Function(Type):
def __repr__(self):
return f"<Function: '{self.name}'>"
####################
# CONTEXT
####################
@@ -1280,7 +1356,13 @@ class Interpreter:
def visit_NumberNode(self, node, context):
return RuntimeResult().success(
Number(node.token.value).set_context(context).set_pos(node.pos_start, node.pos_end))
Number(node.token.value).set_context(context).set_pos(node.pos_start, node.pos_end)
)
def visit_StringNode(self, node: StringNode, context: Context):
return RuntimeResult().success(
String(node.token.value).set_context(context).set_pos(node.pos_start, node.pos_end)
)
def visit_VarAccessNode(self, node, context):
result = RuntimeResult()
@@ -1474,8 +1556,6 @@ class Interpreter:
return result.success(return_value)
####################
# RUNNER
####################