Skip to content

Commit

Permalink
feat: 🚀 ParseInt function
Browse files Browse the repository at this point in the history
  • Loading branch information
JoseLorenzana272 committed Oct 12, 2024
1 parent 02b4947 commit 8be1337
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 28 deletions.
27 changes: 22 additions & 5 deletions JS_Analyzer_parts/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -657,13 +657,10 @@ visitVariableAssign(node) {
} else if (node.callee.id === 'toString'){
this.code.comment(`Llamada a función: ${node.callee.id}`);

// Evaluar el argumento
node.args[0].accept(this);

// El valor y su tipo deberían estar en el stack ahora
const valor = this.code.popObject(r.A0);

// Determinar el tipo y ponerlo en A1
if (valor.type === 'int') {
this.code.li(r.A1, 1);
} else if (valor.type === 'bool') {
Expand All @@ -674,12 +671,32 @@ visitVariableAssign(node) {
this.code.li(r.A1, 4);
}

// Llamar a la función toString
this.code.callBuiltin('toString');

// Pushear el descriptor del objeto retornado
this.code.pushObject({ type: 'string', length: 4 });

this.code.comment('Fin de llamada a función');
}else if (node.callee.id === 'parseInt') {

this.code.comment(`Llamada a función: ${node.callee.id}`);

node.args[0].accept(this);
const isFloat = this.code.getTopObject().type === 'float';
const valor = this.code.popObject(isFloat ? f.FA0 : r.A0);

if (valor.type === 'string' || valor.type === 'int') {

this.code.callBuiltin('parseIntString');

this.code.pushObject({ type: 'int', length: 4 });
}else if(valor.type === 'float'){
this.code.callBuiltin('parseIntFloat');

this.code.pushObject({ type: 'int', length: 4 });
}else {
throw new Error('TypeError: parseInt() requires a string, float, or int argument');
}

this.code.comment('Fin de llamada a función');
}
}
Expand Down
128 changes: 105 additions & 23 deletions RISC/builtins.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { registers as r } from "./constants.js"
import { registers as r, floatRegisters as f } from "./constants.js"
import { Generador } from "./generator.js"

