Generate algebraic expression at compile time in D - metaprogramming

Let's consider a function defined as follows:
f(n, x) = F(n, x, f(n-1, x))
f(0, x) = g(x)
In my program the value of n is always known at compile time. I want to optimize my program and avoid loops or recursive calls in this function. Whole expression for f(n, x) should be generated at compile time in order to allow compiler optimize it.
The direct solution is "manually" generate a string containing this expression and use mixin statement. I don't like this way.
Is compiler able/supposed to unfold a recursion with known depth?
I.e. will the following function be optimized in the way I want:
double f(uint n)(double x)
{
static if(n == 0)
return g(x);
else
return F(n, x, f!(n-1)(x));
}

There is no guarantees for optimizations in language specification as far as I know. Though your examples looks pretty trivial to optimize for compiler.
Simple experiment:
I have written stub functions g() and F() that do some simple calculations. Compiled with
dmd -gc -O -inline". Checked with objdump:
0000000000426860 <_Dmain>:
426860: 55 push %rbp
426861: 48 8b ec mov %rsp,%rbp
426864: f2 48 0f 10 05 2b a7 rex.W movsd 0x2a72b(%rip),%xmm0 # 450f98 <_IO_stdin_used+0x38>
42686b: 02 00
42686d: be 0a 00 00 00 mov $0xa,%esi
426872: 48 bf 28 10 66 00 00 movabs $0x661028,%rdi
426879: 00 00 00
42687c: e8 6f 01 00 00 callq 4269f0 <_D3std5stdio4File14__T5writeTdTaZ5writeMFdaZv>
426881: 31 c0 xor %eax,%eax
426883: 5d pop %rbp
426884: c3 retq
As you can see, everything was actually calculated during compilation and replaced with single numeric value that gets immediately printed as an argument to writeln. I have also checked modification where x get read at run-time and there are no calls to f() either. ASM listing is rather long there so I won't copy it.
Also, if your parameters are known at compile-time, then, probably, CTFE ( Compile Time Function Evaluation ) is a better solution as it is guaranteed.

Related

Prevent GCC (or LLVM) to erase one of two labels referring to the same location?

I do some binary analysis using objdump on compiled binaries using either GCC or LLVM.
To do this analysis, I rely on labels being preserved by the compiler in the output generated by objdump.
Consider the following output from objdump:
0000000000400517 <.cend.c181>:
400517: eb 01 jmp 40051a <.end.c180>
0000000000400519 <.cslot.c180>:
...
000000000040051a <.end.c180>:
40051a: ff 45 fc incl -0x4(%rbp)
Here, since labels .cend.c181 and .cstart.180 refer to the same location (0x400517), the compiler has chosen to erase .cstart.180.
A small snippet of the generated assembly:
#NO_APP
#APP
.cend.c181:
#NO_APP
#APP
.cstart.c180:
#NO_APP
#APP
jmp .end.c180
#NO_APP
#APP
Observe that .cend.c181 and .cstart.c180 refer to same location.
How do I preserve such labels, so that my tools work?
It seems that objdump only prints single label corresponding to line of assembly code and there isn't much you can do about it (see the relevant code). Can you extract all labels from ELF's symtab and then match them against instructions in a separate pass in your tool?
$ readelf -s tmp.o
Symbol table '.symtab' contains 7 entries:
Num: Value Size Type Bind Vis Ndx Name
...
4: 0000000000000000 0 NOTYPE LOCAL DEFAULT 1 .cend.c181
5: 0000000000000000 0 NOTYPE LOCAL DEFAULT 1 .cstart.c180
6: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND .end.c180

Attributes and Instances - Scheme, Racket: unbound identifier in module

