[output]

MOVE #1,D0
MOVE D0,-(SP)
MOVE #2,D0
ADD (SP)+,D0
MOVE D0,-(SP)
MOVE #3,D0
ADD (SP)+,D0
LEA a(PC),A0
MOVE D0,(A0)

[input]

a=1+2+3

[source]

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Cradle
{
    public partial class frmCradle : Form
    {
        public frmCradle()
        {
            InitializeComponent();
        }

        private void btnCompile_Click(object sender, EventArgs e)
        {
            string input = tbxInputCmd.Text;
            if (input.Length > 0)
            {
                Parser myparser = new Parser(input);
                myparser.Assignment();
                tbxOutput.Text = myparser.Output;
            }
            else
            {
                MessageBox.Show("입력 수식이 없습니다");
            }
        }
    }
}

----------------------------------------------------------------------------------------------

using System;
using System.Text;
using System.IO;
using System.Media;
using System.Windows.Forms;

namespace Cradle
{

    class Parser
    {
        private StringBuilder outBuffer;
        private StringReader InBuffer;
        private char look;

        public char Look
        {
            get { return look; }
            set { look = value; }
        }

        public string Output
        {
            get { return outBuffer.ToString(); }
            set { ; }
        }

        // constructor
        public Parser(string msg)
        {
            Console.WriteLine(msg);
            outBuffer = new StringBuilder();
            InBuffer = new StringReader(msg);
            GetChar();
        }

        // method
        protected void GetChar()
        {
            int b;
            b = InBuffer.Read();
            Look = (char)b;
        }

        protected void Error(string msg)
        {
            SystemSounds.Beep.Play();
            MessageBox.Show(msg);
        }

        protected void Abort(string msg)
        {
            Error(msg);
            throw new ArgumentException();
        }

        protected void Expected(string msg)
        {
            Abort(msg + " Expected");
        }

        protected void SkipWhite()
        {
            while (Look == '\t' || Look == ' ')
                GetChar();
        }

        protected string GetNum()
        {
            string value = "";
            if (Char.IsNumber(Look) == false)
                Expected("Integer");
            while (Char.IsNumber(Look))
            {
                value += Look;
                GetChar();
            }
            SkipWhite();
            return value;
        }

        protected string GetName()
        {
            string token = "";
            if (Char.IsLetter(Look) == false)
                Expected("Name");
            while (Char.IsLetter(Look) || Char.IsNumber(Look))
            {
                token += Look;
                GetChar();
            }
            SkipWhite();
            return token;
        }

        protected void Emit(string msg)
        {
            outBuffer.Append(msg);
        }

        protected void EmitLn(string msg)
        {
            outBuffer.AppendLine(msg);
        }

        protected void Match(char ch)
        {
            if (Look == ch)
            {
                GetChar();
                SkipWhite();
            }
            else
            {
                Expected("\'" + ch + "\'");
            }
        }

        protected void Ident()
        {
            string name;
            name = GetName();
            if (Look == '(')
            {
                Match('(');
                Match(')');
                EmitLn("BSR " + name);
            }
            else
            {
                EmitLn("MOVE " + name + "(PC),D0");
            }
        }

        protected void Multiply()
        {
            Match('*');
            Factor();
            EmitLn("MULS (SP)+,D0");
        }

        protected void Divide()
        {
            Match('/');
            Factor();
            EmitLn("MOVE (SP)+,D1");
            EmitLn("DIVS D0,D1");
            EmitLn("MOVE D1,D0");
        }

        protected void Add()
        {
            Match('+');
            Term();
            EmitLn("ADD (SP)+,D0");
        }

        protected void Subtract()
        {
            Match('-');
            Term();
            EmitLn("SUB (SP)+,D0");
            EmitLn("NEG D0");
        }

        protected void Factor()
        {
            if (Look == '(')
            {
                Match('(');
                Expression();
                Match(')');
            }
            else if (Char.IsLetter(Look))
            {
                Ident();
            }
            else
            {
                EmitLn("MOVE #" + GetNum() + ",D0");
            }
        }

        protected void Term()
        {
            Factor();
            while (Look == '*' || Look == '/')
            {
                EmitLn("MOVE D0,-(SP)");
                switch (Look)
                {
                    case '*':
                        Multiply();
                        break;
                    case '/':
                        Divide();
                        break;
                    default:
                        Expected("Mulop");
                        break;
                }
            }
        }

        protected void Expression()
        {
            if (Look == '+' || Look == '-')
                EmitLn("CLR D0");
            else
                Term();
            while (Look == '+' || Look == '-')
            {
                EmitLn("MOVE D0,-(SP)");
                switch (Look)
                {
                    case '+':
                        Add();
                        break;
                    case '-':
                        Subtract();
                        break;
                    default:
                        Expected("Addop");
                        break;
                }
            }
        }

