Skip to content
This repository has been archived by the owner on Jul 7, 2021. It is now read-only.

Commit

Permalink
🔖 v0.0.1.dev1 (from dev)
Browse files Browse the repository at this point in the history
Updates
------------
- Added variables
- Temporal variable created!
- Now you can ask and store the answer (Pregunta y guardalo)
- Code comments using ( comentario )
- Ignored some dialog auxiliary chars: [ . , y ]
  • Loading branch information
CosasDePuma authored May 17, 2019
2 parents 8e49c7d + 42cff4b commit 4ff935b
Show file tree
Hide file tree
Showing 20 changed files with 328 additions and 45 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
venv
build
*.pyc
*.spec
*.egg*
src/__pycache__
lib/__pycache__
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# :chart_with_upwards_trend: CHANGELOG
---

### 0.0.1.dev1
##### May 17th, 2019

###### Updates
- [x] Added variables
- [x] Temporal variable created!
- [x] Now you can ask and store the answer (Pregunta y guardalo)
- [x] Code comments using *( comentario )*
- [x] Ignored some dialog auxiliary chars: *[ . , y ]*
44 changes: 31 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,48 @@ EXE=alfred
SRC=src
LIB=lib
DIST=dist
TEST=test
BUILD=build
EXAMPLE=example

VERSION=$(shell cat VERSION)
BINARY=$(DIST)/$(EXE)-$(VERSION)

CC=pyinstaller
CCXFLAGS=--onefile --clean
CCDFLAGS=--add-data $(LIB)/lexer.py:.
CCCFLAGS=--name $(EXE) --paths $(LIB) --distpath $(DIST) --workpath $(BUILD)
CCCFLAGS=--name $(EXE)-$(VERSION) --paths $(LIB) --distpath $(DIST) --workpath $(BUILD)
CCDFLAGS=--add-data $(LIB)/lexer.py:. --add-data $(LIB)/nodes.py:. --add-data $(LIB)/symbols.py:.

.PHONY: all
all: $(DIST)/$(EXE)
all: $(BINARY)

$(DIST)/$(EXE): $(SRC)/$(EXE).py
$(BINARY): $(SRC)/$(EXE).py
$(CC) $(CCCFLAGS) $(CCDFLAGS) $(CCXFLAGS) $<

.PHONY: test
test: $(DIST)/$(EXE)
./$< $(TEST)/helloworld.alf
.PHONY: install
install: setup.py
python $< $@

.PHONY: uninstall
uninstall: setup.py
pip $@ --yes $(EXE)