I am trying to define a kind of dataset for an exercise I was asked to do. This is the code:
#lang racket
(
(
(pers(sol nub lluv))
(tmp numeric)
(hum numeric)
(vin (yes no))
(class (+ -))
)
;Instances
(sol 30 40 no +)
(lluv 24 70 yes -)
(sol 20 80 no +)
)
The problem is when I run this code I get the following message:
pers: unbound identifier in module in: pers
Do I have to define the identifiers in a different way?
Thanks for your answers!
Well, actually it is a file so there's no need to write "#lang racket". The thing is that I thought I had to run it but it was ok like that according to the exercise.
The next exercise was to read it and the code was the following:
#lang racket
(define (read-file filename)
(define datafile (with-input-from-file filename read))
datafile
)
;Store file info in a variable
(define fileinfo (read-file "filewithinfo.scm"))
So after running that, on console I could write "fileinfo" to display the file information, which was:
>fileinfo
'(((pers (sol nub lluv)) (tmp numeric) (hum numeric) (vin (yes no)) (class (+ -))) (sol 30 40 no +) (lluv 24 70 yes -) (sol 20 80 no +))
More info: https://en.wikibooks.org/wiki/Scheme_Programming/Input_and_Output

Generating HMAC::SHA256.hexdigest in Haskell