        public void Assignment()
        {
            string name;
            name = GetName();
            Match('=');
            Expression();
            EmitLn("LEA " + name + "(PC),A0");
            EmitLn("MOVE D0,(A0)");
        }
    }

}


A Matter of Style
When declaring pointer and reference variables, some C++ programmers use a unique
coding style that associates the * or the & with the type name and not the variable. For
example, here are two functionally equivalent declarations:

int& p; // & associated with type
int &p; // & associated with variable

Associating the * or & with the type name reflects the desire of some programmers
for C++ to contain a separate pointer type. However, the trouble with associating the &
or * with the type name rather than the variable is that, according to the formal C++
syntax, neither the & nor the * is distributive over a list of variables. Thus, misleading
declarations are easily created. For example, the following declaration creates one, not
two, integer pointers.

int* a, b;

Here, b is declared as an integer (not an integer pointer) because, as specified by the
C++ syntax, when used in a declaration, the * (or &) is linked to the individual variable
that it precedes, not to the type that it follows. The trouble with this declaration is that
the visual message suggests that both a and b are pointer types, even though, in fact,
only a is a pointer. This visual confusion not only misleads novice C++ programmers,
but occasionally old pros, too.

It is important to understand that, as far as the C++ compiler is concerned, it
doesn’t matter whether you write int *p or int* p. Thus, if you prefer to associate the *
or & with the type rather than the variable, feel free to do so.


(1) C++의 경우,

#include <iostream>
using namespace std;

class ShareVar
{
    static int num1;
public:
    static int num2;
    void setnum(int i) { num1 = i; }
    void shownum() { cout << num1 << " " << num2 << endl; }
};

int ShareVar::num1; // define num1
int ShareVar::num2;
   
int main()
{
    ShareVar a, b;
   
    a.shownum();
    b.shownum();
   
    a.setnum(10);
    a.shownum();
    ShareVar::num2 = 10;
    b.shownum();
   
    return 0;

}

C++의 경우 cpp 파일에서 class_name::static_member_name;

과 같이 해당 정적 멤버의 저장 공간을 따로 선언해 줘야 한다는걸 기억해야 한다.

 

(2) Java의 경우,

class Car {
  String Name;
  static int CarNum = 0;
  Car(String aName) {
    Name = aName;
    CarNum++;
  }
}

class JavaExam {
  pubic static void main(String args[]) {
    Car Pride = new Car("프라이드");
    Car Matis = new Car("마티즈");
    Car Carnical = new Car("카니발");
    System.out.println("차 " + Car.CarNum + "대 구입함");
  }
}

Java의 경우, 특별히 조심해야할 사항은 없어 보인다


SDL (Simple Directmedia Layer)는 멀티 플랫폼 GUI 개발 및 게임 개발에 흔히 쓰인다

각설하고,

SDL을 Visual Studio와 함께 사용할 때 꼼꼼히 설정을 해주지 않으면

Link Time에서 이런저런 에러가 발생한다

 

아래 사항을 꼼꼼히 확인하자

 

(1) SDL을 특정 Working Directory에 설치한다(압축을 푼다)

편의상 f:\work\sdl_12 폴더에 풀었다고 치자

(2) Visual Studio 2008에서 Empty Project를 생성한다

Win32로 해도 가능하지만, 편의상 Console Project로 한다

(3) 생성한 프로젝트의 소스파일 tree에 예를 들어 main.cpp를 생성한다

그리고 당연히 이 안에는,

int main(int argc, char* argv[])

로 시작하는 샘플 코드를 넣어둔다

(4) 추가 포함 파일 경로를 설정한다

vs2008 (한글) 기준으로: 도구->옵션->프로젝트및솔루션->VC++디렉터리->포함파일

에 f:\work\sdl_12\include 를 추가한다

(5) 추가 라이브러리 파일 경로를 설정한다

vs2008 (한글) 기준으로: 도구->옵션->프로젝트및솔루션->VC++디렉터리->라이브러리파일

에 f:\work\sdl_12\lib 를 추가한다

(6) 런타임라이브러리를 설정한다

vs2008 (한글) 기준으로: 프로젝트->(프로젝트이름)속성->구성속성->C/C++->코드생성

에 "런타임 라이브러리"를 "다중 스레드 DLL”로 설정한다. 여기서 DEBUG 여부는 don’t care

(7) 추가종속성을 설정한다

vs2008 (한글) 기준으로: 프로젝트->(프로젝트이름)속성->구성속성->링커->입력

의 "추가종속성" 부분에 sdl.lib 파일과 sdlmain.lib 파일을 추가한다

