Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/arithmetic.lm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
main(){
init {
x : float
x, c, r, z, f : int
}

x := 27 - c
Expand Down
18 changes: 9 additions & 9 deletions examples/hello_world.lm
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,27 @@ main(){
a, b, c, d : float
var1234 : string
}
a := 4+3
b := 9
a := 4.0+3.0
x := 9
a := 5.25
b := -5.25
c := "test1234"
d := 1
var1234 := "test1234"
d := 1.0

while(a > b) {
a := 1
a := 1.0
}

if(a > b and c > d) {
a := 1
a := 1.0
}
else {
b := 1
b := 1.0
}

b := 1
b := 1.0

if(not b){
a := 1
a := 1.0
}
}
5 changes: 5 additions & 0 deletions inputs/test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,10 @@ read(f6f)
#+ Ejemplo de error por float invalido +#
#+ x := 1001247380987123904721309473201974012938740921374091237409127340983217094874.1234 +#

#+ Ejemplo de error por uso de variable no declarada +#
#+ nodeclarada1 := 1234 +#

#+ Ejemplo de error por asignacion de con tipos incorrectos +#
#+ a1 := 33 + 1.33 +#

a1 := convDate(01-02-1900)
58 changes: 52 additions & 6 deletions src/compiler/ast.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::grammar::types::ComparisonOp;
use crate::grammar::types::{ComparisonOp, DataType};
use std::{
array,
cell::Cell,
Expand Down Expand Up @@ -75,6 +75,7 @@ pub struct Node {
parent: Cell<Option<Rc<Node>>>,
left_child: Option<Rc<Node>>,
right_child: Option<Rc<Node>>,
pub r#type: Option<ExpressionType>,
}

impl Debug for Node {
Expand All @@ -84,12 +85,13 @@ impl Debug for Node {
}

impl Node {
pub fn new_leaf(value: NodeValue) -> Self {
pub fn new_leaf(value: NodeValue, node_type: Option<ExpressionType>) -> Self {
Self {
value,
parent: Cell::new(None),
left_child: None,
right_child: None,
r#type: node_type,
}
}
}
Expand All @@ -109,6 +111,33 @@ impl Display for NodeValue {
}
}

#[derive(Clone, Debug, PartialEq)]
pub enum ExpressionType {
Float,
Int,
String,
}

impl Display for ExpressionType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Float => write!(f, "FLOAT"),
Self::Int => write!(f, "INT"),
Self::String => write!(f, "STRING"),
}
}
}

impl From<DataType> for ExpressionType {
fn from(value: DataType) -> Self {
match value {
DataType::FloatType(_) => ExpressionType::Float,
DataType::IntType(_) => ExpressionType::Int,
DataType::StringType(_) => ExpressionType::String,
}
}
}