.PHONY: test-bin test-cli
test-bin: $(BINARY) $(EXAMPLE)/*
for filetest in $^; do \
echo "Example: $${filetest}"; ./$< $${filetest}; echo; done

test-cli: $(EXAMPLE)/*
for filetest in $^; do \
echo "Example: $${filetest}"; $(EXE) $${filetest}; echo; done

.PHONY: clean drop purge mrproper
clean:
rm -rf $(BUILD)/*
find . -name "*.pyc" -delete
find . -name "__pycache__" -delete
find . -name "$(EXE).spec" -delete
find . -type f -name "*.pyc" -delete
find . -type f -name "*.egg" -delete
find . -type f -name "$(EXE).spec" -delete
find . -path "./$(BUILD)/*" -exec rm -rf {} +
find . -type d -name "$(EXE).egg-info" -exec rm -rf {} +
find . -type d -name "__pycache__" ! -path "./venv/*" -exec rm -rf {} +
purge: clean
find $(DIST) -name $(EXE) -delete
find . -path "./$(DIST)/*" -exec rm -rf {} +
mrproper: purge
Empty file added README.md
Empty file.
22 changes: 22 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# :memo: TODO
---

Estructura:
- [x] Asignar variables
- [x] Evaluar variables
- [ ] Funciones (¿Módulos en una carpeta especial?)
- [x] Comentarios
- [ ] Añadir acentos (UTF-8)
Instrucciones:
- [x] Di (println)
- [x] Escribe (print)
- [x] Pregunta (input)
- [x] Guarda

Control:
- [ ] If
- [ ] If .. Else
- [ ] If .. Else If
- [ ] If .. Else If .. Else
- [ ] While
- [ ] For
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.0.1.dev1
Binary file renamed dist/alfred → dist/alfred-0.0.1.dev1
Binary file not shown.
7 changes: 7 additions & 0 deletions example/escribe.alf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Alfred.
(La instrucción "Escribe"
muestra el texto sin un salto de línea)
Escribe "Un \"cachito\" de texto ".
(La instrucción "Di"
muestra el texto con un salto de línea)
Di "y otra porción.".
4 changes: 4 additions & 0 deletions example/holamundo.alf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(Todos los programas
empiezan llamando a Alfred)

Alfred, di "¡Hola Batman!".
12 changes: 12 additions & 0 deletions example/pregunta.alf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Alfred,

(Alfred puede preguntar para recibir datos
por la entrada estándar.
La respuesta se guarda en una variable temporal
y has de pedirle que te la guarde en otro lado)
Pregunta "¿Cuál es tu nombre?: " y guardalo en nombre.
Escribe "Encantado de conocerte ", escribe nombre y di ".".

(También puede preguntar sin decir nada)
Escribe "¿Te apetecen magdalenas? ".
Pregunta y di "¡Pues ya me las he comido todas!".
1 change: 0 additions & 1 deletion lib/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@

41 changes: 30 additions & 11 deletions lib/lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,47 @@
IGNORECASE = 0b10

reserved = {
"alfred": "ALFRED"
"alfred": "ALFRED",
"di": "PRINTLN",
"en": "IN",
"escribe": "PRINT",
"guardalo": "STORE",
"pregunta": "INPUT"
}
tokens = [
"ID"
"ID",
"STRING",
"INTEGER"
] + list(reserved.values())

def Lexer():
t_ignore = "., \t"
t_ignore = ".,y"

t_ignore_COMMENT = r'\(([^\)])*\)'
t_ignore_WHITESPACE = r'\s+'

def t_ID(t):
r'[a-zA-Z][a-zA-Z0-9_]+'
value = t.value.lower()
t.type = reserved.get(value,"ID")
r'[a-zA-Z][a-zA-Z0-9_]*'
t.value = t.value.lower()
t.type = reserved.get(t.value,"ID")
return t

def t_STRING(t):
r'"([^"\\]|\\.)*"'
t.value = t.value[1:-1]
t.value = t.value.replace("\\\"", "\"")
t.type = reserved.get(t.value,"STRING")
return t

def t_newline(t):
r'\n+'
t.lexer.lineno += len(t.value)
def t_INTEGER(t):
r'[+-]?[0-9]+'
t.value = int(t.value)
t.type = reserved.get(t.value,"INTEGER")
return t

def t_error(t):
print("[Error] Caracter inválido ({},{}): {}".format(
lexer.lexpos, lexer.lineno, t.value[0]))
print("[Error] Caracter inválido ({},~{}): {}".format(
lexer.lineno, lexer.lexpos, t.value[0]))
t.lexer.skip(1)


Expand Down
72 changes: 72 additions & 0 deletions lib/nodes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
from symbols import symbols,_tmpvar

class Node():
def eval(self):
raise NotImplementedError()

class InstructionList(Node):
def __init__(self, child=list()):
self.child = child
def __repr__(self):
return "<InstructionList {}>".format(self.child)
def __iter__(self):
return iter(self.child)
def eval():
ret = list()
for instruction in self.child:
result = instruction.eval()
if res is not None:
ret.append(result)
return ret

class Primitive(Node):
def __init__(self,value):
self.value = value
def __repr__(self):
return "<Primitive {} ({})>".format(self.value, self.value.__class__)
def eval(self):
return self.value

class Identifier(Node):
def __init__(self,name):
self.name = name
def __repr__(self):
return "<Identifier {} ({})>".format(self.name, self.eval())
def eval(self):
return symbols.get(self.name)
def assign(self, value):
symbols.set(self.name,value)

class Assignment(Node):
def __init__(self,name,value=Identifier(_tmpvar)):
self.name = name
self.value = value
def __repr__(self):
return "<Assignment {} ({})>".format(self.name, self.value)
def eval(self):
value = self.value.eval()
self.name.assign(value.eval())

class Stdin(Node):
def __init__(self,text):
self.text = text
def __repr__(self):
return "<Input {}>".format(self.text)
def eval(self):
value = self.text.eval()
if not isinstance(value, str):
raise TypeError("[x] Sólo se puede preguntar texto.")
response = input(value)
symbols.set(_tmpvar,Primitive(response))

class Stdout(Node):
def __init__(self,text,end='\n'):
self.end = end
self.text = text
def __repr__(self):
if self.end == '':
return "<Print {}>".format(self.text)
else:
return "<Println {}>".format(self.text)
def eval(self):
print(self.text.eval(),end=self.end)
71 changes: 61 additions & 10 deletions lib/parser.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,88 @@
from lexer import tokens
from ply.yacc import yacc
from os import EX_SOFTWARE
from sys import exit,stderr

from nodes import *
from lexer import tokens

def Parser():
start = "program"

def p_program(p):
''' program : entrypoint statements '''
''' program : ALFRED statements '''
p[0] = p[2]

def p_entrypoint(p):
''' entrypoint : ALFRED '''
pass

def p_statements(p):
''' statements : statements statement
| statement
| empty
'''
if len(p) == 2:
p[0] = p[1]
p[0] = InstructionList([p[1]])
elif len(p) == 3:
p[0] = p[1] + " " + p[2]
p[1].child.append(p[2])
p[0] = p[1]

def p_statement(p):
''' statement : identifier '''
''' statement : method '''
p[0] = p[1]

def p_method(p):
''' method : store
| stdin
| stdout
'''
p[0] = p[1]

def p_store(p):
''' store : STORE IN id '''
p[0] = Assignment(p[3])

def p_stdin(p):
''' stdin : INPUT arg
'''
p[0] = Stdin(p[2])

def p_stdout(p):
''' stdout : PRINT expression '''
p[0] = Stdout(p[2],'')

def p_stdout_nl(p):
''' stdout : PRINTLN expression '''
p[0] = Stdout(p[2])

def p_identifier(p):
''' identifier : ID '''
''' expression : id '''
p[0] = p[1]

def p_id(p):
''' id : ID '''
p[0] = Identifier(p[1])

def p_primitive(p):
''' expression : STRING
| INTEGER
'''
p[0] = Primitive(p[1])

def p_arg1(p):
''' arg : expression
| empty
'''
p[0] = p[1] if p[1] else Primitive("")

def p_empty(p):
''' empty : '''
pass

def p_error(p):
if p:
print("[X] (Línea: {}) Syntaxis inválida: {}".format(
p.lineno, p.value), file=stderr)
else:
print("[X] Fallo desconocido en la sintaxis.", file=stderr)
exit(EX_SOFTWARE)

return yacc(
debug=False,
write_tables=True
Expand Down
10 changes: 10 additions & 0 deletions lib/symbols.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class Symbols():
def __init__(self):
self.identifiers = dict()
def set(self, id, value):
self.identifiers[id] = value
def get(self, id):
return self.identifiers.get(id,None)

_tmpvar = "$-tmp-$"
symbols = Symbols()
5 changes: 3 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Dependencies
ply
ply>=3.11

# Dev Dependencies
PyInstaller
setuptools>=41.0.1
PyInstaller>=3.4
Loading

0 comments on commit 4ff935b

Please sign in to comment.