한편! 여기서 바로 밑에 있는 "모든 기본 라이브러리 무시" 부분은 "아니오"로 해준다!!!

자! 여기까지 했으면 솔루션 Build 하고서 실행파일이 생긴 곳에 SDL.DLL을 같이 넣어주거나

또는 시스템 디렉토리(난 이 방법 선호하지 않으이!)에 넣어주고 실행 파일을 기동해 본다

 

위와 같이 정확하게 해주면 100% 동작한다.

p.s. : console project가 아닌 win32 project로 생성했으면 main() 대신

WinMain()만 사용하면 된다고 하나 테스트 해보지 않았다


[for C++ ]

class base

{

    int a;

public:

    base(int x) { a = x; }

};

class derived : public base

{

    int b;

public:

    derived(int x, int y) : base(y) { b = x;}

};

[for java]

class base {

  int a;

  public base(int x) { a = x; }

}

class derived extends base {

  int b;

  public derived(int x, int y) { super(y); b = x; }

}


typedef 문을 ,와 함께 쓰는 경우가 종종 있다
생각해 보면 의미는 당연한데 처음에는 좀 헷갈릴 수 있다

--------------------------------------------------
#include <iostream>

using namespace std;

typedef struct {
  int a;
  int b;
  int c;
} mytype, *pmytype;

int main()
{
  mytype var_a;
  pmytype ptr_a;

  ptr_a = &var_a;

  var_a.a = 10;
  var_a.b = 20;
  ptr_a->c = 30;

  cout << "values of var_a is " << ptr_a->a << " " 
       << ptr_a->b << " " << var_a.c << endl;

  return 0;
}



리눅스에서는.

    FILE *fp; 에서

    fp->_fileno 로 file desctiptor 를 뜻하는 integer  값을 얻을 수 있고

 

반면 윈도우에서는,

  FILE *fp; 에서

  fp->_file 을 사용해야 함


int main()
{

char *str1 = “1234567890″;
char str2[] = “1234567890”;

char *str3= “1234″;

memcpy(str1, str3, strlen(str3));    <—(1)

memcpy(str2, str3, strlen(str3));    <—(2)

return 0;

}

여기서 (2)는 기대한대로 동작하지만,

(1)은 segmentation fault 발생시킨다.

 


우선 아래 ps 출력을 좀 보고,

root      2743     1  0 Oct15 ?        00:00:00 /usr/sbin/sshd
root     23689  2743  0 14:14 ?        00:00:00 sshd: jdh69 [priv]
jdh69    23691 23689  0 14:14 ?        00:00:00 sshd: jdh69@pts/6
jdh69    23692 23691  0 14:14 pts/6    00:00:00 –bash

여기서 getpgrp() 사용한 놈을 실행 시켜 결과를 좀 뿌리고,

[jdh69@localhost ~]$ ./pidT1
[child] PID : 23844
[child] PPID : 23843
[parent] PID : 23843
[parent] PID of child : 23844
[parent] PPID : 23692
[parent] GID : 23843
[parent] SID : 23692
[child] GID : 23843
[child] SID : 23692
printout data from MSB to LSB: 0 9 0 0
[parent] status is 2304

 

다음 내가 login 한 GID를 살펴보면,

[jdh69@localhost ~]$ cat /etc/group | grep jdh69
jdh69:x:508:

해석을 좀 해보면,

getpgrp()에서 받아오는 Group ID는 process group ID로서

이건 해당 실행파일이 기동하면서 받은 process ID 임을 알 수 있다

그리고 SID는 해당 실행파일이 기동할 때 사용한 shell의 process ID 되겠다

끝으로 /etc/group의 GID는 해당 로그인 계정이 속한 user group의 ID이다

이건 getpgrp()의 결과값과 전혀 관계가 없다!

 

위에서 부터 좀 살펴보면

sshd –> sshd(내 session 처리 위한 사본) –> sshd(내 권한 처리 위한 사본)

-> bash(여기서의 process ID가 getsid()의 결과) –> pidT1(여기서의 process ID가 getpgrp()의 결과)

-> child (pidT1이 fork()해서 만든 process, pidT1과 GID, SID는 같고 PID, PPID는 다르다)



FILE *fp;

fp = fopen(“/tmp/daemon.out”, “wt”);

if (fp == NULL) {

    printf(“File Open Error\n”);

    return –1;

}

 

대략 위와 같은 맥락에서

fopen(“~/daemon.out”, “wt”) 이렇게 사용하니까

내가 실행하고 있는 user 의 home directory에 만들어 주는게 아니라

fp = NULL 이 return 한다.

 

그러면 my home directory에 만들려면

어떻게 해야 할까?

environment 에서 읽어와서 스트링 연결을 해야하겠구만…