New child language - (Function member address (structure))

Pages: 1... 910111213... 20
Dec 28, 2012 at 7:35pm
Well, if double d; is 8 bytes and int is 4 bytes than the two halves of double are ((int*)d)[0] /*and*/ ((int*)d)[1] (not sure in which order you should push them). Again. Why would you need this?
Dec 28, 2012 at 8:12pm
I don't know either, lol, but I had the right pushing in my interpreter. Just make two guesses.
Dec 28, 2012 at 9:47pm
Don't use a scalar variable as an array, you won't get the correct byte order that way. Use bitwise operators instead.

[edit] Also, ((int*)d)[1] should be ((int*)&d)[1] or *((int*)&d + 1).
Last edited on Dec 28, 2012 at 9:49pm
Dec 28, 2012 at 9:59pm
So using a float pointer (instead of int) should work good, shouldn't it?
Dec 28, 2012 at 11:04pm
No, I'm saying don't use a variable like an array if it isn't an array.
Dec 29, 2012 at 9:15am
Oops about the &. I don't see what's wrong with []s though? Do you mean that as a style thing? This bit of code is only there to copy an 8 byte value on the stack. I am sure that stack has the same endian as the rest of memory, so what could go wrong?
Dec 29, 2012 at 9:43am
Wow finally it works correctly. Thanks hamsterman, your solution is correct... :)
Start point : My program now is able to call a function e.g printf.

I'm going to add some extra operators and rules, such as ++; --; ^; ^= and (maybe) some bitwise operators.
I guess ++;--; operators perform faster than operator ±=1, and ±=1 performs faster than var = var ± 1. Is it correct?

And again the power operator. Unfortunately in my opinion it may be impossible because the parser calculates every expression in order from left to right. So I cannot reverse, turn back the loop and re-calculate all previous calculated values because it's very slow. Here's an example :
x = 5 * 10 ^ 2

5 * 10 = 50 certainly. With the default parser method, it becomes (5 * 10) ^ 2 then 50 ^ 2 and finally 50 * 50. The output is 2500. (Wrong)

But If I changed the precedence, it would become 5 * (10 ^ 2). First, multiply 5 with 10 we get "50". When result is 50 I have to calculate 10 ^ 2 (= 100) then recover the main value (again : 5), then after that recalculate (multiply 5 with 100 together). That's 500, but this method "kills" performance very quickly.

Is there any better solution guys?
Last edited on Dec 29, 2012 at 2:49pm
Dec 29, 2012 at 9:50am
I guess ++;--; operators perform faster than operator ±=1, and ±=1 performs faster than var = var ± 1. Is it correct?
If you're referring to these operators in C/C++, then you are very wrong. Are you aware of such thing as compiler optimization? (Though I'm not even sure what to optimize here...)

About precedences, didn't you solve this problem with 5+10*2. Anyway. You should be able to play with your parse trees a bit.
Dec 29, 2012 at 10:07am
hamsterman, thank you for pointing it out. Yes. I should play around with my parse trees a bit...
Last edited on Dec 29, 2012 at 10:12am
Dec 29, 2012 at 2:18pm
I made an additional function operator which only makes my code easier to read :)

operator[string*]
1
2
3
4
5
inline Data* operator[] (const char *string) {
	unsigned nPos = Search(string);
	if(nPos != -1)return &data[nPos];
	return 0;
}

Example code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//ClassData classItem

classItem.data.push_back(Data("one",t_Int));
classItem.data.push_back(Data("two",t_Int));
classItem.data.push_back(Data("three",t_Int));

//Accessing a variable...
classItem["one"]->SetValue(1);
classItem["two"]->SetValue(2);
classItem["three"]->SetValue(3);

//Instead of this...
//classItem.data[0].SetValue(1);
//classItem.data[1].SetValue(2);
//classItem.data[2].SetValue(3); 
Last edited on Dec 29, 2012 at 2:38pm
Dec 29, 2012 at 3:42pm
The average speed loop I see it's usually between 500.000 and 1.000.000, as it performs just about three million operator commands. In my opinion it's still slow because an interpreter has to handle many things with no performance hit. So now assembly vs a portable parser? No need to say more because assembly performance is perfect and most likely it can be optimized by an intelligent complier by many ways, but it's only designed for a specific unique command. And the "portable" certainly has a powerful portable feature. It knows how to understand an unknown code or expression but it handles information very slowly (one is checking characters, one is handling information via complex variables, functions and structures)...

So I'm very confused about that. I have no idea what the recommended speed for an interpreter is. It's really slow, isn't it?

Does anyone have an idea?
Last edited on Dec 29, 2012 at 3:49pm
Dec 29, 2012 at 11:38pm
I think it would be horrible if I added some advanced features (certainly they're terribly difficult) such as smart pointer, function detector, multiple dimensional array, function returning value, power operator... Because in my point of view they may kill the performance very very quickly.

Now I have some regular operators and I want to sort it (by precedence)

(±); (*); (/); (%); (^); (=);

1st
(^) (power)

2nd
(*); (/);

3rd
(±); (%); (=);


Is it correct? Should my interpreter be divided into three different layers above?
Last edited on Dec 29, 2012 at 11:41pm
Dec 30, 2012 at 12:23am
My power operator is going well. So, I think a new precedence doesn't matter, only I have to insert a lot of code in order to achieve the perfect result.

Now I want to get function returning value.
I've just learnt and memorized how to push parameters, call a function, do some basic calculation, and check, jump, and make while-for loop.

Now for example I want to get the final result from the function isdigit , but how to do this? By assembly?
Dec 30, 2012 at 9:34am
Is it possible if I'm going to make "smart pointer" feature for my intepreter?

I ask this just because I really want the next function scanf to be called properly (by my interpreter)... :)
Last edited on Dec 30, 2012 at 9:54am
Dec 30, 2012 at 12:46pm
Jackson Marie wrote:
Now for example I want to get the final result from the function isdigit , but how to do this? By assembly?