I wonder, what's method equivalent to HMAC::SHA256.hexdigest in Ruby? I ran through http://hackage.haskell.org/package/SHA-1.6.4.1/docs/Data-Digest-Pure-SHA.html but had trouble figuring it out. In Ruby it can be used as:
HMAC::SHA256.hexdigest(secret, nonce.to_s +client_id + api_key)
This sample code works (using the https://hackage.haskell.org/package/SHA) library):
{-# LANGUAGE OverloadedStrings #-}
import Data.Digest.Pure.SHA
main = do
let a = sha256 "some test message"
b = hmacSha256 "key" "some test message"
mapM_ print [showDigest a, showDigest b]
Demo in ghci:
λ> main
"3cb0603701548a84d3e7408a805e270a094000f537b96a6e83a36271a3ff192f"
"a5a36db81683537aacf8b6283121ffdb949ece609abbfe8a5fbc91cc76031edd"
You can also use Crypto.HMAC from the crypto-api:
Crypto.Hash.CryptoAPI Crypto.HMAC> hmac (MacKey "hello") "goodbye" :: SHA512
SHA512 "V]\163\146\166M\199\DLE\201\&5\163\DC17LF\246\150>\141\\*\197Q\198\203\233\235\&1&\b\245\SI\172Zc.\243\218\243\&9\224\172\215y\179|\240L\137\192M \167f\246\235\FS\188\231P(\245\ETXZ"
EDIT: The exact same code can produce the HMAC for other hashes thanks to the functions used being polymorphic. For example:
> simpleHex $ encode (hmac (MacKey "hello") "goodbye" :: SHA256)
"81 48 a0 89 d1 69 a8 9a 3e f0 b2 2a 6e b9 ab c1 d5 7e 70 73 a7 37 c9 0a 03 78 cf 2c 4e 39 94 de"
(Notice the optional-but-pretty use of encoding from the cereal package and hex output from simple-hex)

How can I change the values of elements in a vector from Visual C++'s debugger

I'm used to being able to modify collection elements in C# from Visual Studio's Immediate Window. However, in C++, when I attempt to do this with a vector, I get an odd error. First, here's my collection:
vector<uint8_t>& data;
Now, from the immediate window, after breaking in after data has been populated:
data
data { size=74 }
[size]: 74
[capacity]: 74
[0]: 1 '\x1'
[1]: 5 '\x5'
[2]: 23 '\x17'
...
data[0] = 0
no operator "[]" matches these operands
Is there some special syntax that I should be using here?

Haskell manipulating file contents

I'm a student from Portugal having some doubts about a project I have to handle.
My final objective is to create a pdf catalog with LaTeX that stores information about files using exiftool.
So far, i've managed to separate audio from video files and store their exiftool'ed information on a file, but it bulks them up.
for example:
======== Cartoon Battle.mp3
-ExifToolVersion=8.60
-FileName=Cartoon Battle.mp3
-Directory=.
-FileSize=4.0 MB
-FileModifyDate=2011:12:13 09:46:25+00:00
-FilePermissions=rw-rw-r--
-FileType=MP3
-MIMEType=audio/mpeg
-MPEGAudioVersion=1
-AudioLayer=3
-AudioBitrate=320 kbps
-SampleRate=48000
-ChannelMode=Stereo
-MSStereo=Off
-IntensityStereo=Off
-CopyrightFlag=False
-OriginalMedia=False
-Emphasis=None
-ID3Size=113441
-Title=Cartoon Battle
-Artist=Kevin MacLeod
-Year=2007
-BeatsPerMinute=130
-Genre=Unclassifiable
-Comment=(iTunPGAP) 0
-EncodedBy=iTunes v7.0.2.16
-Comment=(iTunNORM) 000001F7 0000014B 00001DBD 00000B18 000154C8 00000780 00008169 00008180 00000780 00000780
-Comment=(iTunSMPB) 00000000 00000210 00000A84 00000000004A606C 00000000 003DE780 00000000 00000000 00000000 00000000 00000000 00000000
-Album=Far East
-Composer=Kevin MacLeod
-PictureFormat=JPG
-PictureType=Other
-PictureDescription=
-Picture=(Binary data 91855 bytes, use -b option to extract)
-DateTimeOriginal=2007
-Duration=0:01:41 (approx)
======== Comic Plodding.mp3
-ExifToolVersion=8.60
-FileName=Comic Plodding.mp3
-Directory=.
-FileSize=3.8 MB
-FileModifyDate=2011:12:13 09:46:24+00:00
-FilePermissions=rw-rw-r--
-FileType=MP3
-MIMEType=audio/mpeg
-MPEGAudioVersion=1
-AudioLayer=3
-AudioBitrate=320 kbps
-SampleRate=44100
-ChannelMode=Joint Stereo
-MSStereo=Off
-IntensityStereo=Off
-CopyrightFlag=False
-OriginalMedia=False
-Emphasis=None
-ID3Size=105099
-EncoderSettings=Logic Pro 8.0.1
-Comment=(iTunNORM) 000001AE 00000181 000026DF 0000365B 0001100A 00016CE5 00007D33 00007ECF 00010FF0 00016CE5
-Comment=(iTunSMPB) 00000000 00000210 000009D6 000000000040DA1A 00000000 003ABCBC 00000000 00000000 00000000 00000000 00000000 00000000
-Artist=Kevin MacLeod
-Composer=Kevin MacLeod
-Year=2008
-Genre=Silent Film Score
-PictureFormat=JPG
-PictureType=Other
-PictureDescription=
-Picture=(Binary data 84880 bytes, use -b option to extract)
-Album=Scoring - Silent Film: Dark
-DateTimeOriginal=2008
-Duration=0:01:36 (approx)
What i'd like to do is :
first, try to split the two songs on that file in some kind of list of some sort.
then, try and pick up some of the information inside a file, like the FileName, Size and all that.
So far, i've come up with this piece of code, but it isnt correct:
mymain = do{
a <- readFile "audio.txt" ; -- file that has all the infos collected by exiftool
ml <- splitRegex (mkRegex "========") a ; -- I expect this to separate each song and place their corresponding information on a single string
Can anyone give me a hint? I want to store some information on a File structure i've created, but first, i need to split it up by songs, then pick up what I want, right?
THanks for the help and excuse me for my bad french!
PS: I'm not that used to haskell (just starting)
A minimal fix is:
import Text.Regex
main = do {
a <- readFile "audio.txt" ;
print $ splitRegex (mkRegex "========") a ;
}
The arrow extracts a value from a monadic value - from a value of type m a where m is a monad and a is an arbitrary type. readFile returns a monadic value (of type IO String) but splitRegex accepts a plain value of type String. So arrow can be used to extract a String from IO String. But splitRegex returns a non-monadic value so <- cannot extract anything from it.
I suggest to split your code into IO code and non-IO code and use the syntax without ; and {}:
import Text.Regex
processData text = x where
x = splitRegex (mkRegex "========") y
y = text
...
main = do
a <- readFile "audio.txt"
print $ processData a
So IO code will use do and <- and non-IO code will use where and =.

Resources