#[derive(Clone, Debug)]
pub enum AstAction {
Plus,
Expand Down Expand Up @@ -182,7 +211,9 @@ impl From<ComparisonOp> for AstAction {
impl Default for Ast {
fn default() -> Self {
Self {
tree: array::from_fn(|_| Rc::new(Node::new_leaf(NodeValue::Value("".to_string())))),
tree: array::from_fn(|_| {
Rc::new(Node::new_leaf(NodeValue::Value("".to_string()), None))
}),
expression_stack: Vec::new(),
term_stack: Vec::new(),
comparision_op_stack: Vec::new(),
Expand Down Expand Up @@ -215,6 +246,7 @@ impl Ast {
left_child_ptr: AstNodeRef,
right_child_ptr: AstNodeRef,
dest_ptr: AstPtr,
r#type: Option<ExpressionType>,
) -> Rc<Node> {
let left_child = match left_child_ptr {
AstNodeRef::Ptr(ptr) => self.tree.get(ptr as usize).cloned(),
Expand All @@ -230,6 +262,7 @@ impl Ast {
parent: Cell::new(None),
left_child: left_child.clone(),
right_child: right_child.clone(),
r#type,
});

if let Some(left) = left_child {
Expand All @@ -243,8 +276,13 @@ impl Ast {
node
}

pub fn create_leaf(&mut self, value: String, dest_ptr: AstPtr) -> Rc<Node> {
let leaf = Rc::new(Node::new_leaf(NodeValue::Value(value)));
pub fn create_leaf(
&mut self,
value: String,
dest_ptr: AstPtr,
node_type: Option<ExpressionType>,
) -> Rc<Node> {
let leaf = Rc::new(Node::new_leaf(NodeValue::Value(value), node_type));
self.tree[dest_ptr as usize] = leaf.clone();
leaf
}
Expand Down Expand Up @@ -273,7 +311,15 @@ impl Ast {
) -> Result<usize, io::Error> {
let node_name = format!("n{node_count:0>3}");
writeln!(file, " {node_name:0>3} ;")?;
writeln!(file, " {node_name:0>3} [label=\"{:}\"] ;", node.value)?;
writeln!(
file,
" {node_name:0>3} [label=\"{}{}\"] ;",
node.value,
node.r#type
.as_ref()
.map(|t| format!(" | {t}"))
.unwrap_or_default()
)?;
if let Some(left_child) = &node.left_child {
node_count += 1;
writeln!(file, " {node_name} -- n{node_count:0>3} ;")?;
Expand Down
100 changes: 63 additions & 37 deletions src/compiler/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,13 @@ impl CompilerContext {
self.symbol_table.contains(symbol)
}

pub fn get_symbol_type(&self, symbol_name: &str) -> Option<Option<DataType>> {
self.symbol_table
.iter()
.find(|x| x.name == symbol_name)
.map(|x| x.data_type.clone())
}

pub fn create_ast_graph(&mut self, from: AstPtr) -> Result<(), CompilerError> {
self.ast
.graph_ast(
Expand All @@ -167,66 +174,85 @@ impl CompilerContext {
}
}

#[derive(Clone, Debug)]
pub enum SymbolTableElement {
VarDeclaration(String, DataType, usize),
IntLiteral(TokenIntLiteral),
FloatLiteral(TokenFloatLiteral),
StringLiteral(TokenStringLiteral),
#[derive(Default)]
pub struct SymbolTableElement {
pub name: String,
pub data_type: Option<DataType>,
pub value: Option<String>,
pub length: Option<usize>,
}

impl Display for SymbolTableElement {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::FloatLiteral(float) => write!(
f,
"{}|CONST_FLOAT|{}|{}",
float.original,
float.original,
float.original.len()
)?,
Self::IntLiteral(int) => {
write!(f, "{}|CONST_INT|{}|{}", int, int, int.to_string().len())?
}
Self::StringLiteral(string) => {
write!(f, "{}|CONST_STRING|{}|{}", string, string, string.len())?
}
Self::VarDeclaration(token, r#type, length) => {
write!(f, "{}|{}|-|{}", token, r#type, length)?
}
};
Ok(())
let name = &self.name;
let data_type = self
.data_type
.as_ref()
.map(|r#type| r#type.to_string())
.unwrap_or_else(|| String::from("-"));
let value = self
.value
.as_ref()
.cloned()
.unwrap_or_else(|| String::from("-"));
let length = self
.length
.map(|length| length.to_string())
.unwrap_or_else(|| String::from("-"));

write!(f, "{name}|{data_type}|{value}|{length}")
}
}

impl PartialEq for SymbolTableElement {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::FloatLiteral(token0), Self::FloatLiteral(token1)) => token0 == token1,
(Self::IntLiteral(token0), Self::IntLiteral(token1)) => token0 == token1,
(Self::StringLiteral(token0), Self::StringLiteral(token1)) => token0 == token1,
(Self::VarDeclaration(token0, _, _), Self::VarDeclaration(token1, _, _)) => {
token0 == token1
}
_ => false,
}
self.name == other.name
}
}

impl Eq for SymbolTableElement {}

impl From<TokenIntLiteral> for SymbolTableElement {
fn from(value: TokenIntLiteral) -> Self {
Self::IntLiteral(value)
let mut name = String::with_capacity(value.original.len() + 1);
name.push('_');
name.push_str(&value.original);

Self {
name,
data_type: None,
value: Some(value.original),
length: None,
}
}
}

impl From<TokenFloatLiteral> for SymbolTableElement {
fn from(value: TokenFloatLiteral) -> Self {
Self::FloatLiteral(value)
let mut name = String::with_capacity(value.original.len() + 1);
name.push('_');
name.push_str(&value.original);

Self {
name: value.original.clone(),
data_type: None,
value: Some(value.original),
length: None,
}
}
}

impl From<TokenStringLiteral> for SymbolTableElement {
fn from(value: TokenStringLiteral) -> Self {
Self::StringLiteral(value)
let mut name = String::with_capacity(value.len() + 1);
name.push('_');
name.push_str(&value);

Self {
name,
data_type: None,
length: Some(value.len()),
value: Some(value),
}
}
}
4 changes: 4 additions & 0 deletions src/compiler/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ pub enum CompilerError {
Lexer(String),
#[error("Context error: {0}")]
Context(String),
#[error("Type mismatch error: {0}")]
TypeMismatch(String),
#[error("Use of undeclared variable: {0}")]
UndeclaredVariable(String),
#[error("IO error: {0}")]
IO(String),
#[error("Compiler internal error: {0}. This is a bug.")]
Expand Down
Loading