Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[mycpp] Can now write to stdout.
There is a polymorphic CFile and Buf, which are of type IO.  (TODO:
rename to File?)

Also simplify Buf::write() implementation with realloc().
  • Loading branch information
Andy Chu committed Oct 6, 2019
1 parent b34b8a9 commit 88e62c1
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 19 deletions.
11 changes: 7 additions & 4 deletions mycpp/cppgen_pass.py
Expand Up @@ -52,6 +52,9 @@ def get_c_type(t):
inner_c_type = get_c_type(type_param)
c_type = 'List<%s>*' % inner_c_type

elif type_name == 'typing.IO':
c_type = 'runtime::IO*'

else:
# fullname() => 'parse.Lexer'; name() => 'Lexer'

Expand Down Expand Up @@ -283,7 +286,9 @@ def visit_member_expr(self, o: 'mypy.nodes.MemberExpr') -> T:
if o.expr:
# This is an approximate hack that assumes that locals don't shadow
# imported names. Might be a problem with names like 'word'?
if isinstance(o.expr, NameExpr) and o.expr.name in self.imported_names:
expr_name = o.expr.name
if (isinstance(o.expr, NameExpr) and
(expr_name in self.imported_names or expr_name == 'runtime')):
op = '::'
else:
op = '->' # Everything is a pointer
Expand Down Expand Up @@ -331,9 +336,7 @@ def visit_call_expr(self, o: 'mypy.nodes.CallExpr') -> T:
self.write('new ')

# Namespace.
if callee_name == 'Buf':
self.write('runtime::Buf')
elif callee_name == 'int': # int('foo') in Python conflicts with keyword
if callee_name == 'int': # int('foo') in Python conflicts with keyword
self.write('str_to_int')
else:
self.accept(o.callee) # could be f() or obj.method()
Expand Down
12 changes: 6 additions & 6 deletions mycpp/examples/files.py
Expand Up @@ -7,23 +7,23 @@
import os
import sys

from runtime import log, Buf
import runtime
from runtime import log


def run_tests():
# type: () -> None

f = Buf()
f = runtime.Buf()
for i in xrange(30):
f.write(chr(i + 65))

contents = f.getvalue()
log('Wrote %d bytes to StringIO', len(contents))
log('contents = %s ... %s', contents[:10], contents[-10:])

# TODO:
#f = sys.stdout
#f.write('stdout\n')
f2 = runtime.StdOut()
f2.write('stdout\n')


def run_benchmarks():
Expand All @@ -34,7 +34,7 @@ def run_benchmarks():

i = 0
while i < n:
f = Buf()
f = runtime.Buf()
for j in xrange(30):
f.write(chr(i + 65))

Expand Down
2 changes: 1 addition & 1 deletion mycpp/run.sh
Expand Up @@ -313,7 +313,7 @@ python-example() {
example-both() {
local name=$1

#mypy --py2 --strict examples/$name.py
mypy --py2 --strict examples/$name.py

translate-example $name
compile-example $name
Expand Down
15 changes: 10 additions & 5 deletions mycpp/runtime.cc
Expand Up @@ -143,20 +143,25 @@ Str* StrIter::Value() {

namespace runtime {

IO* gStdOut;

void Buf::write(Str* s) {
int orig_len = len_;
len_ += s->len_;
if (data_ == nullptr) { // first write
data_ = static_cast<char*>(malloc(len_ + 1));
} else {
data_ = static_cast<char*>(realloc(data_, len_ + 1));
}
// data_ is nullptr at first
data_ = static_cast<char*>(realloc(data_, len_ + 1));

// Append to the end
memcpy(data_ + orig_len, s->data_, s->len_);
data_[len_] = '\0';
}

void CFile::write(Str* s) {
// note: throwing away the return value
fwrite(s->data_, s->len_, 1, f_);
}


};

//
Expand Down
31 changes: 29 additions & 2 deletions mycpp/runtime.h
Expand Up @@ -8,6 +8,8 @@
#include <stddef.h> // size_t
#include <stdlib.h> // malloc
#include <string.h> // strlen
// https://stackoverflow.com/questions/3882346/forward-declare-file
#include <cstdio> // FILE*
#include <vector>
#include <initializer_list>

Expand Down Expand Up @@ -297,11 +299,16 @@ int str_to_int(Str* s);

namespace runtime { // MyPy artifact

class Buf {
class IO {
public:
virtual void write(Str* s) = 0;
};

class Buf : public IO {
public:
Buf() : data_(nullptr), len_(0) {
};
void write(Str* s);
virtual void write(Str* s);
Str* getvalue() { return new Str(data_, len_); }

private:
Expand All @@ -310,6 +317,26 @@ class Buf {
size_t len_;
};

// Wrap a FILE*
class CFile : public IO {
public:
CFile(FILE* f) : f_(f) {
};
virtual void write(Str* s);

private:
FILE* f_;
};

extern IO* gStdOut;

inline IO* StdOut() {
if (gStdOut == nullptr) {
gStdOut = new CFile(stdout);
}
return gStdOut;
}

};

#endif // RUNTIME_H
6 changes: 5 additions & 1 deletion mycpp/runtime.py
Expand Up @@ -4,7 +4,7 @@
from __future__ import print_function

import sys
from typing import Any
from typing import IO, Any


# C code ignores this!
Expand All @@ -25,3 +25,7 @@ def p_die(msg, *args):

class Buf(StringIO.StringIO):
pass


def StdOut():
return sys.stdout
9 changes: 9 additions & 0 deletions mycpp/runtime.pyi
@@ -0,0 +1,9 @@
from typing import IO, Any

class Buf:
def write(self, s: str) -> None: ...
def getvalue(self) -> str: ...

def StdOut() -> IO[bytes]: ...

def log(msg: str, *args: Any) -> None: ...

0 comments on commit 88e62c1

Please sign in to comment.