/**
Expand Down Expand Up @@ -111,33 +111,30 @@ export const toString = (code) => {
code.addLabel(intEnd)
code.j(endFunction)

// Caso bool
// Caso float

// Caso bool (optimizado)
const copyString = code.getLabel()
const endCopyString = code.getLabel()
code.addLabel(boolCase)
code.beqz(r.A0, falseBranch)
// true
code.li(r.T1, 116) // 't'
code.sb(r.T1, r.HP)
code.li(r.T1, 114) // 'r'
code.sb(r.T1, (r.HP))
code.li(r.T1, 117) // 'u'
code.sb(r.T1, (r.HP))
code.li(r.T1, 101) // 'e'
code.sb(r.T1, (r.HP))
code.addi(r.HP, r.HP, 4)
code.j(endFunction)
code.la(r.T1, 'true_str')
code.j(copyString)

code.addLabel(falseBranch)
code.li(r.T1, 102) // 'f'
code.sb(r.T1, r.HP)
code.li(r.T1, 97) // 'a'
code.sb(r.T1, (r.HP))
code.li(r.T1, 108) // 'l'
code.sb(r.T1, (r.HP))
code.li(r.T1, 115) // 's'
code.sb(r.T1, (r.HP))
code.li(r.T1, 101) // 'e'
code.sb(r.T1, (r.HP))
code.addi(r.HP, r.HP, 5)
code.la(r.T1, 'false_str')

// Copiar la cadena correspondiente al heap

code.addLabel(copyString)
code.lb(r.T2, (r.T1))
code.beqz(r.T2, endCopyString)
code.sb(r.T2, (r.HP))
code.addi(r.HP, r.HP, 1)
code.addi(r.T1, r.T1, 1)
code.j(copyString)
code.addLabel(endCopyString)
code.j(endFunction)

// Caso char
Expand Down Expand Up @@ -291,11 +288,96 @@ export const toUpperCase = (code) => {
code.comment('Fin de la cadena')
}

export const parseIntString = (code) => {
// A0 -> dirección en heap de la cadena a convertir
// result -> push en el stack el valor entero resultante

code.comment('Inicializando el resultado en 0')
code.li(r.T0, 0)

code.comment('Verificando si el primer carácter es un signo negativo')
code.lb(r.T1, r.A0)
code.li(r.T2, 45) // ASCII del signo '-'
const notNegative = code.getLabel()
code.bne(r.T1, r.T2, notNegative)
code.addi(r.A0, r.A0, 1) // Si es negativo, avanzamos al siguiente carácter
code.addLabel(notNegative)

const parseLoop = code.getLabel()
const endParse = code.getLabel()
const isNegative = code.getLabel()
const pushResult = code.getLabel()

code.comment('Iterando sobre cada carácter de la cadena')
code.addLabel(parseLoop)
code.lb(r.T1, r.A0)
code.beqz(r.T1, endParse) // Si llegamos al final de la cadena (carácter nulo), terminamos


code.comment('Convirtiendo el carácter ASCII a su valor numérico')
code.addi(r.T1, r.T1, -48) // ASCII '0' = 48

code.comment('Verificando si el carácter es un dígito válido (0-9)')
code.li(r.T2, 0)
code.blt(r.T1, r.T2, endParse) // Si es menor que 0, terminamos
code.li(r.T2, 9)
code.bgt(r.T1, r.T2, endParse) // Si es mayor que 9, terminamos

code.comment('Multiplicando el resultado acumulado por 10 y sumando el nuevo dígito')
code.li(r.T3, 10)
code.mul(r.T0, r.T0, r.T3)
code.add(r.T0, r.T0, r.T1)

code.comment('Avanzando al siguiente carácter')
code.addi(r.A0, r.A0, 1)
code.j(parseLoop)



code.addLabel(endParse)

code.comment('Verificando si el número es negativo')
code.lb(r.T1, r.A0)
code.li(r.T2, 45) // ASCII del signo '-'
code.bne(r.T1, r.T2, pushResult)

code.addLabel(isNegative)
code.comment('Si es negativo, negamos el resultado antes de guardarlo')
code.neg(r.T0, r.T0)

code.addLabel(pushResult)
code.comment('Guardando el resultado en el stack')
code.push(r.T0)

code.comment('Retornando de la función')
code.jr(r.RA)
}

export const parseIntFloat = (code) => {
// A0 -> contiene el valor flotante a convertir
// result -> push en el stack el valor entero resultante

code.comment('Convertir float a int')

// Mover el valor flotante de A0 a FT0
code.fmvs(f.FT0, f.FA0)

// Truncar el float a int
code.fcvtws(r.T0, f.FT0)

code.comment('Guardando el resultado en el stack')
code.push(r.T0)

code.comment('Retornando de la función')
code.jr(r.RA)
}

export const builtins = {
concatString: concatString,
typeof: typeOf,
toString: toString,
toLowerCase: toLowerCase,
toUpperCase: toUpperCase,
parseIntString: parseIntString,
parseIntFloat: parseIntFloat,
}
24 changes: 24 additions & 0 deletions RISC/generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,18 @@ export class Generador {
this.instrucciones.push(new Instruction('fli.s', rd, inmediato))
}

flt(rd, rs1, rs2) {
this.instrucciones.push(new Instruction('flt.s', rd, rs1, rs2))
}

fcvtsw(rd, rs1) {
this.instrucciones.push(new Instruction('fcvt.s.w', rd, rs1))
}

fcvtws (rd, rs1) {
this.instrucciones.push(new Instruction('fcvt.w.s', rd, rs1))
}

fmv(rd, rs1) {
this.instrucciones.push(new Instruction('fmv.s', rd, rs1))
}
Expand All @@ -105,6 +117,14 @@ export class Generador {
this.instrucciones.push(new Instruction('fcvt.s.w', rd, rs1))
}

fneg(rd, rs1) {
this.instrucciones.push(new Instruction('fneg', rd, rs1))
}

fmvs(rd, rs1) {
this.instrucciones.push(new Instruction('fmv.s', rd, rs1))
}


/* ---------------- Instrucciones Relacionales --------------------- */

Expand Down Expand Up @@ -258,6 +278,10 @@ export class Generador {
this.instrucciones.push(new Instruction('ret'))
}

jr(rs1) {
this.instrucciones.push(new Instruction('jr', rs1))
}

/* ------------------------------------------------------------------- */

/* ------------------------ Instrucción de Break ---------------------- */
Expand Down

0 comments on commit 8be1337

Please sign in to comment.