The code looks like:


1
2
3
4
5
6
7
8
9
int Result = 0;
int Source = '1';
asm {
    mov eax, (ascii value of the letter to convert)
    push eax
    call isdigit
    (pop ebx, if cdecl)
    mov Result, eax
};


Only works for MSVS, I hope it's correct.
Anyways you should not make it like every function needs its own code to be called.

Jackson Marie wrote:
Is it possible if I'm going to make "smart pointer" feature for my intepreter?

You should make classes in your interpreter to make it look consistent.
I suggest you to leave control to the user, anyways.
Last edited on Dec 30, 2012 at 12:50pm
Dec 31, 2012 at 1:43am
Thank you EssGeEich very much but now I got a trouble about stack correcting.

First of all let's take a look :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int func(int i){return 0;} //Only one parameter

int main()
{
//Input parameters
Input();

//Push parameters (Suppose there are two parameters which are accepted...)
__asm push 10
__asm push 15

__asm call func //Crash !!!
__asm add esp, 8

return 0;
}


The correct version :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int func(int i){return 0;} //Only one parameter

int main()
{
//Input parameters
Input();

//Push parameters (Suppose there are two parameters which are accepted...)
__asm push 10
__asm push 15

if(number_of_parameters != 1)
{
     __asm clear, stack //Clear all things that the program has just pushed...
     return 0;
}


__asm call func 
__asm add esp, 4

return 0;
}


When the program detected there is a function calling error, for example :
- Missing one or more necessary parameters
- Incorrect stack size,
- Incorrect parameter list - order


...then it would clear the stack and break its function calling. The problem is I could not find any assembly code which is used to clear function stack when any noticeable problem is detected.

Is there any magical code which can do this?
Do you know guys?
Last edited on Dec 31, 2012 at 1:45am
Dec 31, 2012 at 7:40am
I spent about twenty minutes to fix value conversion order.

And, this is conversion rule :
Simplest :
- Integers meet decimals -> decimal
- Low precedence meets higher precedence level : switch to higher level

Value level list :
- bool < char < short < long long < float < double


Wow, that's quite interesting! The program automatically adjusts the main precedence is needed. You may change the default value definition and also can change the main conversion precedence by using type_cast feature. And now with this feature I can write :
1
2
// '0' = 40
'0' + '0' + '0' + '0' // = 160 

What will happen if this expression is performed? Well, it gives -33 - if the main value is unsigned, that's 160. So it needs to be converted, by using type_cast. If you want the interpreter to give the correct value, here is one solution :
[int]'0' + '0' + '0' + '0'

Other examples :
false - true

Certainly the exact value is "-1" but actually result is "1". Just because boolean values only and only accept value "0", or "1".

[char]10 + 10000 / [char]6

10000 is unknown, so the parser will automatically load it as an integer. If the value is 'char', then it causes "Out of range". The value increases the main precedence conversion up to Int level, so generally the result is not affected much except decimal data (is truncated). Result is 176.

10 + [double]10000 / 6

10; 10000; 6 are integers, but 10000 has a double attribute. Because integers have a lower precedence than decimals, so the precedence is switched to decimal. So the value is more accurate - 176.66666...

[int]10.24 + [float]10000 / [char]6.49f

Same value, 176.666...
But it's float, not double. So when I call a function it only takes 4 bytes, rather than a double it takes 8 bytes...

Generally my opinion it's very important because certainly it helps a lot about function calling and correcting... :)

Only a question : If an unsigned value meets a signed value, what will happen? :)
Last edited on Dec 31, 2012 at 12:19pm
Dec 31, 2012 at 12:44pm
Wow! Finally I completed a very small feature that C++ currently cannot handle.

And now, here is a test example :
10 + (10 > 100) ? 10 : (5 > 50) ? 50 : 100

As you can see, the example has two "?" constructs. And after calculation the result is 100. Why?

- Assign the main variable a value (10)
- (10 > 100) returns 0 (false)
- The false value forces "10" to take the second value (5 > 50)
- But the expression (5 > 50) also is locked because there is another "?" construct.
- Then calculate (5 > 50) and it returns 0 (false)
- The main value now can take the next second value 100...

Similar expression...
(1 > 2) ? (2 > 3) : (3 > 4) ? (4 > 5) : (5 > 6)....

Conclusion : C++ cannot handle these things. :)
My opinion is only "because it's too complex". But let me know your compiler result. What is your result? :)
Last edited on Dec 31, 2012 at 1:41pm
Dec 31, 2012 at 2:07pm
I got a trouble and I have no idea "what should I do"?

I created a new source file and tried moving a function then re-complied the project. The function I had defined before is from a header file (call_a_function()). And I caught hundreds of linking errors. :C

I only see an error "(object_name) has already existed, found : define.obj"

What do you mean by that? How to fix those errors?

(Any help would be greatly appreciated)
Dec 31, 2012 at 3:59pm
C and C++'s conditional operator is right-associative, but its precedence is very low:
(a+b?c:d?e:f) == ((a+b)?c:(d?e:f))

No one uses this because a) the conditional operator is hard enough to read without the extra help and b) no one remembers its exact precedence and associativity without looking it up.
Last edited on Dec 31, 2012 at 4:01pm
Pages: 1... 910111213... 20